PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/XSpriter/CharacterAnimator.cs

https://bitbucket.org/dylanwolf/xspriter
C# | 184 lines | 156 code | 26 blank | 2 comment | 20 complexity | 51ffc580218e6e0e515ee3bd9bd8d36c MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.Xna.Framework;
  6. using Microsoft.Xna.Framework.Graphics;
  7. namespace FuncWorks.XNA.XSpriter
  8. {
  9. public class CharacterAnimator
  10. {
  11. public CharacterData Data;
  12. public Boolean Playing;
  13. public Vector2 Position;
  14. public Double Timer;
  15. public Int32 CurrentAnimation;
  16. public Int32 FrameIndex;
  17. public Boolean FlipX;
  18. public Boolean FlipY;
  19. public List<List<RuntimeTransform>> Transforms;
  20. public float LayerStart = 0;
  21. public float LayerStep = 0.01f;
  22. public CharacterAnimator(CharacterData data)
  23. {
  24. Data = data;
  25. Transforms = new List<List<RuntimeTransform>>();
  26. for (int i = 0; i < data.Animations.Count; i++)
  27. {
  28. Transforms.Add(new List<RuntimeTransform>());
  29. }
  30. }
  31. public void ResetAnimation()
  32. {
  33. Timer = 0;
  34. FrameIndex = 0;
  35. }
  36. public void SetAnimation(int animationIndex)
  37. {
  38. if (animationIndex != CurrentAnimation)
  39. {
  40. CurrentAnimation = animationIndex;
  41. ResetAnimation();
  42. }
  43. }
  44. public void SetAnimation(string animationName)
  45. {
  46. int? id = Data.GetAnimationIdByName(animationName);
  47. if (id.HasValue)
  48. {
  49. SetAnimation(id.Value);
  50. }
  51. }
  52. public Animation GetCurrentAnimation()
  53. {
  54. return Data.Animations[CurrentAnimation];
  55. }
  56. public float? GetCurrentLayerForTimeline(int timelineId)
  57. {
  58. float result = LayerStart;
  59. for (int i = 0; i < Data.Animations[CurrentAnimation].Frames[FrameIndex].Objects.Length; i++)
  60. {
  61. if (Data.Animations[CurrentAnimation].Frames[FrameIndex].Objects[i].TimelineId.Equals(timelineId))
  62. {
  63. return result;
  64. }
  65. result += LayerStep;
  66. }
  67. return null;
  68. }
  69. public RenderedPosition? GetCurrentRenderedPositionForTimeline(int timelineId)
  70. {
  71. // Get the frame image
  72. FrameImage fimg = null;
  73. Frame frame = Data.Animations[CurrentAnimation].Frames[FrameIndex];
  74. float layer = LayerStart;
  75. foreach (FrameImage fi in frame.Objects)
  76. {
  77. if (fi.TimelineId.Equals(timelineId))
  78. {
  79. fimg = fi;
  80. break;
  81. }
  82. layer += LayerStep;
  83. }
  84. if (fimg == null)
  85. {
  86. return null;
  87. }
  88. RenderedPosition result = GetRenderedPosition(frame, fimg);
  89. result.Layer = layer;
  90. return result;
  91. }
  92. public RenderedPosition GetRenderedPosition(Frame frame, FrameImage fimg)
  93. {
  94. // Apply transforms
  95. AnimationTransform transform = frame.ApplyBoneTransforms(fimg, Transforms[CurrentAnimation]);
  96. RenderedPosition result = new RenderedPosition();
  97. result.Positon = Vector2.Zero;
  98. result.Positon.Y = Position.Y + (transform.Position.Y * (FlipY ? -1 : 1));
  99. result.Positon.X = Position.X + (transform.Position.X * (FlipX ? -1 : 1));
  100. bool flipX = FlipX;
  101. bool flipY = FlipY;
  102. result.Angle = transform.Angle;
  103. if (flipX != flipY) { result.Angle *= -1; }
  104. result.Pivot = fimg.Pivot;
  105. if (flipX) { result.Pivot.X = Data.Textures[fimg.TextureFolder][fimg.TextureFile].Texture.Width - result.Pivot.X; }
  106. if (flipY) { result.Pivot.Y = Data.Textures[fimg.TextureFolder][fimg.TextureFile].Texture.Height - result.Pivot.Y; }
  107. result.Scale = transform.Scale;
  108. if (result.Scale.X < 0)
  109. {
  110. result.Scale.X = -result.Scale.X;
  111. flipX = !flipX;
  112. }
  113. if (result.Scale.Y < 0)
  114. {
  115. result.Scale.Y = -result.Scale.Y;
  116. flipY = !flipY;
  117. }
  118. result.Effects = SpriteEffects.None;
  119. if (flipX) { result.Effects |= SpriteEffects.FlipHorizontally; }
  120. if (flipY) { result.Effects |= SpriteEffects.FlipVertically; }
  121. return result;
  122. }
  123. public void Update(GameTime gameTime)
  124. {
  125. if (Playing)
  126. {
  127. Timer += gameTime.ElapsedGameTime.TotalMilliseconds;
  128. if (Timer > Data.Animations[CurrentAnimation].Length)
  129. {
  130. if (Data.Animations[CurrentAnimation].Looping)
  131. {
  132. Timer %= Data.Animations[CurrentAnimation].Length;
  133. }
  134. else
  135. {
  136. Timer = Data.Animations[CurrentAnimation].Length;
  137. }
  138. }
  139. FrameIndex =
  140. (int)MathHelper.Clamp(
  141. (int)Math.Ceiling((Timer / 1000.0) * Data.FramesPerSecond),
  142. 0, Data.Animations[CurrentAnimation].Frames.Length - 1);
  143. }
  144. }
  145. public void Draw(SpriteBatch spriteBatch)
  146. {
  147. Frame frame = Data.Animations[CurrentAnimation].Frames[FrameIndex];
  148. float layer = LayerStart;
  149. foreach (FrameImage ki in frame.Objects)
  150. {
  151. RenderedPosition pos = GetRenderedPosition(frame, ki);
  152. spriteBatch.Draw(Data.Textures[ki.TextureFolder][ki.TextureFile].Texture, pos.Positon, null, Color.White,
  153. pos.Angle, pos.Pivot, pos.Scale, pos.Effects, layer);
  154. layer += LayerStep;
  155. }
  156. }
  157. }
  158. }