WeaponManager.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  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 Robot_Rampage
  8. {
  9. static class WeaponManager
  10. {
  11. #region declarations
  12. static public List<Particle> Shots = new List<Particle>();
  13. static public Texture2D Texture;
  14. static public Rectangle shotRectangle =
  15. new Rectangle(0, 128, 32, 32);
  16. static public float WeaponSpeed = 600f;
  17. static private float shotTimer = 0f;
  18. static private float shotMinTimer = 0.15f;
  19. static private float rocketMinTimer = 0.5f;
  20. public enum WeaponType { Normal, Triple, Rocket };
  21. static public WeaponType CurrentWeaponType = WeaponType.Normal;
  22. static public float WeaponTimeRemaining = 0.0f;
  23. static private float weaponTimeDefault = 30.0f;
  24. static private float tripleWeaponSplitAngle = 15;
  25. static public List<Sprite> PowerUps = new List<Sprite>();
  26. static private int maxActivePowerups = 5;
  27. static private float timeSinceLastPowerup = 0.0f;
  28. static private float timeBetweenPowerups = 2.0f;
  29. static private Random rand = new Random();
  30. #endregion
  31. #region Properties
  32. static public float WeaponFireDelay
  33. {
  34. get
  35. {
  36. if (CurrentWeaponType == WeaponType.Rocket)
  37. {
  38. return rocketMinTimer;
  39. }
  40. else
  41. {
  42. return shotMinTimer;
  43. }
  44. }
  45. }
  46. static public bool CanFireWeapon
  47. {
  48. get
  49. {
  50. return (shotTimer >= WeaponFireDelay);
  51. }
  52. }
  53. #endregion
  54. #region Effects Management Methods
  55. private static void AddShot(
  56. Vector2 location,
  57. Vector2 velocity,
  58. int frame)
  59. {
  60. Particle shot = new Particle(
  61. location,
  62. Texture,
  63. shotRectangle,
  64. velocity,
  65. Vector2.Zero,
  66. 400f,
  67. 120,
  68. Color.White,
  69. Color.White);
  70. shot.AddFrame(new Rectangle(
  71. shotRectangle.X + shotRectangle.Width,
  72. shotRectangle.Y,
  73. shotRectangle.Width,
  74. shotRectangle.Height));
  75. shot.Animate = false;
  76. shot.Frame = frame;
  77. shot.RotateTo(velocity);
  78. Shots.Add(shot);
  79. }
  80. private static void createLargeExplosion(Vector2 location)
  81. {
  82. EffectsManager.AddLargeExplosion(
  83. location + new Vector2(-10, -10));
  84. EffectsManager.AddLargeExplosion(
  85. location + new Vector2(-10, 10));
  86. EffectsManager.AddLargeExplosion(
  87. location + new Vector2(10, 10));
  88. EffectsManager.AddLargeExplosion(
  89. location + new Vector2(10, -10));
  90. EffectsManager.AddLargeExplosion(location);
  91. }
  92. #endregion
  93. #region Weapons Management Methods
  94. private static void checkWeaponUpgradeExpire(float elapsed)
  95. {
  96. if (CurrentWeaponType != WeaponType.Normal)
  97. {
  98. WeaponTimeRemaining -= elapsed;
  99. if (WeaponTimeRemaining <= 0)
  100. {
  101. CurrentWeaponType = WeaponType.Normal;
  102. }
  103. }
  104. }
  105. public static void FireWeapon(Vector2 location, Vector2 velocity)
  106. {
  107. switch (CurrentWeaponType)
  108. {
  109. case WeaponType.Normal:
  110. AddShot(location, velocity, 0);
  111. break;
  112. case WeaponType.Triple:
  113. AddShot(location, velocity, 0);
  114. float baseAngle = (float)Math.Atan2(
  115. velocity.Y,
  116. velocity.X);
  117. float offset = MathHelper.ToRadians(
  118. tripleWeaponSplitAngle);
  119. AddShot(
  120. location,
  121. new Vector2(
  122. (float)Math.Cos(baseAngle - offset),
  123. (float)Math.Sin(baseAngle - offset)
  124. ) * velocity.Length(),
  125. 0);
  126. AddShot(
  127. location,
  128. new Vector2(
  129. (float)Math.Cos(baseAngle + offset),
  130. (float)Math.Sin(baseAngle + offset)
  131. ) * velocity.Length(),
  132. 0);
  133. break;
  134. case WeaponType.Rocket:
  135. AddShot(location, velocity, 1);
  136. break;
  137. }
  138. shotTimer = 0.0f;
  139. }
  140. private static void tryToSpawnPowerup(int x, int y, WeaponType type)
  141. {
  142. if (PowerUps.Count >= maxActivePowerups)
  143. {
  144. return;
  145. }
  146. Rectangle thisDestination =
  147. TileMap.SquareWorldRectangle(new Vector2(x, y));
  148. foreach (Sprite powerup in PowerUps)
  149. {
  150. if (powerup.WorldRectangle == thisDestination)
  151. {
  152. return;
  153. }
  154. }
  155. if (!(PathFinder.FindPath(
  156. new Vector2(x, y),
  157. Player.PathingNodePosition) == null))
  158. {
  159. Sprite newPowerup = new Sprite(
  160. new Vector2(thisDestination.X, thisDestination.Y),
  161. Texture,
  162. new Rectangle(64, 128, 32, 32),
  163. Vector2.Zero);
  164. newPowerup.Animate = false;
  165. newPowerup.CollisionRadius = 14;
  166. newPowerup.AddFrame(new Rectangle(96, 128, 32, 32));
  167. if (type == WeaponType.Rocket)
  168. newPowerup.Frame = 1;
  169. PowerUps.Add(newPowerup);
  170. timeSinceLastPowerup = 0.0f;
  171. }
  172. }
  173. private static void checkPowerupSpawns(float elapsed)
  174. {
  175. timeSinceLastPowerup += elapsed;
  176. if (timeSinceLastPowerup >= timeBetweenPowerups)
  177. {
  178. WeaponType type = WeaponType.Triple;
  179. if (rand.Next(0, 2) == 1)
  180. {
  181. type = WeaponType.Rocket;
  182. }
  183. tryToSpawnPowerup(
  184. rand.Next(0, TileMap.MapWidth),
  185. rand.Next(0, TileMap.MapHeight),
  186. type);
  187. }
  188. }
  189. #endregion
  190. #region Collision Detection
  191. private static void checkShotWallImpacts(Sprite shot)
  192. {
  193. if (shot.Expired)
  194. {
  195. return;
  196. }
  197. if (TileMap.IsWallTile(
  198. TileMap.GetSquareAtPixel(shot.WorldCenter)))
  199. {
  200. shot.Expired = true;
  201. if (shot.Frame == 0)
  202. {
  203. EffectsManager.AddSparksEffect(
  204. shot.WorldCenter,
  205. shot.Velocity);
  206. }
  207. else
  208. {
  209. createLargeExplosion(shot.WorldCenter);
  210. checkRocketSplashDamage(shot.WorldCenter);
  211. }
  212. }
  213. }
  214. private static void checkPowerupPickups()
  215. {
  216. for (int x = PowerUps.Count - 1; x >= 0; x--)
  217. {
  218. if (Player.BaseSprite.IsCircleColliding(
  219. PowerUps[x].WorldCenter,
  220. PowerUps[x].CollisionRadius))
  221. {
  222. switch (PowerUps[x].Frame)
  223. {
  224. case 0: CurrentWeaponType = WeaponType.Triple;
  225. break;
  226. case 1: CurrentWeaponType = WeaponType.Rocket;
  227. break;
  228. }
  229. WeaponTimeRemaining = weaponTimeDefault;
  230. PowerUps.RemoveAt(x);
  231. }
  232. }
  233. }
  234. private static void checkShotEnemyImpacts(Sprite shot)
  235. {
  236. if (shot.Expired)
  237. {
  238. return;
  239. }
  240. foreach (Enemy enemy in EnemyManager.Enemies)
  241. {
  242. if (!enemy.Destroyed)
  243. {
  244. if (shot.IsCircleColliding(
  245. enemy.EnemyBase.WorldCenter,
  246. enemy.EnemyBase.CollisionRadius))
  247. {
  248. shot.Expired = true;
  249. enemy.Destroyed = true;
  250. GameManager.Score += 10;
  251. if (shot.Frame == 0)
  252. {
  253. EffectsManager.AddExplosion(
  254. enemy.EnemyBase.WorldCenter,
  255. enemy.EnemyBase.Velocity / 30);
  256. }
  257. else
  258. {
  259. if (shot.Frame == 1)
  260. {
  261. createLargeExplosion(shot.WorldCenter);
  262. checkRocketSplashDamage(shot.WorldCenter);
  263. }
  264. }
  265. }
  266. }
  267. }
  268. }
  269. private static void checkRocketSplashDamage(Vector2 location)
  270. {
  271. int rocketSplashRadius = 40;
  272. foreach (Enemy enemy in EnemyManager.Enemies)
  273. {
  274. if (!enemy.Destroyed)
  275. {
  276. if (enemy.EnemyBase.IsCircleColliding(
  277. location, rocketSplashRadius))
  278. {
  279. enemy.Destroyed = true;
  280. GameManager.Score += 10;
  281. EffectsManager.AddExplosion(
  282. enemy.EnemyBase.WorldCenter,
  283. Vector2.Zero);
  284. }
  285. }
  286. }
  287. }
  288. #endregion
  289. #region Update and Draw
  290. static public void Update(GameTime gameTime)
  291. {
  292. float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
  293. shotTimer += elapsed;
  294. checkWeaponUpgradeExpire(elapsed);
  295. for (int x = Shots.Count - 1; x >= 0; x--)
  296. {
  297. Shots[x].Update(gameTime);
  298. checkShotWallImpacts(Shots[x]);
  299. checkShotEnemyImpacts(Shots[x]);
  300. if (Shots[x].Expired)
  301. {
  302. Shots.RemoveAt(x);
  303. }
  304. }
  305. checkPowerupSpawns(elapsed);
  306. checkPowerupPickups();
  307. }
  308. static public void Draw(SpriteBatch spriteBatch)
  309. {
  310. foreach (Particle sprite in Shots)
  311. {
  312. sprite.Draw(spriteBatch);
  313. }
  314. foreach (Sprite sprite in PowerUps)
  315. {
  316. sprite.Draw(spriteBatch);
  317. }
  318. }
  319. #endregion
  320. }
  321. }