Game1.cs 7.2 KB

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