2
0

AnimatedHandGameComponent.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. //-----------------------------------------------------------------------------
  2. // AnimatedHandGameComponent.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 CardsFramework;
  11. using Microsoft.Xna.Framework;
  12. using Microsoft.Xna.Framework.Graphics;
  13. namespace CardsFramework
  14. {
  15. public class AnimatedHandGameComponent : AnimatedGameComponent
  16. {
  17. public int Place { get; private set; }
  18. public readonly Hand Hand;
  19. List<AnimatedCardsGameComponent> heldAnimatedCards = new List<AnimatedCardsGameComponent>();
  20. public override bool IsAnimating
  21. {
  22. get
  23. {
  24. for (int animationIndex = 0; animationIndex < heldAnimatedCards.Count; animationIndex++)
  25. {
  26. if (heldAnimatedCards[animationIndex].IsAnimating)
  27. {
  28. return true;
  29. }
  30. }
  31. return false;
  32. }
  33. }
  34. /// <summary>
  35. /// Returns the animated cards contained in the hand.
  36. /// </summary>
  37. public IEnumerable<AnimatedCardsGameComponent> AnimatedCards
  38. {
  39. get
  40. {
  41. return heldAnimatedCards.AsReadOnly();
  42. }
  43. }
  44. SpriteBatch spriteBatch;
  45. Matrix globalTransformation;
  46. /// <summary>
  47. /// Initializes a new instance of the animated hand component. This means
  48. /// setting the hand's position and initializing all animated cards and their
  49. /// respective positions. Also, registrations are performed to the associated
  50. /// <paramref name="hand"/> events to update the animated hand as cards are
  51. /// added or removed.
  52. /// </summary>
  53. /// <param name="place">The player's place index (-1 for the dealer).</param>
  54. /// <param name="hand">The hand represented by this instance.</param>
  55. /// <param name="cardGame">The associated card game.</param>
  56. public AnimatedHandGameComponent(int place, Hand hand, CardsGame cardGame, SpriteBatch spriteBatch, Matrix globalTransformation)
  57. : base(cardGame, null, spriteBatch, globalTransformation)
  58. {
  59. Place = place;
  60. Hand = hand;
  61. hand.ReceivedCard += Hand_ReceivedCard;
  62. hand.LostCard += Hand_LostCard;
  63. this.spriteBatch = spriteBatch;
  64. this.globalTransformation = globalTransformation;
  65. // Set the component's position
  66. if (place == -1)
  67. {
  68. CurrentPosition = CardGame.GameTable.DealerPosition;
  69. }
  70. else
  71. {
  72. CurrentPosition = CardGame.GameTable[place];
  73. }
  74. // Create and initialize animated cards according to the cards in the
  75. // associated hand
  76. for (int cardIndex = 0; cardIndex < hand.Count; cardIndex++)
  77. {
  78. AnimatedCardsGameComponent animatedCardGameComponent =
  79. new AnimatedCardsGameComponent(hand[cardIndex], CardGame, spriteBatch, globalTransformation)
  80. {
  81. CurrentPosition = CurrentPosition + new Vector2(30 * cardIndex, 0)
  82. };
  83. heldAnimatedCards.Add(animatedCardGameComponent);
  84. Game.Components.Add(animatedCardGameComponent);
  85. }
  86. Game.Components.ComponentRemoved += Components_ComponentRemoved;
  87. }
  88. /// <summary>
  89. /// Updates the component.
  90. /// </summary>
  91. /// <param name="gameTime">The time which elapsed since this method was last
  92. /// called.</param>
  93. public override void Update(GameTime gameTime)
  94. {
  95. // Arrange the hand's animated cards' positions
  96. for (int animationIndex = 0; animationIndex < heldAnimatedCards.Count; animationIndex++)
  97. {
  98. if (!heldAnimatedCards[animationIndex].IsAnimating)
  99. {
  100. heldAnimatedCards[animationIndex].CurrentPosition = CurrentPosition +
  101. GetCardRelativePosition(animationIndex);
  102. }
  103. }
  104. base.Update(gameTime);
  105. }
  106. /// <summary>
  107. /// Gets the card's offset from the hand position according to its index
  108. /// in the hand.
  109. /// </summary>
  110. /// <param name="cardLocationInHand">The card index in the hand.</param>
  111. /// <returns></returns>
  112. public virtual Vector2 GetCardRelativePosition(int cardLocationInHand)
  113. {
  114. return default(Vector2);
  115. }
  116. /// <summary>
  117. /// Finds the index of a specified card in the hand.
  118. /// </summary>
  119. /// <param name="card">The card to locate.</param>
  120. /// <returns>The card's index inside the hand, or -1 if it cannot be
  121. /// found.</returns>
  122. public int GetCardLocationInHand(TraditionalCard card)
  123. {
  124. for (int animationIndex = 0; animationIndex < heldAnimatedCards.Count; animationIndex++)
  125. {
  126. if (heldAnimatedCards[animationIndex].Card == card)
  127. {
  128. return animationIndex;
  129. }
  130. }
  131. return -1;
  132. }
  133. /// <summary>
  134. /// Gets the animated game component associated with a specified card.
  135. /// </summary>
  136. /// <param name="card">The card for which to get the animation
  137. /// component.</param>
  138. /// <returns>The card's animation component, or null if such a card cannot
  139. /// be found in the hand.</returns>
  140. public AnimatedCardsGameComponent GetCardGameComponent(TraditionalCard card)
  141. {
  142. int location = GetCardLocationInHand(card);
  143. if (location == -1)
  144. return null;
  145. return heldAnimatedCards[location];
  146. }
  147. /// <summary>
  148. /// Gets the animated game component associated with a specified card.
  149. /// </summary>
  150. /// <param name="location">The location where the desired card is
  151. /// in the hand.</param>
  152. /// <returns>The card's animation component.</return>s
  153. public AnimatedCardsGameComponent GetCardGameComponent(int location)
  154. {
  155. if (location == -1 || location >= heldAnimatedCards.Count)
  156. return null;
  157. return heldAnimatedCards[location];
  158. }
  159. /// <summary>
  160. /// Handles the ComponentRemoved event of the Components control.
  161. /// </summary>
  162. /// <param name="sender">The source of the event.</param>
  163. /// <param name="e">The
  164. /// <see cref="Microsoft.Xna.Framework.GameComponentCollectionEventArgs"/>
  165. /// instance containing the event data.</param>
  166. void Components_ComponentRemoved(object sender, GameComponentCollectionEventArgs e)
  167. {
  168. if (e.GameComponent == this)
  169. {
  170. Dispose();
  171. }
  172. }
  173. /// <summary>
  174. /// Handles the hand's LostCard event be removing the corresponding animated
  175. /// card.
  176. /// </summary>
  177. /// <param name="sender">The source of the event.</param>
  178. /// <param name="e">The
  179. /// <see cref="CardsFramework.CardEventArgs"/>
  180. /// instance containing the event data.</param>
  181. void Hand_LostCard(object sender, CardEventArgs e)
  182. {
  183. // Remove the card from screen
  184. for (int animationIndex = 0; animationIndex < heldAnimatedCards.Count; animationIndex++)
  185. {
  186. if (heldAnimatedCards[animationIndex].Card == e.Card)
  187. {
  188. Game.Components.Remove(heldAnimatedCards[animationIndex]);
  189. heldAnimatedCards.RemoveAt(animationIndex);
  190. return;
  191. }
  192. }
  193. }
  194. /// <summary>
  195. /// Handles the hand's ReceivedCard event be adding a corresponding
  196. /// animated card.
  197. /// </summary>
  198. /// <param name="sender">The source of the event.</param>
  199. /// <param name="e">The
  200. /// <see cref="CardsFramework.CardEventArgs"/>
  201. /// instance containing the event data.</param>
  202. void Hand_ReceivedCard(object sender, CardEventArgs e)
  203. {
  204. // Add the card to the screen
  205. AnimatedCardsGameComponent animatedCardGameComponent =
  206. new AnimatedCardsGameComponent(e.Card, CardGame, spriteBatch, globalTransformation) { Visible = false };
  207. heldAnimatedCards.Add(animatedCardGameComponent);
  208. Game.Components.Add(animatedCardGameComponent);
  209. }
  210. /// <summary>
  211. /// Calculate the estimated time at which the longest lasting animation currently managed
  212. /// will complete.
  213. /// </summary>
  214. /// <returns>The estimated time for animation complete </returns>
  215. public override TimeSpan EstimatedTimeForAnimationsCompletion()
  216. {
  217. TimeSpan result = TimeSpan.Zero;
  218. if (IsAnimating)
  219. {
  220. for (int animationIndex = 0; animationIndex < heldAnimatedCards.Count; animationIndex++)
  221. {
  222. if (heldAnimatedCards[animationIndex].EstimatedTimeForAnimationsCompletion() > result)
  223. {
  224. result = heldAnimatedCards[animationIndex].EstimatedTimeForAnimationsCompletion();
  225. }
  226. }
  227. }
  228. return result;
  229. }
  230. /// <summary>
  231. /// Properly disposes of the component when it is removed.
  232. /// </summary>
  233. /// <param name="disposing"></param>
  234. protected override void Dispose(bool disposing)
  235. {
  236. // Remove the registrations to the event to make this
  237. // instance collectable by gc
  238. Hand.ReceivedCard -= Hand_ReceivedCard;
  239. Hand.LostCard -= Hand_LostCard;
  240. base.Dispose(disposing);
  241. }
  242. }
  243. }