Butterfly.cs 3.3 KB

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