diff options
Diffstat (limited to 'Plugins/MonoGame.Extended/tests/MonoGame.Extended.Tests/Sprites')
-rw-r--r-- | Plugins/MonoGame.Extended/tests/MonoGame.Extended.Tests/Sprites/SpriteSheetAnimationTests.cs | 910 | ||||
-rw-r--r-- | Plugins/MonoGame.Extended/tests/MonoGame.Extended.Tests/Sprites/SpriteTests.cs | 91 |
2 files changed, 1001 insertions, 0 deletions
diff --git a/Plugins/MonoGame.Extended/tests/MonoGame.Extended.Tests/Sprites/SpriteSheetAnimationTests.cs b/Plugins/MonoGame.Extended/tests/MonoGame.Extended.Tests/Sprites/SpriteSheetAnimationTests.cs new file mode 100644 index 0000000..35ad3e3 --- /dev/null +++ b/Plugins/MonoGame.Extended/tests/MonoGame.Extended.Tests/Sprites/SpriteSheetAnimationTests.cs @@ -0,0 +1,910 @@ +using System; +using Microsoft.Xna.Framework; +using MonoGame.Extended.Sprites; +using MonoGame.Extended.TextureAtlases; +using Xunit; + +namespace MonoGame.Extended.Tests.Sprites +{ + public class SpriteSheetAnimationTests + { + [Theory] + [InlineData(0, 0)] + [InlineData(0, 0.9f)] + [InlineData(1, 1f)] + [InlineData(1, 1.9f)] + [InlineData(0, 2f)] + [InlineData(0, 2.9f)] + [InlineData(1, 3f)] + [InlineData(0, 4f)] + [InlineData(1, 5f)] + public void Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Not_Complete(int expectedTextureRegionIndex, float time) + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(time)); + + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[expectedTextureRegionIndex], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + } + + [Fact] + public void Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Not_Complete_Over_Multiple_Updates() + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(0)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + } + + [Theory] + [InlineData(0, 0.9f)] + [InlineData(1, 1f)] + [InlineData(1, 1.1f)] + [InlineData(1, 1.9f)] + public void Non_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Not_Complete(int expectedTextureRegionIndex, float time) + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + false + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(time)); + + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[expectedTextureRegionIndex], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + } + + [Theory] + [InlineData(1, 2f)] + [InlineData(1, 3f)] + [InlineData(1, 4f)] + public void Non_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Complete_When_AnimationDuration_Is_Reached(int expectedTextureRegionIndex, float time) + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + false + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(time)); + + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[expectedTextureRegionIndex], spriteSheetAnimation.CurrentFrame); + Assert.True(spriteSheetAnimation.IsComplete); + Assert.True(isCompleteFired); + } + + [Fact] + public void Non_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Complete_When_AnimationDuration_Is_Reached_Over_Multiple_Updates() + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + false + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(0)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.True(spriteSheetAnimation.IsComplete); + Assert.True(isCompleteFired); + + isCompleteFired = false; // Reset isCompleteFired for next execution + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.True(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); // Event is not fired again as animation was already completed + } + + [Theory] + [InlineData(1, 0)] + [InlineData(1, 0.9f)] + [InlineData(0, 1f)] + [InlineData(0, 1.9f)] + [InlineData(1, 2f)] + [InlineData(1, 2.9f)] + [InlineData(0, 3f)] + [InlineData(1, 4f)] + [InlineData(0, 5f)] + public void Reversed_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Not_Complete(int expectedTextureRegionIndex, float time) + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + true, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(time)); + + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[expectedTextureRegionIndex], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + } + + [Fact] + public void Reversed_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Not_Complete_Over_Multiple_Updates() + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + true, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(0)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + } + + [Theory] + [InlineData(1, 0.9f)] + [InlineData(0, 1f)] + [InlineData(0, 1.1f)] + [InlineData(0, 1.9f)] + public void Reversed_Non_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Not_Complete(int expectedTextureRegionIndex, float time) + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + false, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(time)); + + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[expectedTextureRegionIndex], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + } + + [Theory] + [InlineData(0, 2f)] + [InlineData(0, 3f)] + [InlineData(0, 4f)] + public void Reversed_Non_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Complete_When_AnimationDuration_Is_Reached(int expectedTextureRegionIndex, float time) + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + false, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(time)); + + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[expectedTextureRegionIndex], spriteSheetAnimation.CurrentFrame); + Assert.True(spriteSheetAnimation.IsComplete); + Assert.True(isCompleteFired); + } + + [Fact] + public void Reversed_Non_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Complete_When_AnimationDuration_Is_Reached_Over_Multiple_Updates() + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + false, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(0)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.True(spriteSheetAnimation.IsComplete); + Assert.True(isCompleteFired); + + isCompleteFired = false; // Reset isCompleteFired for next execution + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.True(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); // Event is not fired again as animation was already completed; + } + + [Theory] + [InlineData(0, 0)] + [InlineData(0, 0.9f)] + [InlineData(1, 1f)] + [InlineData(1, 1.9f)] + [InlineData(0, 2f)] + [InlineData(0, 2.9f)] + [InlineData(1, 3f)] + [InlineData(0, 4f)] + [InlineData(1, 5f)] + [InlineData(0, 6f)] + [InlineData(1, 7f)] + [InlineData(0, 8f)] + public void PingPong_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Not_Complete(int expectedTextureRegionIndex, float time) + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + true, + false, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(time)); + + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[expectedTextureRegionIndex], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + } + + [Fact] + public void PingPong_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Not_Complete_Over_Multiple_Updates() + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + true, + false, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(0)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + } + + [Theory] + [InlineData(0, 0.9f)] + [InlineData(1, 1f)] + [InlineData(1, 1.9f)] + [InlineData(0, 2f)] + [InlineData(0, 2.9f)] + public void PingPong_Non_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Not_Complete(int expectedTextureRegionIndex, float time) + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + false, + false, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(time)); + + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[expectedTextureRegionIndex], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + } + + [Theory] + [InlineData(0, 3f)] + [InlineData(0, 4f)] + [InlineData(0, 5f)] + public void PingPong_Non_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Complete_When_AnimationDuration_Is_Reached(int expectedTextureRegionIndex, float time) + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + false, + false, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(time)); + + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[expectedTextureRegionIndex], spriteSheetAnimation.CurrentFrame); + Assert.True(spriteSheetAnimation.IsComplete); + Assert.True(isCompleteFired); + } + + [Fact] + public void PingPong_Non_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Complete_When_AnimationDuration_Is_Reached_Over_Multiple_Updates() + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + var textureRegion2D3 = new TextureRegion2D("Region 3", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2, textureRegion2D3 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1, 2 }, + 1, + false, + false, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(0)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[2], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.True(spriteSheetAnimation.IsComplete); + Assert.True(isCompleteFired); + + isCompleteFired = false; // Reset isCompleteFired for next execution + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.True(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); // Event is not fired again as animation was already completed + } + + [Theory] + [InlineData(1, 0)] + [InlineData(1, 0.9f)] + [InlineData(0, 1f)] + [InlineData(0, 1.9f)] + [InlineData(1, 2f)] + [InlineData(1, 2.9f)] + [InlineData(0, 3f)] + [InlineData(1, 4f)] + [InlineData(0, 5f)] + [InlineData(1, 6f)] + [InlineData(0, 7f)] + [InlineData(1, 8f)] + public void Reversed_PingPong_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Not_Complete(int expectedTextureRegionIndex, float time) + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + true, + true, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(time)); + + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[expectedTextureRegionIndex], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + } + + [Fact] + public void Reversed_PingPong_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Not_Complete_Over_Multiple_Updates() + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + true, + true, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(0)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + } + + [Theory] + [InlineData(1, 0.9f)] + [InlineData(0, 1f)] + [InlineData(0, 1.9f)] + [InlineData(1, 2f)] + [InlineData(1, 2.9f)] + public void Reversed_PingPong_Non_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Not_Complete(int expectedTextureRegionIndex, float time) + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + false, + true, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(time)); + + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[expectedTextureRegionIndex], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + } + + [Theory] + [InlineData(1, 3f)] + [InlineData(1, 4f)] + [InlineData(1, 5f)] + public void Reversed_PingPong_Non_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Complete_When_AnimationDuration_Is_Reached(int expectedTextureRegionIndex, float time) + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1 }, + 1, + false, + true, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(time)); + + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[expectedTextureRegionIndex], spriteSheetAnimation.CurrentFrame); + Assert.True(spriteSheetAnimation.IsComplete); + Assert.True(isCompleteFired); + } + + [Fact] + public void Reversed_PingPong_Non_Looping_SpriteSheetAnimation_Should_Return_Correct_Frame_And_Complete_When_AnimationDuration_Is_Reached_Over_Multiple_Updates() + { + var textureRegion2D1 = new TextureRegion2D("Region 1", null, new Rectangle()); + var textureRegion2D2 = new TextureRegion2D("Region 2", null, new Rectangle()); + var textureRegion2D3 = new TextureRegion2D("Region 3", null, new Rectangle()); + + var textureRegions = new[] { textureRegion2D1, textureRegion2D2, textureRegion2D3 }; + + var spriteSheetAnimationData = new SpriteSheetAnimationData( + new[] { 0, 1, 2 }, + 1, + false, + true, + true + ); + + var spriteSheetAnimation = new SpriteSheetAnimation("Test", textureRegions, spriteSheetAnimationData); + + var isCompleteFired = false; + spriteSheetAnimation.OnCompleted += () => isCompleteFired = true; + + spriteSheetAnimation.Play(); + + var gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(0)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[2], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[0], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[1], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[2], spriteSheetAnimation.CurrentFrame); + Assert.False(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); + + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[2], spriteSheetAnimation.CurrentFrame); + Assert.True(spriteSheetAnimation.IsComplete); + Assert.True(isCompleteFired); + + isCompleteFired = false; // Reset isCompleteFired for next execution + gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromSeconds(1)); + spriteSheetAnimation.Update(gameTime); + + Assert.Equal(textureRegions[2], spriteSheetAnimation.CurrentFrame); + Assert.True(spriteSheetAnimation.IsComplete); + Assert.False(isCompleteFired); // Event is not fired again as animation was already completed + } + } +} diff --git a/Plugins/MonoGame.Extended/tests/MonoGame.Extended.Tests/Sprites/SpriteTests.cs b/Plugins/MonoGame.Extended/tests/MonoGame.Extended.Tests/Sprites/SpriteTests.cs new file mode 100644 index 0000000..307e272 --- /dev/null +++ b/Plugins/MonoGame.Extended/tests/MonoGame.Extended.Tests/Sprites/SpriteTests.cs @@ -0,0 +1,91 @@ +//using Microsoft.Xna.Framework; +//using Microsoft.Xna.Framework.Graphics; +//using MonoGame.Extended.Sprites; +//using MonoGame.Extended.TextureAtlases; +//using NSubstitute; +//using Xunit; + +//namespace MonoGame.Extended.Tests.Sprites +//{ +// +// public class SpriteTests +// { +// [Fact] +// public void Sprite_BoundingRectangleAfterPosition_Test() +// { +// var graphicsDevice = TestHelper.CreateGraphicsDevice(); +// var texture = Substitute.For<Texture2D>(graphicsDevice, 50, 200); +// var sprite = new Sprite(texture); + +// Assert.Equal(new RectangleF(375, 140, 50, 200), sprite.GetBoundingRectangle(new Vector2(400, 240), 0, Vector2.One)); +// } + +// [Fact] +// public void Sprite_BoundingRectangleAfterOrigin_Test() +// { +// var graphicsDevice = TestHelper.CreateGraphicsDevice(); +// var texture = Substitute.For<Texture2D>(graphicsDevice, 50, 200); +// var sprite = new Sprite(texture) { OriginNormalized = new Vector2(1.0f, 1.0f) }; + +// Assert.Equal(new RectangleF(-50, -200, 50, 200), sprite.GetBoundingRectangle(Vector2.Zero, 0, Vector2.One)); +// } + +// [Fact] +// public void Sprite_BoundingRectangleAfterScale_Test() +// { +// var graphicsDevice = TestHelper.CreateGraphicsDevice(); +// var texture = Substitute.For<Texture2D>(graphicsDevice, 50, 200); +// var sprite = new Sprite(texture); + +// Assert.Equal(new RectangleF(-50, -200, 100, 400), sprite.GetBoundingRectangle(Vector2.Zero, 0, Vector2.One * 2.0f)); +// } + +// [Fact] +// public void Sprite_BoundingRectangleAfterRotation_Test() +// { +// var graphicsDevice = TestHelper.CreateGraphicsDevice(); +// var texture = Substitute.For<Texture2D>(graphicsDevice, 50, 200); +// var sprite = new Sprite(texture); + +// AssertExtensions.AreApproximatelyEqual(new RectangleF(-100, -25, 200, 50), sprite.GetBoundingRectangle(Vector2.Zero, MathHelper.ToRadians(90), Vector2.One * 2.0f)); +// } + +// [Fact] +// public void Sprite_TextureRegionIsFullTextureWhenTextureConstructorIsUsed_Test() +// { +// var graphicsDevice = TestHelper.CreateGraphicsDevice(); +// var texture = Substitute.For<Texture2D>(graphicsDevice, 100, 200); +// var sprite = new Sprite(texture); + +// Assert.Equal(new Rectangle(0, 0, 100, 200), sprite.TextureRegion.Bounds); +// } + +// [Fact] +// public void Sprite_DefaultOriginIsCentre_Test() +// { +// var graphicsDevice = TestHelper.CreateGraphicsDevice(); +// var texture = Substitute.For<Texture2D>(graphicsDevice, 100, 200); +// var sprite = new Sprite(texture); + +// Assert.Equal(new Vector2(0.5f, 0.5f), sprite.OriginNormalized); +// Assert.Equal(new Vector2(50, 100), sprite.Origin); +// } + +// [Fact] +// public void Sprite_PreserveNormalizedOriginWhenTextureRegionChanges_Test() +// { +// var graphicsDevice = TestHelper.CreateGraphicsDevice(); +// var texture = Substitute.For<Texture2D>(graphicsDevice, 100, 100); +// var textureRegion = new TextureRegion2D(texture, 10, 20, 30, 40); +// var sprite = new Sprite(textureRegion); + +// Assert.Equal(new Vector2(0.5f, 0.5f), sprite.OriginNormalized); +// Assert.Equal(new Vector2(15, 20), sprite.Origin); + +// sprite.TextureRegion = new TextureRegion2D(texture, 30, 40, 50, 60); + +// Assert.Equal(new Vector2(0.5f, 0.5f), sprite.OriginNormalized); +// Assert.Equal(new Vector2(25, 30), sprite.Origin); +// } +// } +//} |