RacingGameManager.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. //-----------------------------------------------------------------------------
  2. // RacingGameManager.cs
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7. using Microsoft.Xna.Framework;
  8. using Microsoft.Xna.Framework.Audio;
  9. using Microsoft.Xna.Framework.Content;
  10. using Microsoft.Xna.Framework.Graphics;
  11. using Microsoft.Xna.Framework.Input;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Threading;
  15. using RacingGame.GameLogic;
  16. using RacingGame.GameScreens;
  17. using RacingGame.Graphics;
  18. using RacingGame.Helpers;
  19. using RacingGame.Landscapes;
  20. using RacingGame.Sounds;
  21. using Model = RacingGame.Graphics.Model;
  22. using Texture = RacingGame.Graphics.Texture;
  23. using RacingGame.Properties;
  24. using RacingGame.Shaders;
  25. using System.Threading.Tasks;
  26. namespace RacingGame
  27. {
  28. /// <summary>
  29. /// This is the main entry class our game. Handles all game screens,
  30. /// which themself handle all the game logic.
  31. /// As you can see this class is very simple, which is really cool.
  32. /// </summary>
  33. public class RacingGameManager : BaseGame
  34. {
  35. /// <summary>
  36. /// Game screens stack. We can easily add and remove game screens
  37. /// and they follow the game logic automatically. Very cool.
  38. /// </summary>
  39. private static Stack<IGameScreen> gameScreens = new Stack<IGameScreen>();
  40. /// <summary>
  41. /// Player for the game, also allows us to control the car and contains
  42. /// all the required code for the car physics, chase camera and basic
  43. /// player values and the game time because this is the top class
  44. /// of many derived classes. Player, car and camera position is set
  45. /// when the game starts depending on the selected level.
  46. /// </summary>
  47. private static Player player = new Player(new Vector3(0, 0, 0));
  48. /// <summary>
  49. /// Car model and selection plate for the car selection screen.
  50. /// </summary>
  51. private static Model carModel = null,
  52. carSelectionPlate = null;
  53. /// <summary>
  54. /// Car textures we exchange for our car model.
  55. /// </summary>
  56. private static Texture[] carTextures = null;
  57. /// <summary>
  58. /// The player can select between the 3 cars: 0 (white), 1 (red) and
  59. /// 2 (yellow).
  60. /// </summary>
  61. public static int currentCarNumber = 0;
  62. /// <summary>
  63. /// The player can also select a car color, which will be used to
  64. /// recolor the car. Looks best for the first car (white).
  65. /// </summary>
  66. public static int currentCarColor;// Color carColor = Color.White;
  67. /// <summary>
  68. /// Helper texture for color selection
  69. /// </summary>
  70. public static Texture colorSelectionTexture = null;
  71. /// <summary>
  72. /// Material for brake tracks on the road.
  73. /// </summary>
  74. private static Material brakeTrackMaterial = null;
  75. /// <summary>
  76. /// Car colors for the car selection screen.
  77. /// </summary>
  78. public static List<Color> CarColors = new List<Color>(
  79. new Color[]
  80. {
  81. Color.White,
  82. Color.Yellow,
  83. Color.Blue,
  84. Color.Purple,
  85. Color.Red,
  86. Color.Green,
  87. Color.Teal,
  88. Color.Gray,
  89. Color.Chocolate,
  90. Color.MonoGameOrange,
  91. Color.SeaGreen,
  92. });
  93. /// <summary>
  94. /// Landscape we are currently using.
  95. /// </summary>
  96. private static Landscape landscape = null;
  97. /// <summary>
  98. /// Level we use for our track and landscape
  99. /// </summary>
  100. public enum Level
  101. {
  102. Beginner,
  103. Advanced,
  104. Expert,
  105. }
  106. /// <summary>
  107. /// Load level
  108. /// </summary>
  109. /// <param name="setNewLevel">Set new level</param>
  110. public static void LoadLevel(Level setNewLevel)
  111. {
  112. landscape.ReloadLevel(setNewLevel);
  113. }
  114. public static event EventHandler<EventArgs> LoadEvent;
  115. /// <summary>
  116. /// In menu
  117. /// </summary>
  118. /// <returns>Bool</returns>
  119. public static bool InMenu
  120. {
  121. get
  122. {
  123. return gameScreens.Count > 0 &&
  124. gameScreens.Peek().GetType() != typeof(GameScreen);
  125. }
  126. }
  127. /// <summary>
  128. /// In game?
  129. /// </summary>
  130. public static bool InGame
  131. {
  132. get
  133. {
  134. return gameScreens.Count > 0 &&
  135. gameScreens.Peek().GetType() == typeof(GameScreen);
  136. }
  137. }
  138. /// <summary>
  139. /// ShowMouseCursor
  140. /// </summary>
  141. /// <returns>Bool</returns>
  142. public static bool ShowMouseCursor
  143. {
  144. get
  145. {
  146. // Only if not in Game, not in splash screen!
  147. return gameScreens.Count > 0 &&
  148. gameScreens.Peek().GetType() != typeof(GameScreen) &&
  149. gameScreens.Peek().GetType() != typeof(SplashScreen) &&
  150. gameScreens.Peek().GetType() != typeof(LoadingScreen);
  151. }
  152. }
  153. /// <summary>
  154. /// In car selection screen
  155. /// </summary>
  156. /// <returns>Bool</returns>
  157. public static bool InCarSelectionScreen
  158. {
  159. get
  160. {
  161. return gameScreens.Count > 0 &&
  162. gameScreens.Peek().GetType() == typeof(CarSelection);
  163. }
  164. }
  165. /// <summary>
  166. /// Player for the game, also allows us to control the car and contains
  167. /// all the required code for the car physics, chase camera and basic
  168. /// player values and the game time because this is the top class
  169. /// of many derived classes.
  170. /// Easy access here with a static property in case we need the player
  171. /// somewhere in the game.
  172. /// </summary>
  173. /// <returns>Player</returns>
  174. public static Player Player
  175. {
  176. get
  177. {
  178. return player;
  179. }
  180. }
  181. /// <summary>
  182. /// Car model
  183. /// </summary>
  184. /// <returns>Model</returns>
  185. public static Model CarModel
  186. {
  187. get
  188. {
  189. return carModel;
  190. }
  191. }
  192. /// <summary>
  193. /// Car color
  194. /// </summary>
  195. /// <returns>Color</returns>
  196. public static Color CarColor
  197. {
  198. get
  199. {
  200. return CarColors[currentCarColor % CarColors.Count];
  201. }
  202. }
  203. /// <summary>
  204. /// Number of car colors
  205. /// </summary>
  206. /// <returns>Int</returns>
  207. public static int NumberOfCarColors
  208. {
  209. get
  210. {
  211. return CarColors.Count;
  212. }
  213. }
  214. /// <summary>
  215. /// Number of car texture types
  216. /// </summary>
  217. /// <returns>Int</returns>
  218. public static int NumberOfCarTextureTypes
  219. {
  220. get
  221. {
  222. return carTextures.Length;
  223. }
  224. }
  225. /// <summary>
  226. /// Car texture
  227. /// </summary>
  228. /// <param name="carNumber">Car number</param>
  229. /// <returns>Texture</returns>
  230. public static Texture CarTexture(int carNumber)
  231. {
  232. return carTextures[carNumber % carTextures.Length];
  233. }
  234. /// <summary>
  235. /// Brake track material
  236. /// </summary>
  237. /// <returns>Material</returns>
  238. public static Material BrakeTrackMaterial
  239. {
  240. get
  241. {
  242. return brakeTrackMaterial;
  243. }
  244. }
  245. /// <summary>
  246. /// Car selection plate
  247. /// </summary>
  248. /// <returns>Model</returns>
  249. public static Model CarSelectionPlate
  250. {
  251. get
  252. {
  253. return carSelectionPlate;
  254. }
  255. }
  256. /// <summary>
  257. /// Landscape we are currently using, used for several things (menu
  258. /// background, the game, some other classes outside the landscape class).
  259. /// </summary>
  260. /// <returns>Landscape</returns>
  261. public static Landscape Landscape
  262. {
  263. get
  264. {
  265. return landscape;
  266. }
  267. }
  268. /// <summary>
  269. /// The Task that will load most of the content for this game
  270. /// in the background, while the loading screen is shown.
  271. /// </summary>
  272. private static Task loadingTask;
  273. public static Task LoadingTask
  274. {
  275. get
  276. {
  277. return loadingTask;
  278. }
  279. set
  280. {
  281. loadingTask = value;
  282. }
  283. }
  284. public static bool ContentLoaded
  285. {
  286. get
  287. {
  288. return loadingTask?.IsCompleted == true;
  289. }
  290. }
  291. /// <summary>
  292. /// Create Racing game
  293. /// </summary>
  294. public RacingGameManager()
  295. : base("RacingGame")
  296. {
  297. Sound.Initialize();
  298. // Start playing the menu music
  299. //Sound.Play(Sound.Sounds.MenuMusic);
  300. // Create main menu at our main entry point
  301. gameScreens.Push(new MainMenu());
  302. // But start with splash screen, if user clicks or presses Start,
  303. // we are back in the main menu.
  304. gameScreens.Push(new SplashScreen());
  305. //We want to initially show the loading screen while things start.
  306. gameScreens.Push(new LoadingScreen());
  307. }
  308. /// <summary>
  309. /// Create Racing game for unit tests, not used for anything else.
  310. /// </summary>
  311. public RacingGameManager(string unitTestName)
  312. : base(unitTestName)
  313. {
  314. // Don't add game screens here
  315. }
  316. /// <summary>
  317. /// Load car stuff
  318. /// </summary>
  319. protected override void Initialize()
  320. {
  321. base.Initialize();
  322. }
  323. /// <summary>
  324. /// Initializes and loads some content, previously referred to as the
  325. /// "car stuff".
  326. /// </summary>
  327. public static void LoadResources()
  328. {
  329. LoadEvent("Models...", null);
  330. // Load models
  331. carModel = new Model("Car");
  332. carSelectionPlate = new Model("CarSelectionPlate");
  333. LoadEvent("Landscape...", null);
  334. // Load landscape
  335. landscape = new Landscape(Level.Beginner);
  336. LoadEvent("Textures...", null);
  337. // Load textures, first one is grabbed from the imported one through
  338. // the car.x model, the other two are loaded seperately.
  339. carTextures = new Texture[3];
  340. carTextures[0] = new Texture("RacerCar");
  341. carTextures[1] = new Texture("RacerCar2");
  342. carTextures[2] = new Texture("RacerCar3");
  343. colorSelectionTexture = new Texture("ColorSelection");
  344. brakeTrackMaterial = new Material("Track");
  345. LoadEvent("All systems go!", null);
  346. Task.Delay(1000).Wait();
  347. }
  348. /// <summary>
  349. /// Add game screen
  350. /// </summary>
  351. /// <param name="gameScreen">Game screen</param>
  352. public static void AddGameScreen(IGameScreen gameScreen)
  353. {
  354. // Play sound for screen click
  355. Sound.Play(Sound.Sounds.ScreenClick);
  356. // Add the game screen
  357. gameScreens.Push(gameScreen);
  358. }
  359. /// <summary>
  360. /// Update
  361. /// </summary>
  362. protected override void Update(GameTime gameTime)
  363. {
  364. // Update game engine
  365. base.Update(gameTime);
  366. if (gameScreens.Count > 0)
  367. {
  368. if (gameScreens.Peek().GetType() != typeof(LoadingScreen))
  369. {
  370. // Update player and game logic
  371. player.Update();
  372. }
  373. //Update the game screen
  374. gameScreens.Peek().Update(gameTime);
  375. }
  376. }
  377. /// <summary>
  378. /// Render
  379. /// </summary>
  380. protected override void Render()
  381. {
  382. // No more game screens?
  383. if (gameScreens.Count == 0)
  384. {
  385. // Before quiting, stop music and play crash sound :)
  386. Sound.PlayCrashSound(true);
  387. Sound.StopMusic();
  388. // Then quit
  389. Exit();
  390. return;
  391. }
  392. // Handle current screen
  393. if (gameScreens.Peek().Render())
  394. {
  395. // If this was the options screen and the resolution has changed,
  396. // apply the changes
  397. if (gameScreens.Peek().GetType() == typeof(Options) &&
  398. (BaseGame.Width != GameSettings.Default.ResolutionWidth ||
  399. BaseGame.Height != GameSettings.Default.ResolutionHeight ||
  400. BaseGame.Fullscreen != GameSettings.Default.Fullscreen))
  401. {
  402. BaseGame.ApplyResolutionChange();
  403. }
  404. // Play sound for screen back
  405. Sound.Play(Sound.Sounds.ScreenBack);
  406. gameScreens.Pop();
  407. }
  408. }
  409. /// <summary>
  410. /// Post user interface rendering, in case we need it.
  411. /// Used for rendering the car selection 3d stuff after the UI.
  412. /// </summary>
  413. protected override void PostUIRender()
  414. {
  415. // Enable depth buffer again
  416. BaseGame.Device.DepthStencilState = DepthStencilState.Default;
  417. // Currently in car selection screen?
  418. if (gameScreens.Count > 0 &&
  419. gameScreens.Peek().GetType() == typeof(CarSelection))
  420. ((CarSelection)gameScreens.Peek()).PostUIRender();
  421. // Do menu shader after everything
  422. if (BaseGame.UsePostScreenShaders && PostScreenMenu.Started)
  423. UI.PostScreenMenuShader.Show();
  424. }
  425. }
  426. }