Butterfly.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. using System;
  2. using AtomicEngine;
  3. class FloatRandom : Random
  4. {
  5. public float Random() { return (float)NextDouble(); }
  6. }
  7. public class Butterfly : CSComponent
  8. {
  9. float speed;
  10. float direction;
  11. float desiredDirection;
  12. float rotationSpeed = 10.0f;
  13. float time = 0.0f;
  14. Vector2 pos;
  15. AnimatedSprite2D sprite;
  16. public void Start()
  17. {
  18. if (halfWidth == 0.0f)
  19. {
  20. random = new FloatRandom();
  21. var graphics = AtomicNET.GetSubsystem<Graphics>();
  22. halfWidth = graphics.Width * Constants.PIXEL_SIZE * 0.5f;
  23. halfHeight = graphics.Height * Constants.PIXEL_SIZE * 0.5f;
  24. animationSet = AtomicNET.Cache.GetResource<AnimationSet2D>("Sprites/butterfly.scml");
  25. }
  26. speed = 1 + 2.0f * random.Random();
  27. direction = random.Random() * (float)Math.PI * 2.0f;
  28. pos = Node.Position2D;
  29. sprite = (AnimatedSprite2D)Node.CreateComponent("AnimatedSprite2D");
  30. sprite.Speed = .1f + random.Random() * 2.0f;
  31. sprite.AnimationSet = animationSet;
  32. sprite.SetAnimation("idle");
  33. sprite.Color = new Color(.1f + random.Random() * .9f, .1f + random.Random() * .9f, .1f + random.Random() * .9f, 1);
  34. sprite.BlendMode = BlendMode.BLEND_ALPHA;
  35. }
  36. void Update(float timeStep)
  37. {
  38. time += timeStep;
  39. if (time % 1000 / 1000 < 0.5f)
  40. desiredDirection = random.Random() * (float)Math.PI * 2;
  41. direction = circWrapTo(direction, desiredDirection, rotationSpeed * timeStep);
  42. pos.X += (float)Math.Cos(direction) * speed * timeStep;
  43. pos.Y += (float)Math.Sin(direction) * speed * timeStep;
  44. Node.Position2D = pos;
  45. Node.Rotation2D = (direction + (float)Math.PI * 3 / 2) * (180 / (float)Math.PI);
  46. //check if our butterfly is out of bounds
  47. if (pos.X < -halfWidth || pos.Y < -halfHeight || pos.X > halfWidth || pos.Y > halfHeight)
  48. {
  49. // TODO: We need to remove the component first, then the Node
  50. // The component removal removes the component from the scene Update
  51. // Which at the time of writing this comment, Node.Remove is not
  52. var node = Node;
  53. Remove();
  54. node.Remove();
  55. }
  56. }
  57. float circWrapTo(float value, float target, float step)
  58. {
  59. if (value == target)
  60. return target;
  61. var max = (float)Math.PI * 2;
  62. var result = value;
  63. var d = wrappedDistance(value, target, max);
  64. if (Math.Abs(d) < step)
  65. return target;
  66. result += (d < 0 ? -1 : 1) * step;
  67. if (result > max)
  68. result = result - max;
  69. else if (result < 0)
  70. result = max + result;
  71. return result;
  72. }
  73. float wrappedDistance(float a, float b, float max)
  74. {
  75. if (a == b) return 0;
  76. float l;
  77. float r;
  78. if (a < b)
  79. {
  80. l = -a - max + b;
  81. r = b - a;
  82. }
  83. else
  84. {
  85. l = b - a;
  86. r = max - a + b;
  87. }
  88. if (Math.Abs(l) > Math.Abs(r))
  89. return r;
  90. else
  91. return l;
  92. }
  93. static FloatRandom random;
  94. static float halfWidth = 0.0f;
  95. static float halfHeight = 0.0f;
  96. static AnimationSet2D animationSet;
  97. }