| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- using System;
- namespace MonoGame.Extended.Tilemaps
- {
- /// <summary>
- /// Represents a frame-based animation for a tile.
- /// </summary>
- public class TilemapTileAnimation
- {
- private int _currentFrameIndex;
- private float _elapsedTime;
- /// <summary>
- /// Gets the animation frames.
- /// </summary>
- public TilemapTileAnimationFrame[] Frames { get; }
- /// <summary>
- /// Gets the total duration of the animation in seconds.
- /// </summary>
- public float TotalDuration
- {
- get
- {
- float total = 0;
- foreach (var frame in Frames)
- {
- total += frame.Duration;
- }
- return total;
- }
- }
- /// <summary>
- /// Gets the current frame index.
- /// </summary>
- public int CurrentFrameIndex
- {
- get
- {
- return _currentFrameIndex;
- }
- }
- /// <summary>
- /// Gets the current frame.
- /// </summary>
- public TilemapTileAnimationFrame CurrentFrame
- {
- get
- {
- return Frames[_currentFrameIndex];
- }
- }
- /// <summary>
- /// Initializes a new instance of the <see cref="TilemapTileAnimation"/> class.
- /// </summary>
- /// <param name="frames">The animation frames.</param>
- public TilemapTileAnimation(TilemapTileAnimationFrame[] frames)
- {
- Frames = frames;
- }
- /// <summary>
- /// Updates the animation.
- /// </summary>
- /// <param name="deltaTime">The time elapsed since the last update, in seconds.</param>
- public void Update(float deltaTime)
- {
- if (Frames.Length == 0)
- {
- return;
- }
- _elapsedTime += deltaTime;
- // Advance frames based on elapsed time
- while (_elapsedTime >= Frames[_currentFrameIndex].Duration)
- {
- _elapsedTime -= Frames[_currentFrameIndex].Duration;
- _currentFrameIndex = (_currentFrameIndex + 1) % Frames.Length;
- }
- }
- public TilemapTileAnimationFrame GetFrameAtTime(float time)
- {
- if (Frames.Length == 0)
- {
- throw new InvalidOperationException("Animation has no frames");
- }
- // Wrap time within total duration
- float totalDuration = TotalDuration;
- if (totalDuration <= 0)
- {
- return Frames[0];
- }
- time = time % totalDuration;
- if (time < 0)
- {
- time += totalDuration;
- }
- // Find the frame at this time
- float accumulated = 0;
- foreach (var frame in Frames)
- {
- accumulated += frame.Duration;
- if (time < accumulated)
- {
- return frame;
- }
- }
- // Should never reach here, but return last frame as fallback
- return Frames[Frames.Length - 1];
- }
- /// <summary>
- /// Resets the animation to the first frame.
- /// </summary>
- public void Reset()
- {
- _currentFrameIndex = 0;
- _elapsedTime = 0;
- }
- }
- }
|