TilemapTileAnimation.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. using System;
  2. namespace MonoGame.Extended.Tilemaps
  3. {
  4. /// <summary>
  5. /// Represents a frame-based animation for a tile.
  6. /// </summary>
  7. public class TilemapTileAnimation
  8. {
  9. private int _currentFrameIndex;
  10. private float _elapsedTime;
  11. /// <summary>
  12. /// Gets the animation frames.
  13. /// </summary>
  14. public TilemapTileAnimationFrame[] Frames { get; }
  15. /// <summary>
  16. /// Gets the total duration of the animation in seconds.
  17. /// </summary>
  18. public float TotalDuration
  19. {
  20. get
  21. {
  22. float total = 0;
  23. foreach (var frame in Frames)
  24. {
  25. total += frame.Duration;
  26. }
  27. return total;
  28. }
  29. }
  30. /// <summary>
  31. /// Gets the current frame index.
  32. /// </summary>
  33. public int CurrentFrameIndex
  34. {
  35. get
  36. {
  37. return _currentFrameIndex;
  38. }
  39. }
  40. /// <summary>
  41. /// Gets the current frame.
  42. /// </summary>
  43. public TilemapTileAnimationFrame CurrentFrame
  44. {
  45. get
  46. {
  47. return Frames[_currentFrameIndex];
  48. }
  49. }
  50. /// <summary>
  51. /// Initializes a new instance of the <see cref="TilemapTileAnimation"/> class.
  52. /// </summary>
  53. /// <param name="frames">The animation frames.</param>
  54. public TilemapTileAnimation(TilemapTileAnimationFrame[] frames)
  55. {
  56. Frames = frames;
  57. }
  58. /// <summary>
  59. /// Updates the animation.
  60. /// </summary>
  61. /// <param name="deltaTime">The time elapsed since the last update, in seconds.</param>
  62. public void Update(float deltaTime)
  63. {
  64. if (Frames.Length == 0)
  65. {
  66. return;
  67. }
  68. _elapsedTime += deltaTime;
  69. // Advance frames based on elapsed time
  70. while (_elapsedTime >= Frames[_currentFrameIndex].Duration)
  71. {
  72. _elapsedTime -= Frames[_currentFrameIndex].Duration;
  73. _currentFrameIndex = (_currentFrameIndex + 1) % Frames.Length;
  74. }
  75. }
  76. public TilemapTileAnimationFrame GetFrameAtTime(float time)
  77. {
  78. if (Frames.Length == 0)
  79. {
  80. throw new InvalidOperationException("Animation has no frames");
  81. }
  82. // Wrap time within total duration
  83. float totalDuration = TotalDuration;
  84. if (totalDuration <= 0)
  85. {
  86. return Frames[0];
  87. }
  88. time = time % totalDuration;
  89. if (time < 0)
  90. {
  91. time += totalDuration;
  92. }
  93. // Find the frame at this time
  94. float accumulated = 0;
  95. foreach (var frame in Frames)
  96. {
  97. accumulated += frame.Duration;
  98. if (time < accumulated)
  99. {
  100. return frame;
  101. }
  102. }
  103. // Should never reach here, but return last frame as fallback
  104. return Frames[Frames.Length - 1];
  105. }
  106. /// <summary>
  107. /// Resets the animation to the first frame.
  108. /// </summary>
  109. public void Reset()
  110. {
  111. _currentFrameIndex = 0;
  112. _elapsedTime = 0;
  113. }
  114. }
  115. }