Game1.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // Game.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 Microsoft.Xna.Framework;
  13. using Microsoft.Xna.Framework.Audio;
  14. using Microsoft.Xna.Framework.Content;
  15. using Microsoft.Xna.Framework.Graphics;
  16. using Microsoft.Xna.Framework.Input;
  17. using Microsoft.Xna.Framework.Storage;
  18. #endregion
  19. namespace RectangleCollision
  20. {
  21. /// <summary>
  22. /// This is the main type for your game
  23. /// </summary>
  24. public class RectangleCollisionGame : Microsoft.Xna.Framework.Game
  25. {
  26. GraphicsDeviceManager graphics;
  27. // The images we will draw
  28. Texture2D personTexture;
  29. Texture2D blockTexture;
  30. // The images will be drawn with this SpriteBatch
  31. SpriteBatch spriteBatch;
  32. // Person
  33. Vector2 personPosition;
  34. const int PersonMoveSpeed = 5;
  35. // Blocks
  36. List<Vector2> blockPositions = new List<Vector2>();
  37. float BlockSpawnProbability = 0.01f;
  38. const int BlockFallSpeed = 2;
  39. Random random = new Random();
  40. // For when a collision is detected
  41. bool personHit = false;
  42. // The sub-rectangle of the drawable area which should be visible on all TVs
  43. Rectangle safeBounds;
  44. // Percentage of the screen on every side is the safe area
  45. const float SafeAreaPortion = 0.05f;
  46. public RectangleCollisionGame()
  47. {
  48. graphics = new GraphicsDeviceManager(this);
  49. Content.RootDirectory = "Content";
  50. }
  51. /// <summary>
  52. /// Allows the game to perform any initialization it needs to before starting to
  53. /// run. This is where it can query for any required services and load any
  54. /// non-graphic related content. Calling base.Initialize will enumerate through
  55. /// any components and initialize them as well.
  56. /// </summary>
  57. protected override void Initialize()
  58. {
  59. base.Initialize();
  60. // Calculate safe bounds based on current resolution
  61. Viewport viewport = graphics.GraphicsDevice.Viewport;
  62. safeBounds = new Rectangle(
  63. (int)(viewport.Width * SafeAreaPortion),
  64. (int)(viewport.Height * SafeAreaPortion),
  65. (int)(viewport.Width * (1 - 2 * SafeAreaPortion)),
  66. (int)(viewport.Height * (1 - 2 * SafeAreaPortion)));
  67. // Start the player in the center along the bottom of the screen
  68. personPosition.X = (safeBounds.Width - personTexture.Width) / 2;
  69. personPosition.Y = safeBounds.Height - personTexture.Height;
  70. }
  71. /// <summary>
  72. /// Load your graphics content.
  73. /// </summary>
  74. protected override void LoadContent()
  75. {
  76. // Load textures
  77. blockTexture = Content.Load<Texture2D>("Block");
  78. personTexture = Content.Load<Texture2D>("Person");
  79. // Create a sprite batch to draw those textures
  80. spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
  81. }
  82. /// <summary>
  83. /// Allows the game to run logic such as updating the world,
  84. /// checking for collisions, gathering input and playing audio.
  85. /// </summary>
  86. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  87. protected override void Update(GameTime gameTime)
  88. {
  89. // Get input
  90. KeyboardState keyboard = Keyboard.GetState();
  91. GamePadState gamePad = GamePad.GetState(PlayerIndex.One);
  92. // Allows the game to exit
  93. if (gamePad.Buttons.Back == ButtonState.Pressed ||
  94. keyboard.IsKeyDown(Keys.Escape))
  95. {
  96. this.Exit();
  97. }
  98. // Move the player left and right with arrow keys or d-pad
  99. if (keyboard.IsKeyDown(Keys.Left) ||
  100. gamePad.DPad.Left == ButtonState.Pressed)
  101. {
  102. personPosition.X -= PersonMoveSpeed;
  103. }
  104. if (keyboard.IsKeyDown(Keys.Right) ||
  105. gamePad.DPad.Right == ButtonState.Pressed)
  106. {
  107. personPosition.X += PersonMoveSpeed;
  108. }
  109. // Prevent the person from moving off of the screen
  110. personPosition.X = MathHelper.Clamp(personPosition.X,
  111. safeBounds.Left, safeBounds.Right - personTexture.Width);
  112. // Spawn new falling blocks
  113. if (random.NextDouble() < BlockSpawnProbability)
  114. {
  115. float x = (float)random.NextDouble() *
  116. (Window.ClientBounds.Width - blockTexture.Width);
  117. blockPositions.Add(new Vector2(x, -blockTexture.Height));
  118. }
  119. // Get the bounding rectangle of the person
  120. Rectangle personRectangle =
  121. new Rectangle((int)personPosition.X, (int)personPosition.Y,
  122. personTexture.Width, personTexture.Height);
  123. // Update each block
  124. personHit = false;
  125. for (int i = 0; i < blockPositions.Count; i++)
  126. {
  127. // Animate this block falling
  128. blockPositions[i] =
  129. new Vector2(blockPositions[i].X,
  130. blockPositions[i].Y + BlockFallSpeed);
  131. // Get the bounding rectangle of this block
  132. Rectangle blockRectangle =
  133. new Rectangle((int)blockPositions[i].X, (int)blockPositions[i].Y,
  134. blockTexture.Width, blockTexture.Height);
  135. // Check collision with person
  136. if (personRectangle.Intersects(blockRectangle))
  137. personHit = true;
  138. // Remove this block if it have fallen off the screen
  139. if (blockPositions[i].Y > Window.ClientBounds.Height)
  140. {
  141. blockPositions.RemoveAt(i);
  142. // When removing a block, the next block will have the same index
  143. // as the current block. Decrement i to prevent skipping a block.
  144. i--;
  145. }
  146. }
  147. base.Update(gameTime);
  148. }
  149. /// <summary>
  150. /// This is called when the game should draw itself.
  151. /// </summary>
  152. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  153. protected override void Draw(GameTime gameTime)
  154. {
  155. GraphicsDevice device = graphics.GraphicsDevice;
  156. // Change the background to red when the person was hit by a block
  157. if (personHit)
  158. {
  159. device.Clear(Color.Red);
  160. }
  161. else
  162. {
  163. device.Clear(Color.CornflowerBlue);
  164. }
  165. spriteBatch.Begin();
  166. // Draw person
  167. spriteBatch.Draw(personTexture, personPosition, Color.White);
  168. // Draw blocks
  169. foreach (Vector2 blockPosition in blockPositions)
  170. spriteBatch.Draw(blockTexture, blockPosition, Color.White);
  171. spriteBatch.End();
  172. base.Draw(gameTime);
  173. }
  174. }
  175. }