AsteroidManager.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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 Asteroid_Belt_Assault
  8. {
  9. class AsteroidManager
  10. {
  11. private int screenWidth = 800;
  12. private int screenHeight = 600;
  13. private int screenPadding = 10;
  14. private Rectangle initialFrame;
  15. private int asteroidFrames;
  16. private Texture2D texture;
  17. public List<Sprite> Asteroids = new List<Sprite>();
  18. private int minSpeed = 60;
  19. private int maxSpeed = 120;
  20. private Random rand = new Random();
  21. public void AddAsteroid()
  22. {
  23. Sprite newAsteroid = new Sprite(
  24. new Vector2(-500, -500),
  25. texture,
  26. initialFrame,
  27. Vector2.Zero);
  28. for (int x = 1; x < asteroidFrames; x++)
  29. {
  30. newAsteroid.AddFrame(new Rectangle(
  31. initialFrame.X + (initialFrame.Width * x),
  32. initialFrame.Y,
  33. initialFrame.Width,
  34. initialFrame.Height));
  35. }
  36. newAsteroid.Rotation =
  37. MathHelper.ToRadians((float)rand.Next(0, 360));
  38. newAsteroid.CollisionRadius = 15;
  39. Asteroids.Add(newAsteroid);
  40. }
  41. public void Clear()
  42. {
  43. Asteroids.Clear();
  44. }
  45. public AsteroidManager(
  46. int asteroidCount,
  47. Texture2D texture,
  48. Rectangle initialFrame,
  49. int asteroidFrames,
  50. int screenWidth,
  51. int screenHeight)
  52. {
  53. this.texture = texture;
  54. this.initialFrame = initialFrame;
  55. this.asteroidFrames = asteroidFrames;
  56. this.screenWidth = screenWidth;
  57. this.screenHeight = screenHeight;
  58. for (int x = 0; x < asteroidCount; x++)
  59. {
  60. AddAsteroid();
  61. }
  62. }
  63. private Vector2 randomLocation()
  64. {
  65. Vector2 location = Vector2.Zero;
  66. bool locationOK = true;
  67. int tryCount = 0;
  68. do
  69. {
  70. locationOK = true;
  71. switch (rand.Next(0, 3))
  72. {
  73. case 0:
  74. location.X = -initialFrame.Width;
  75. location.Y = rand.Next(0, screenHeight);
  76. break;
  77. case 1:
  78. location.X = screenWidth;
  79. location.Y = rand.Next(0, screenHeight);
  80. break;
  81. case 2:
  82. location.X = rand.Next(0, screenWidth);
  83. location.Y = -initialFrame.Height;
  84. break;
  85. }
  86. foreach (Sprite asteroid in Asteroids)
  87. {
  88. if (asteroid.IsBoxColliding(
  89. new Rectangle(
  90. (int)location.X,
  91. (int)location.Y,
  92. initialFrame.Width,
  93. initialFrame.Height)))
  94. {
  95. locationOK = false;
  96. }
  97. }
  98. tryCount++;
  99. if ((tryCount > 5) && locationOK == false)
  100. {
  101. location = new Vector2(-500, -500);
  102. locationOK = true;
  103. }
  104. } while (locationOK == false);
  105. return location;
  106. }
  107. private Vector2 randomVelocity()
  108. {
  109. Vector2 velocity = new Vector2(
  110. rand.Next(0, 101) - 50,
  111. rand.Next(0, 101) - 50);
  112. velocity.Normalize();
  113. velocity *= rand.Next(minSpeed, maxSpeed);
  114. return velocity;
  115. }
  116. private bool isOnScreen(Sprite asteroid)
  117. {
  118. if (asteroid.Destination.Intersects(
  119. new Rectangle(
  120. -screenPadding,
  121. -screenPadding,
  122. screenWidth + screenPadding,
  123. screenHeight + screenPadding)
  124. )
  125. )
  126. {
  127. return true;
  128. }
  129. else
  130. {
  131. return false;
  132. }
  133. }
  134. private void BounceAsteroids(Sprite asteroid1, Sprite asteroid2)
  135. {
  136. {
  137. Vector2 cOfMass = (asteroid1.Velocity +
  138. asteroid2.Velocity) / 2;
  139. Vector2 normal1 = asteroid2.Center - asteroid1.Center;
  140. normal1.Normalize();
  141. Vector2 normal2 = asteroid1.Center - asteroid2.Center;
  142. normal2.Normalize();
  143. asteroid1.Velocity -= cOfMass;
  144. asteroid1.Velocity =
  145. Vector2.Reflect(asteroid1.Velocity, normal1);
  146. asteroid1.Velocity += cOfMass;
  147. asteroid2.Velocity -= cOfMass;
  148. asteroid2.Velocity =
  149. Vector2.Reflect(asteroid2.Velocity, normal2);
  150. asteroid2.Velocity += cOfMass;
  151. }
  152. }
  153. public void Update(GameTime gameTime)
  154. {
  155. foreach (Sprite asteroid in Asteroids)
  156. {
  157. asteroid.Update(gameTime);
  158. if (!isOnScreen(asteroid))
  159. {
  160. asteroid.Location = randomLocation();
  161. asteroid.Velocity = randomVelocity();
  162. }
  163. }
  164. for (int x = 0; x < Asteroids.Count; x++)
  165. {
  166. for (int y = x + 1; y < Asteroids.Count; y++)
  167. {
  168. if (Asteroids[x].IsCircleColliding(
  169. Asteroids[y].Center, Asteroids[y].CollisionRadius))
  170. {
  171. BounceAsteroids(Asteroids[x], Asteroids[y]);
  172. }
  173. }
  174. }
  175. }
  176. public void Draw(SpriteBatch spriteBatch)
  177. {
  178. foreach (Sprite asteroid in Asteroids)
  179. {
  180. asteroid.Draw(spriteBatch);
  181. }
  182. }
  183. }
  184. }