Enemy.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. //---------------------------------------------------------------------------------
  2. // Written by Michael Hoffman
  3. // Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
  4. //----------------------------------------------------------------------------------
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using AtomicEngine;
  9. namespace AtomicBlaster
  10. {
  11. class Enemy : Entity
  12. {
  13. public static Random rand = new Random();
  14. private List<IEnumerator<int>> behaviours = new List<IEnumerator<int>>();
  15. private int timeUntilStart = 60;
  16. public bool IsActive { get { return timeUntilStart <= 0; } }
  17. public int PointValue { get; private set; }
  18. public Enemy(Texture2D image, Vector2 position)
  19. {
  20. this.image = image;
  21. Position = position;
  22. Radius = image.Width / 2f;
  23. color = Color.Transparent;
  24. PointValue = 1;
  25. }
  26. public static Enemy CreateSeeker(Vector2 position)
  27. {
  28. var enemy = new Enemy(Art.Seeker, position);
  29. enemy.AddBehaviour(enemy.FollowPlayer(0.9f));
  30. enemy.PointValue = 2;
  31. return enemy;
  32. }
  33. public static Enemy CreateWanderer(Vector2 position)
  34. {
  35. var enemy = new Enemy(Art.Wanderer, position);
  36. enemy.AddBehaviour(enemy.MoveRandomly());
  37. return enemy;
  38. }
  39. public override void Update()
  40. {
  41. if (timeUntilStart <= 0)
  42. ApplyBehaviours();
  43. else
  44. {
  45. timeUntilStart--;
  46. float mul = (1 - timeUntilStart / 60f);
  47. color = new Color(mul, mul, mul, mul);
  48. }
  49. Position += Velocity;
  50. Position = Vector2.Clamp(Position, Size / 2, GameRoot.ScreenSize - Size / 2);
  51. Velocity *= 0.8f;
  52. }
  53. public override void Draw(/*SpriteBatch spriteBatch*/)
  54. {
  55. /*
  56. if (timeUntilStart > 0)
  57. {
  58. // Draw an expanding, fading-out version of the sprite as part of the spawn-in effect.
  59. float factor = timeUntilStart / 60f; // decreases from 1 to 0 as the enemy spawns in
  60. spriteBatch.Draw(image, Position, null, Color.White * factor, Orientation, Size / 2f, 2 - factor, 0, 0);
  61. }
  62. base.Draw(spriteBatch);
  63. */
  64. }
  65. private void AddBehaviour(IEnumerable<int> behaviour)
  66. {
  67. behaviours.Add(behaviour.GetEnumerator());
  68. }
  69. private void ApplyBehaviours()
  70. {
  71. for (int i = 0; i < behaviours.Count; i++)
  72. {
  73. if (!behaviours[i].MoveNext())
  74. behaviours.RemoveAt(i--);
  75. }
  76. }
  77. public void HandleCollision(Enemy other)
  78. {
  79. var d = Position - other.Position;
  80. Velocity += 10 * d / (d.LengthSquared + 1);
  81. }
  82. public void WasShot()
  83. {
  84. IsExpired = true;
  85. PlayerStatus.AddPoints(PointValue);
  86. PlayerStatus.IncreaseMultiplier();
  87. float hue1 = rand.NextFloat(0, 6);
  88. float hue2 = (hue1 + rand.NextFloat(0, 2)) % 6f;
  89. Color color1 = ColorUtil.HSVToColor(hue1, 0.5f, 1);
  90. Color color2 = ColorUtil.HSVToColor(hue2, 0.5f, 1);
  91. for (int i = 0; i < 120; i++)
  92. {
  93. float speed = 18f * (1f - 1 / rand.NextFloat(1, 10));
  94. var state = new ParticleState()
  95. {
  96. Velocity = rand.NextVector2(speed, speed),
  97. Type = ParticleType.Enemy,
  98. LengthMultiplier = 1
  99. };
  100. Color color = Color.Lerp(color1, color2, rand.NextFloat(0, 1));
  101. GameRoot.ParticleManager.CreateParticle(Art.LineParticle, Position, color, 190, 1.5f, state);
  102. }
  103. //Sound.Explosion.Play(0.5f, rand.NextFloat(-0.2f, 0.2f), 0);
  104. }
  105. #region Behaviours
  106. IEnumerable<int> FollowPlayer(float acceleration)
  107. {
  108. while (true)
  109. {
  110. if (!PlayerShip.Instance.IsDead)
  111. Velocity += (PlayerShip.Instance.Position - Position).ScaleTo(acceleration);
  112. if (Velocity != Vector2.Zero)
  113. Orientation = Velocity.ToAngle();
  114. yield return 0;
  115. }
  116. }
  117. IEnumerable<int> MoveRandomly()
  118. {
  119. float direction = rand.NextFloat(0, MathHelper.TwoPi);
  120. while (true)
  121. {
  122. direction += rand.NextFloat(-0.1f, 0.1f);
  123. direction = MathHelper.WrapAngle(direction);
  124. for (int i = 0; i < 6; i++)
  125. {
  126. Velocity += MathUtil.FromPolar(direction, 0.4f);
  127. Orientation -= 0.05f;
  128. var bounds = GameRoot.ScreenBounds;
  129. bounds.Inflate(-image.Width / 2 - 1, -image.Height / 2 - 1);
  130. // if the enemy is outside the bounds, make it move away from the edge
  131. if (!bounds.Contains(Position))
  132. direction = (GameRoot.ScreenSize / 2 - Position).ToAngle() + rand.NextFloat(-MathHelper.PiOver2, MathHelper.PiOver2);
  133. yield return 0;
  134. }
  135. }
  136. }
  137. #endregion
  138. }
  139. }