ShuffleAnimationComponent.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. //-----------------------------------------------------------------------------
  2. // ShuffleAnimationComponent.cs
  3. //
  4. // Game component that manages a shuffle animation, creates and coordinates
  5. // all animated card components, and handles cleanup
  6. //-----------------------------------------------------------------------------
  7. using System;
  8. using System.Collections.Generic;
  9. using Microsoft.Xna.Framework;
  10. using Microsoft.Xna.Framework.Graphics;
  11. namespace CardsFramework
  12. {
  13. /// <summary>
  14. /// Component that orchestrates a shuffle animation by creating animated
  15. /// cards and managing their lifecycle
  16. /// </summary>
  17. public class ShuffleAnimationComponent : DrawableGameComponent
  18. {
  19. private readonly ShuffleAnimation shuffleAnimation;
  20. private readonly List<TraditionalCard> deck;
  21. private readonly SpriteBatch spriteBatch;
  22. private readonly Matrix globalTransformation;
  23. private List<AnimatedCardsGameComponent> animatedCards;
  24. private TimeSpan elapsedTime;
  25. private bool animationStarted = false;
  26. private bool animationCompleted = false;
  27. /// <summary>
  28. /// Gets whether the shuffle animation has completed
  29. /// </summary>
  30. public bool IsComplete => animationCompleted;
  31. /// <summary>
  32. /// Creates a new shuffle animation component
  33. /// </summary>
  34. /// <param name="game">The game instance</param>
  35. /// <param name="shuffleAnimation">The shuffle animation to perform</param>
  36. /// <param name="deck">The deck of cards to shuffle</param>
  37. /// <param name="spriteBatch">Shared sprite batch for rendering</param>
  38. /// <param name="globalTransformation">Transformation matrix for scaling</param>
  39. public ShuffleAnimationComponent(
  40. Game game,
  41. ShuffleAnimation shuffleAnimation,
  42. List<TraditionalCard> deck,
  43. SpriteBatch spriteBatch,
  44. Matrix globalTransformation)
  45. : base(game)
  46. {
  47. this.shuffleAnimation = shuffleAnimation;
  48. this.deck = deck;
  49. this.spriteBatch = spriteBatch;
  50. this.globalTransformation = globalTransformation;
  51. // Component should not be visible initially
  52. Visible = false;
  53. }
  54. /// <summary>
  55. /// Initialize and start the animation
  56. /// </summary>
  57. public override void Initialize()
  58. {
  59. base.Initialize();
  60. // Create all animated cards
  61. animatedCards = shuffleAnimation.CreateAnimatedCards(deck, spriteBatch, globalTransformation);
  62. // Add all card components to the game
  63. foreach (var card in animatedCards)
  64. {
  65. Game.Components.Add(card);
  66. }
  67. // Make component visible and trigger start callback
  68. Visible = true;
  69. animationStarted = true;
  70. shuffleAnimation.OnAnimationStart?.Invoke();
  71. }
  72. /// <summary>
  73. /// Update animation progress and check for completion
  74. /// </summary>
  75. public override void Update(GameTime gameTime)
  76. {
  77. base.Update(gameTime);
  78. if (!animationStarted)
  79. return;
  80. elapsedTime += gameTime.ElapsedGameTime;
  81. // Check if animation duration has elapsed
  82. if (elapsedTime >= shuffleAnimation.Duration && !animationCompleted)
  83. {
  84. CompleteAnimation();
  85. }
  86. }
  87. /// <summary>
  88. /// Called when animation finishes
  89. /// </summary>
  90. private void CompleteAnimation()
  91. {
  92. animationCompleted = true;
  93. // CRITICAL: Hide cards immediately before doing anything else
  94. // This prevents the "ghost deck" from appearing at shuffle position
  95. if (animatedCards != null)
  96. {
  97. foreach (var card in animatedCards)
  98. {
  99. card.Visible = false;
  100. }
  101. }
  102. // Invoke completion callback
  103. shuffleAnimation.OnAnimationComplete?.Invoke();
  104. // Clean up all card components
  105. CleanupCards();
  106. // Remove this component from the game
  107. Game.Components.Remove(this);
  108. }
  109. /// <summary>
  110. /// Removes all animated card components from the game
  111. /// </summary>
  112. private void CleanupCards()
  113. {
  114. if (animatedCards != null)
  115. {
  116. // First make all cards invisible
  117. foreach (var card in animatedCards)
  118. {
  119. card.Visible = false;
  120. }
  121. // Then remove them from the game
  122. foreach (var card in animatedCards)
  123. {
  124. if (Game.Components.Contains(card))
  125. {
  126. Game.Components.Remove(card);
  127. }
  128. }
  129. animatedCards.Clear();
  130. }
  131. }
  132. /// <summary>
  133. /// Dispose and cleanup
  134. /// </summary>
  135. protected override void Dispose(bool disposing)
  136. {
  137. if (disposing)
  138. {
  139. CleanupCards();
  140. }
  141. base.Dispose(disposing);
  142. }
  143. }
  144. }