Engine.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. using System;
  2. using System.IO;
  3. using Microsoft.Xna.Framework;
  4. using Microsoft.Xna.Framework.GamerServices;
  5. using Microsoft.Xna.Framework.Graphics;
  6. using Microsoft.Xna.Framework.Input;
  7. #if !LINUX
  8. using MonoMac.Foundation;
  9. #endif
  10. namespace Tetris
  11. {
  12. /// <summary>
  13. /// This is the main type for your game
  14. /// </summary>
  15. public class Engine : Microsoft.Xna.Framework.Game
  16. {
  17. // Graphics
  18. GraphicsDeviceManager graphics;
  19. SpriteBatch spriteBatch;
  20. Texture2D tetrisBackground, tetrisTextures;
  21. SpriteFont gameFont;
  22. readonly Rectangle[] blockRectangles = new Rectangle[7];
  23. // Game
  24. Board board;
  25. Score score;
  26. bool pause = false;
  27. // Input
  28. KeyboardState oldKeyboardState = Keyboard.GetState ();
  29. public Engine ()
  30. {
  31. graphics = new GraphicsDeviceManager (this);
  32. #if !LINUX
  33. Content.RootDirectory = Path.Combine (NSBundle.MainBundle.ResourcePath, "Content");
  34. #else
  35. Content.RootDirectory = "Content";
  36. #endif
  37. // Create sprite rectangles for each figure in texture file
  38. // O figure
  39. blockRectangles [0] = new Rectangle (312, 0, 24, 24);
  40. // I figure
  41. blockRectangles [1] = new Rectangle (0, 24, 24, 24);
  42. // J figure
  43. blockRectangles [2] = new Rectangle (120, 0, 24, 24);
  44. // L figure
  45. blockRectangles [3] = new Rectangle (216, 24, 24, 24);
  46. // S figure
  47. blockRectangles [4] = new Rectangle (48, 96, 24, 24);
  48. // Z figure
  49. blockRectangles [5] = new Rectangle (240, 72, 24, 24);
  50. // T figure
  51. blockRectangles [6] = new Rectangle (144, 96, 24, 24);
  52. }
  53. /// <summary>
  54. /// Allows the game to perform any initialization it needs to before starting to run.
  55. /// This is where it can query for any required services and load any non-graphic
  56. /// related content. Calling base.Initialize will enumerate through any components
  57. /// and initialize them as well.
  58. /// </summary>
  59. protected override void Initialize ()
  60. {
  61. Window.Title = "MonoGame XNA Tetris 2D";
  62. graphics.PreferredBackBufferHeight = 600;
  63. graphics.PreferredBackBufferWidth = 800;
  64. this.TargetElapsedTime = TimeSpan.FromSeconds (1.0f / 10.0f);
  65. // Try to open file if it exists, otherwise create it
  66. using (FileStream fileStream = File.Open ("record.dat", FileMode.OpenOrCreate)) {
  67. fileStream.Close ();
  68. }
  69. base.Initialize ();
  70. }
  71. /// <summary>
  72. /// LoadContent will be called once per game and is the place to load
  73. /// all of your content.
  74. /// </summary>
  75. protected override void LoadContent ()
  76. {
  77. // Create a new SpriteBatch, which can be used to draw textures.
  78. spriteBatch = new SpriteBatch (GraphicsDevice);
  79. // Add the SpriteBatch service
  80. Services.AddService (typeof(SpriteBatch), spriteBatch);
  81. //Load 2D textures
  82. tetrisBackground = Content.Load<Texture2D> ("background");
  83. tetrisTextures = Content.Load<Texture2D> ("tetris");
  84. // Load game font
  85. //gameFont = Content.Load<SpriteFont> ("font");
  86. gameFont = Content.Load<SpriteFont> ("Arial");
  87. // Create game field
  88. board = new Board (this, ref tetrisTextures, blockRectangles);
  89. board.Initialize ();
  90. Components.Add (board);
  91. // Save player's score and game level
  92. score = new Score (this, gameFont);
  93. score.Initialize ();
  94. Components.Add (score);
  95. // Load game record
  96. using (StreamReader streamReader = File.OpenText ("record.dat")) {
  97. string player = null;
  98. if ((player = streamReader.ReadLine ()) != null)
  99. score.RecordPlayer = player;
  100. int record = 0;
  101. if ((record = Convert.ToInt32 (streamReader.ReadLine ())) != 0)
  102. score.RecordScore = record;
  103. }
  104. }
  105. /// <summary>
  106. /// Allows the game to run logic such as updating the world,
  107. /// checking for collisions, gathering input, and playing audio.
  108. /// </summary>
  109. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  110. protected override void Update (GameTime gameTime)
  111. {
  112. // Allows the game to exit
  113. KeyboardState keyboardState = Keyboard.GetState ();
  114. if (keyboardState.IsKeyDown (Keys.Escape))
  115. this.Exit ();
  116. // Check pause
  117. bool pauseKey = (oldKeyboardState.IsKeyDown (Keys.P) && (keyboardState.IsKeyUp (Keys.P)));
  118. oldKeyboardState = keyboardState;
  119. if (pauseKey)
  120. pause = !pause;
  121. if (!pause) {
  122. // Find dynamic figure position
  123. board.FindDynamicFigure ();
  124. // Increase player score
  125. int lines = board.DestroyLines ();
  126. if (lines > 0) {
  127. score.Value += (int)((5.0f / 2.0f) * lines * (lines + 3));
  128. board.Speed += 0.005f;
  129. }
  130. score.Level = (int)(10 * board.Speed);
  131. // Create new shape in game
  132. if (!board.CreateNewFigure ())
  133. GameOver ();
  134. else {
  135. // If left key is pressed
  136. if (keyboardState.IsKeyDown (Keys.Left))
  137. board.MoveFigureLeft ();
  138. // If right key is pressed
  139. if (keyboardState.IsKeyDown (Keys.Right))
  140. board.MoveFigureRight ();
  141. // If down key is pressed
  142. if (keyboardState.IsKeyDown (Keys.Down))
  143. board.MoveFigureDown ();
  144. // Rotate figure
  145. if (keyboardState.IsKeyDown (Keys.Up) || keyboardState.IsKeyDown (Keys.Space))
  146. board.RotateFigure ();
  147. // Moving figure
  148. if (board.Movement >= 1) {
  149. board.Movement = 0;
  150. board.MoveFigureDown ();
  151. } else
  152. board.Movement += board.Speed;
  153. }
  154. }
  155. base.Update (gameTime);
  156. }
  157. private void GameOver ()
  158. {
  159. if (score.Value > score.RecordScore) {
  160. score.RecordScore = score.Value;
  161. pause = true;
  162. Record record = new Record ();
  163. //record.ShowDialog ();
  164. score.RecordPlayer = record.Player;
  165. using (StreamWriter writer = File.CreateText ("record.dat")) {
  166. writer.WriteLine (score.RecordPlayer);
  167. writer.WriteLine (score.RecordScore);
  168. }
  169. pause = false;
  170. }
  171. board.Initialize ();
  172. score.Initialize ();
  173. }
  174. /// <summary>
  175. /// This is called when the game should draw itself.
  176. /// </summary>
  177. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  178. protected override void Draw (GameTime gameTime)
  179. {
  180. spriteBatch.Begin ();
  181. spriteBatch.Draw (tetrisBackground, Vector2.Zero, Color.White);
  182. base.Draw (gameTime);
  183. spriteBatch.End ();
  184. }
  185. }
  186. }