#region File Description //----------------------------------------------------------------------------- // AnimatedGameComponent.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion #region Using Statements using System; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using CardsFramework; #endregion namespace CardsFramework { /// /// A game component. /// Enable variable display while managing and displaying a set of /// Animations /// public class AnimatedGameComponent : DrawableGameComponent { #region Fields and Properties public Texture2D CurrentFrame { get; set; } public Rectangle? CurrentSegment { get; set; } public string Text { get; set; } public Color TextColor { get; set; } public bool IsFaceDown = true; public Vector2 CurrentPosition { get; set; } public Rectangle? CurrentDestination { get; set; } List runningAnimations = new List(); /// /// Whether or not an animation belonging to the component is running. /// public virtual bool IsAnimating { get { return runningAnimations.Count > 0; } } public CardsGame CardGame { get; private set; } #endregion #region Initializatios /// /// Initializes a new instance of the class, using black text color. /// /// The associated game class. public AnimatedGameComponent(Game game) : base(game) { TextColor = Color.Black; } /// /// Initializes a new instance of the class, using black text color. /// /// The associated game class. /// The texture serving as the current frame /// to display as the component. public AnimatedGameComponent(Game game, Texture2D currentFrame) : this(game) { CurrentFrame = currentFrame; } /// /// Initializes a new instance of the class, using black text color. /// /// The associated card game. /// The texture serving as the current frame /// to display as the component. public AnimatedGameComponent(CardsGame cardGame, Texture2D currentFrame) : this(cardGame.Game) { CardGame = cardGame; CurrentFrame = currentFrame; } #endregion #region Update and Render /// /// Keeps track of the component's animations. /// /// The time which as elapsed since the last call /// to this method. public override void Update(GameTime gameTime) { base.Update(gameTime); for (int animationIndex = 0; animationIndex < runningAnimations.Count; animationIndex++) { runningAnimations[animationIndex].AccumulateElapsedTime(gameTime.ElapsedGameTime); runningAnimations[animationIndex].Run(gameTime); if (runningAnimations[animationIndex].IsDone()) { runningAnimations.RemoveAt(animationIndex); animationIndex--; } } } /// /// Draws the animated component and its associated text, if it exists, at /// the object's set destination. If a destination is not set, its initial /// position is used. /// /// The time which as elapsed since the last call /// to this method. public override void Draw(GameTime gameTime) { base.Draw(gameTime); SpriteBatch spriteBatch; if (CardGame != null) { spriteBatch = CardGame.SpriteBatch; } else { spriteBatch = new SpriteBatch(Game.GraphicsDevice); } spriteBatch.Begin(); // Draw at the destination if one is set if (CurrentDestination.HasValue) { if (CurrentFrame != null) { spriteBatch.Draw(CurrentFrame, CurrentDestination.Value, CurrentSegment, Color.White); if (Text != null) { Vector2 size = CardGame.Font.MeasureString(Text); Vector2 textPosition = new Vector2(CurrentDestination.Value.X + CurrentDestination.Value.Width / 2 - size.X / 2, CurrentDestination.Value.Y + CurrentDestination.Value.Height / 2 - size.Y / 2); spriteBatch.DrawString(CardGame.Font, Text, textPosition, TextColor); } } } // Draw at the component's position if there is no destination else { if (CurrentFrame != null) { spriteBatch.Draw(CurrentFrame, CurrentPosition, CurrentSegment, Color.White); if (Text != null) { Vector2 size = CardGame.Font.MeasureString(Text); Vector2 textPosition = new Vector2(CurrentPosition.X + CurrentFrame.Bounds.Width / 2 - size.X / 2, CurrentPosition.Y + CurrentFrame.Bounds.Height / 2 - size.Y / 2); spriteBatch.DrawString(CardGame.Font, Text, textPosition, TextColor); } } } spriteBatch.End(); } #endregion /// /// Adds an animation to the animated component. /// /// The animation to add. public void AddAnimation(AnimatedGameComponentAnimation animation) { animation.Component = this; runningAnimations.Add(animation); } /// /// Calculate the estimated time at which the longest lasting animation currently managed /// will complete. /// /// The estimated time for animation complete public virtual TimeSpan EstimatedTimeForAnimationsCompletion() { TimeSpan result = TimeSpan.Zero; if (IsAnimating) { for (int animationIndex = 0; animationIndex < runningAnimations.Count; animationIndex++) { if (runningAnimations[animationIndex].EstimatedTimeForAnimationCompletion > result) { result = runningAnimations[animationIndex].EstimatedTimeForAnimationCompletion; } } } return result; } } }