AnimatedGameComponent.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. //-----------------------------------------------------------------------------
  2. // AnimatedGameComponent.cs
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using Microsoft.Xna.Framework;
  11. using Microsoft.Xna.Framework.Graphics;
  12. using CardsFramework;
  13. namespace CardsFramework
  14. {
  15. /// <summary>
  16. /// A game component.
  17. /// Enable variable display while managing and displaying a set of
  18. /// <see cref="AnimatedGameComponentAnimation">Animations</see>
  19. /// </summary>
  20. public class AnimatedGameComponent : DrawableGameComponent
  21. {
  22. public Texture2D CurrentFrame { get; set; }
  23. public Rectangle? CurrentSegment { get; set; }
  24. public string Text { get; set; }
  25. public Color TextColor { get; set; }
  26. public bool IsFaceDown = true;
  27. public Vector2 CurrentPosition { get; set; }
  28. public Rectangle? CurrentDestination { get; set; }
  29. List<AnimatedGameComponentAnimation> runningAnimations =
  30. new List<AnimatedGameComponentAnimation>();
  31. /// <summary>
  32. /// Whether or not an animation belonging to the component is running.
  33. /// </summary>
  34. public virtual bool IsAnimating { get { return runningAnimations.Count > 0; } }
  35. public CardsGame CardGame { get; private set; }
  36. private SpriteBatch spriteBatch;
  37. private Matrix globalTransformation;
  38. /// <summary>
  39. /// Initializes a new instance of the class, using black text color.
  40. /// </summary>
  41. /// <param name="cardGame">The associated card game.</param>
  42. /// <param name="currentFrame">The texture serving as the current frame
  43. /// to display as the component.</param>
  44. public AnimatedGameComponent(CardsGame cardGame, Texture2D? currentFrame, SpriteBatch sharedSpriteBatch, Matrix? globalTransformation = null)
  45. : base(cardGame.Game)
  46. {
  47. if (sharedSpriteBatch == null)
  48. throw new ArgumentNullException(nameof(sharedSpriteBatch), "AnimatedGameComponent requires a valid SpriteBatch.");
  49. CardGame = cardGame;
  50. CurrentFrame = currentFrame;
  51. TextColor = Color.Black;
  52. this.spriteBatch = sharedSpriteBatch;
  53. this.globalTransformation = globalTransformation ?? Matrix.Identity;
  54. }
  55. /// <summary>
  56. /// Keeps track of the component's animations.
  57. /// </summary>
  58. /// <param name="gameTime">The time which as elapsed since the last call
  59. /// to this method.</param>
  60. public override void Update(GameTime gameTime)
  61. {
  62. base.Update(gameTime);
  63. for (int animationIndex = 0; animationIndex < runningAnimations.Count; animationIndex++)
  64. {
  65. runningAnimations[animationIndex].AccumulateElapsedTime(gameTime.ElapsedGameTime);
  66. runningAnimations[animationIndex].Run(gameTime);
  67. if (runningAnimations[animationIndex].IsDone())
  68. {
  69. runningAnimations.RemoveAt(animationIndex);
  70. animationIndex--;
  71. }
  72. }
  73. }
  74. /// <summary>
  75. /// Draws the animated component and its associated text, if it exists, at
  76. /// the object's set destination. If a destination is not set, its initial
  77. /// position is used.
  78. /// </summary>
  79. /// <param name="gameTime">The time which as elapsed since the last call
  80. /// to this method.</param>
  81. public override void Draw(GameTime gameTime)
  82. {
  83. spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, globalTransformation);
  84. // Draw at the destination if one is set
  85. if (CurrentDestination.HasValue)
  86. {
  87. if (CurrentFrame != null)
  88. {
  89. spriteBatch.Draw(CurrentFrame, CurrentDestination.Value, CurrentSegment, Color.White);
  90. if (Text != null)
  91. {
  92. Vector2 size = CardGame.Font.MeasureString(Text);
  93. Vector2 textPosition = new Vector2(CurrentDestination.Value.X +
  94. CurrentDestination.Value.Width / 2 - size.X / 2,
  95. CurrentDestination.Value.Y + CurrentDestination.Value.Height / 2 - size.Y / 2);
  96. spriteBatch.DrawString(CardGame.Font, Text, textPosition, TextColor);
  97. }
  98. }
  99. }
  100. // Draw at the component's position if there is no destination
  101. else
  102. {
  103. if (CurrentFrame != null)
  104. {
  105. spriteBatch.Draw(CurrentFrame, CurrentPosition, CurrentSegment, Color.White);
  106. if (Text != null)
  107. {
  108. Vector2 size = CardGame.Font.MeasureString(Text);
  109. Vector2 textPosition = new Vector2(CurrentPosition.X +
  110. CurrentFrame.Bounds.Width / 2 - size.X / 2,
  111. CurrentPosition.Y + CurrentFrame.Bounds.Height / 2 - size.Y / 2);
  112. spriteBatch.DrawString(CardGame.Font, Text, textPosition, TextColor);
  113. }
  114. }
  115. }
  116. spriteBatch.End();
  117. base.Draw(gameTime);
  118. }
  119. /// <summary>
  120. /// Adds an animation to the animated component.
  121. /// </summary>
  122. /// <param name="animation">The animation to add.</param>
  123. public void AddAnimation(AnimatedGameComponentAnimation animation)
  124. {
  125. animation.Component = this;
  126. runningAnimations.Add(animation);
  127. }
  128. /// <summary>
  129. /// Calculate the estimated time at which the longest lasting animation currently managed
  130. /// will complete.
  131. /// </summary>
  132. /// <returns>The estimated time for animation complete </returns>
  133. public virtual TimeSpan EstimatedTimeForAnimationsCompletion()
  134. {
  135. TimeSpan result = TimeSpan.Zero;
  136. if (IsAnimating)
  137. {
  138. for (int animationIndex = 0; animationIndex < runningAnimations.Count; animationIndex++)
  139. {
  140. if (runningAnimations[animationIndex].EstimatedTimeForAnimationCompletion > result)
  141. {
  142. result = runningAnimations[animationIndex].EstimatedTimeForAnimationCompletion;
  143. }
  144. }
  145. }
  146. return result;
  147. }
  148. }
  149. }