EvolvedScreen.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // EvolvedScreen.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Text;
  13. using Microsoft.Xna.Framework;
  14. using Microsoft.Xna.Framework.Graphics;
  15. using Microsoft.Xna.Framework.Input;
  16. using System.Diagnostics;
  17. #endregion
  18. namespace Spacewar
  19. {
  20. /// <summary>
  21. /// SpacewarScreen is the main game screen
  22. /// </summary>
  23. public class EvolvedScreen : SpacewarScreen
  24. {
  25. private double sunScale = 1000.0;
  26. private Asteroid[] asteroids;
  27. private float levelTime;
  28. private int lastLevelTime;
  29. private bool ended;
  30. private double endTime;
  31. private static string[] scoreLookup = new string[] { "000", "001", "011", "111" };
  32. private static Vector3[] asteroidStarts = new Vector3[]
  33. {
  34. new Vector3(390, 240, 0),
  35. new Vector3(-390, -240, 0),
  36. new Vector3(390, -240, 0),
  37. new Vector3(-390, 240,0),
  38. new Vector3(-390, 240,0),
  39. new Vector3(390, 240,0),
  40. new Vector3(-390, -240,0)
  41. };
  42. private Random random = new Random();
  43. /// <summary>
  44. /// Creates a new SpacewarScreen
  45. /// </summary>
  46. public EvolvedScreen(Game game)
  47. : base(game)
  48. {
  49. backdrop = new SceneItem(game, new EvolvedBackdrop(game));
  50. const float factor = 46;
  51. backdrop.Center = new Vector3(.5f, .5f, 0);
  52. backdrop.Scale = new Vector3(16f * factor, 9f * factor, 1f);
  53. backdrop.Position = new Vector3(-.5f, -.5f, 0);
  54. scene.Add(backdrop);
  55. bullets = new Projectiles(game);
  56. particles = new Particles(game);
  57. ship1 = new Ship(game, PlayerIndex.One, SpacewarGame.Players[0].ShipClass, SpacewarGame.Players[0].Skin, new Vector3(SpacewarGame.Settings.Ships[0].StartPosition, 0.0f), bullets, particles);
  58. ship1.Paused = true;
  59. ship1.Radius = 15f;
  60. if (SpacewarGame.Players[0].ShipClass == ShipClass.Pencil)
  61. {
  62. ship1.ExtendedExtent[0] = new Vector3(0.0f, 25.0f, 0.0f);
  63. ship1.ExtendedExtent[1] = new Vector3(0.0f, -25.0f, 0.0f);
  64. }
  65. ship2 = new Ship(game, PlayerIndex.Two, SpacewarGame.Players[1].ShipClass, SpacewarGame.Players[1].Skin, new Vector3(SpacewarGame.Settings.Ships[1].StartPosition, 0.0f), bullets, particles);
  66. ship2.Paused = true;
  67. ship2.Radius = 15f;
  68. if (SpacewarGame.Players[1].ShipClass == ShipClass.Pencil)
  69. {
  70. ship2.ExtendedExtent[0] = new Vector3(0.0f, 25f, 0.0f);
  71. ship2.ExtendedExtent[1] = new Vector3(0.0f, -25f, 0.0f);
  72. }
  73. scene.Add(bullets);
  74. asteroids = new Asteroid[SpacewarGame.GameLevel + 2];
  75. for (int i = 0; i < SpacewarGame.GameLevel + 2; i++)
  76. {
  77. asteroids[i] = new Asteroid(game, random.NextDouble() > .5 ? AsteroidType.Large : AsteroidType.Small, asteroidStarts[i]);
  78. asteroids[i].Scale = new Vector3(SpacewarGame.Settings.AsteroidScale, SpacewarGame.Settings.AsteroidScale, SpacewarGame.Settings.AsteroidScale);
  79. asteroids[i].Paused = true;
  80. asteroids[i].Velocity = (float)random.Next(100) * Vector3.Normalize(new Vector3((float)(random.NextDouble() - .5), (float)(random.NextDouble() - .5), 0));
  81. scene.Add(asteroids[i]);
  82. }
  83. scene.Add(ship1);
  84. scene.Add(ship2);
  85. //Added after other objects so they draw over the top
  86. scene.Add(particles);
  87. //Sun last so its on top
  88. sun = new Sun(game, new EvolvedSun(game), new Vector3(-.5f, -.5f, 0));
  89. scene.Add(sun);
  90. //Reset health meters.
  91. SpacewarGame.Players[0].Health = 5;
  92. SpacewarGame.Players[1].Health = 5;
  93. }
  94. /// <summary>
  95. /// Update for SpacewarScreen uses the base Update method and adds Sun zoom animation
  96. /// and detects the end of the level time
  97. /// </summary>
  98. /// <param name="time">Game time</param>
  99. /// <param name="elapsedTime">Elapsed time since last update</param>
  100. /// <returns>
  101. /// The next gamestate to transition to. Default is the return value of an overlay or NONE. Override Update if you want to change this behaviour
  102. /// </returns>
  103. public override GameState Update(TimeSpan time, TimeSpan elapsedTime)
  104. {
  105. if (sunScale > 1)
  106. {
  107. //1st frame always has a big elapsed time so use that to set the start pos
  108. if (sunScale > 20.0)
  109. {
  110. sunScale = 20.0;
  111. }
  112. else
  113. {
  114. sunScale -= elapsedTime.TotalSeconds * 15.0;
  115. }
  116. if (sunScale < 1)
  117. {
  118. sunScale = 1;
  119. paused = false;
  120. ship1.Paused = false;
  121. ship2.Paused = false;
  122. foreach (Asteroid asteroid in asteroids)
  123. {
  124. asteroid.Paused = false;
  125. }
  126. //Kick off level timer
  127. levelTime = SpacewarGame.Settings.LevelTime;
  128. }
  129. //Zoom the Sun
  130. sun.Scale = new Vector3(SpacewarGame.Settings.Size * (float)sunScale, SpacewarGame.Settings.Size * (float)sunScale, 1f);
  131. }
  132. base.Update(time, elapsedTime);
  133. handleCollisions(time);
  134. //Update screentimer
  135. if (!paused)
  136. {
  137. levelTime -= (float)elapsedTime.TotalSeconds;
  138. if ((levelTime - lastLevelTime) < 0.0f)
  139. {
  140. //We have ticked down
  141. if (levelTime < 0.0f)
  142. {
  143. Sound.PlayCue(Sounds.CountDownExpire);
  144. }
  145. else if (levelTime < 6)
  146. {
  147. Sound.PlayCue(Sounds.CountDownWarning);
  148. }
  149. }
  150. lastLevelTime = (int)levelTime;
  151. }
  152. //When we run out of time show the totals
  153. if (!paused && (levelTime <= 0.0f))
  154. {
  155. //Stop everything while we count up the $$$
  156. paused = true;
  157. ended = true;
  158. ship1.Paused = true;
  159. ship2.Paused = true;
  160. ship1.Silence();
  161. ship2.Silence();
  162. foreach (Asteroid asteroid in asteroids)
  163. {
  164. asteroid.Paused = true;
  165. }
  166. bullets.Clear(); //No more bullets
  167. particles.Clear(); //No more particles
  168. endTime = time.TotalSeconds + 5; //Show scores for 5 seconds
  169. }
  170. if (ended && time.TotalSeconds > endTime)
  171. {
  172. //Don't need the screen anymore, shut it down!
  173. Shutdown();
  174. //Update scores and round
  175. SpacewarGame.Players[0].Cash += player1Score * 1000;
  176. SpacewarGame.Players[1].Cash += player2Score * 1000;
  177. if (player1Score > player2Score)
  178. {
  179. SpacewarGame.Players[0].Score++;
  180. SpacewarGame.GameLevel++;
  181. }
  182. else if (player2Score > player1Score)
  183. {
  184. SpacewarGame.Players[1].Score++;
  185. SpacewarGame.GameLevel++;
  186. }
  187. else
  188. {
  189. //nobody won - tie game
  190. //replay that level
  191. }
  192. if (SpacewarGame.Players[0].Score == 3 || SpacewarGame.Players[1].Score == 3)
  193. {
  194. return GameState.Victory;
  195. }
  196. else
  197. {
  198. return GameState.ShipUpgrade;
  199. }
  200. }
  201. else
  202. {
  203. return GameState.None;
  204. }
  205. }
  206. /// <summary>
  207. /// Renders the screen using the base class and adds the HUD
  208. /// </summary>
  209. public override void Render()
  210. {
  211. //Render scene stuff
  212. base.Render();
  213. //If this is the end of level then show the overlays
  214. if (ended)
  215. {
  216. Texture2D overlayTexture = SpacewarGame.ContentManager.Load<Texture2D>(SpacewarGame.Settings.MediaPath + @"textures\In-game_score_overlay");
  217. SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque);
  218. SpriteBatch.Draw(overlayTexture, new Vector2(70, 200), null, Color.White);
  219. SpriteBatch.Draw(overlayTexture, new Vector2(900, 200), null, Color.White);
  220. SpriteBatch.End();
  221. }
  222. //HUD stuff
  223. Font.Begin();
  224. //If this is the end of level then show the scores
  225. if (ended)
  226. {
  227. Font.Draw(FontStyle.WeaponLarge, 100, 240, String.Format("{0} pts x $1,000", player1Score));
  228. Font.Draw(FontStyle.WeaponLarge, 220, 280, "=");
  229. Font.Draw(FontStyle.WeaponLarge, 180, 320, String.Format("{0:$##,##0}", player1Score * 1000));
  230. Font.Draw(FontStyle.WeaponLarge, 930, 240, String.Format("{0} pts x $1,000", player2Score));
  231. Font.Draw(FontStyle.WeaponLarge, 1050, 280, "=");
  232. Font.Draw(FontStyle.WeaponLarge, 1010, 320, String.Format("{0:$##,##0}", player2Score * 1000));
  233. }
  234. //Timer
  235. Font.Draw(FontStyle.GameCountDown, 592, 40, String.Format("{0:0}:{1:00}", (int)(levelTime / 60), levelTime % 60));
  236. //Player1/2 labels
  237. Font.Draw(FontStyle.GamePlayerNames, 50, 40, "1");
  238. Font.Draw(FontStyle.GamePlayerNames, 1110, 40, "2");
  239. //Weapon icons 01234 is player1 weapons, 56789 is player2 weapons
  240. Font.Draw(FontStyle.WeaponIcons, 50, 560, ((int)SpacewarGame.Players[0].ProjectileType));
  241. Font.Draw(FontStyle.WeaponIcons, 1090, 560, ((int)(SpacewarGame.Players[1].ProjectileType) + 5));
  242. //Score buttons
  243. Font.Draw(FontStyle.ScoreButtons, 60, 70, scoreLookup[SpacewarGame.Players[0].Score]);
  244. Font.Draw(FontStyle.ScoreButtons, 1140, 70, scoreLookup[SpacewarGame.Players[1].Score]);
  245. //Health
  246. //Fudge factor for BFG icon
  247. int xOffset;
  248. xOffset = (SpacewarGame.Players[0].ProjectileType == ProjectileType.BFG) ? 12 : 0;
  249. Font.Draw(FontStyle.HealthBar, 130 + xOffset, 625, SpacewarGame.Players[0].Health);
  250. xOffset = (SpacewarGame.Players[1].ProjectileType == ProjectileType.BFG) ? 16 : 0;
  251. Font.Draw(FontStyle.HealthBar, 1170 + xOffset, 625, SpacewarGame.Players[1].Health);
  252. //Scores
  253. Font.Draw(FontStyle.Score, 300, 15, player1Score);
  254. Font.Draw(FontStyle.Score, 940, 15, player2Score);
  255. Font.End();
  256. }
  257. protected override void handleCollisions(TimeSpan gameTime)
  258. {
  259. base.handleCollisions(gameTime);
  260. bool asteroidHitShip1 = false;
  261. bool asteroidHitShip2 = false;
  262. //Asteroids do 3 damage and bounce you
  263. foreach (Asteroid asteroid in asteroids)
  264. {
  265. if (!asteroid.Destroyed)
  266. {
  267. if (asteroid.Collide(ship1) && !ship1.Uncollidable)
  268. {
  269. asteroidHitShip1 = true;
  270. if (!ship1.Invulnerable)
  271. {
  272. float ship1Speed = ship1.Velocity.Length();
  273. float asteroidSpeed = asteroid.Velocity.Length();
  274. Vector3 tmp = ship1.Velocity;
  275. Vector3 vel = asteroid.Velocity;
  276. vel.Normalize();
  277. ship1.Velocity = vel * ship1Speed;
  278. tmp.Normalize();
  279. asteroid.Velocity = tmp * asteroidSpeed;
  280. HitPlayer1(gameTime, 1);
  281. ship1.Invulnerable = true;
  282. }
  283. }
  284. if (asteroid.Collide(ship2) && !ship2.Uncollidable)
  285. {
  286. asteroidHitShip2 = true;
  287. if (!ship2.Invulnerable)
  288. {
  289. float ship2Speed = ship2.Velocity.Length();
  290. float asteroidSpeed = asteroid.Velocity.Length();
  291. Vector3 tmp = ship2.Velocity;
  292. Vector3 vel = asteroid.Velocity;
  293. vel.Normalize();
  294. ship2.Velocity = vel * ship2Speed;
  295. tmp.Normalize();
  296. asteroid.Velocity = tmp * asteroidSpeed;
  297. HitPlayer2(gameTime, 1);
  298. ship2.Invulnerable = true;
  299. }
  300. }
  301. foreach (Projectile bullet in bullets)
  302. {
  303. if (bullet.Collide(asteroid))
  304. {
  305. particles.AddExplosion(asteroid.Position);
  306. asteroid.Delete = true;
  307. asteroid.Destroyed = true;
  308. bullet.DeleteProjectile();
  309. Sound.PlayCue(Sounds.Explosion);
  310. }
  311. }
  312. }
  313. }
  314. if (!asteroidHitShip1 && ship1.Invulnerable)
  315. {
  316. ship1.Invulnerable = false;
  317. }
  318. if (!asteroidHitShip2 && ship2.Invulnerable)
  319. {
  320. ship2.Invulnerable = false;
  321. }
  322. }
  323. public override void OnCreateDevice()
  324. {
  325. base.OnCreateDevice();
  326. foreach (Asteroid asteroid in asteroids)
  327. {
  328. asteroid.ShapeItem.OnCreateDevice();
  329. }
  330. foreach (Projectile bullet in bullets)
  331. {
  332. bullet.ShapeItem.OnCreateDevice();
  333. }
  334. particles.OnCreateDevice();
  335. }
  336. }
  337. }