using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; namespace RectangleCollision { /// /// This is the main type for your game /// public class RectangleCollisionGame : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; // The images we will draw Texture2D personTexture; Texture2D blockTexture; Texture2D StartScreen; Texture2D GameOver; Texture2D mMessageBox; Texture2D Pause; Color mPauseColor = Color.MediumSlateBlue; // The images will be drawn with this SpriteBatch SpriteBatch spriteBatch; SpriteBatch spriteBatchIntro; SpriteBatch spriteBatchPaused; SpriteBatch spriteBatchEnd; // Person public Vector2 personPosition = new Vector2(600, 600); const int PersonMoveSpeed = 5; // Blocks List blockPositions = new List(); public Vector2 IntroStartScreen = new Vector2(200, 0); float BlockSpawnProbability = 0.07f; const int BlockFallSpeed = 3; private SpriteFont mText; private SpriteFont wText; private enum GameState { Intro, Playing, Paused, GameOver } private GameState mCurrentState = GameState.Intro; Random random = new Random(); // For when a collision is detected bool personHit = false; // The sub-rectangle of the drawable area which should be visible on all TVs Rectangle safeBounds; // Percentage of the screen on every side is the safe area const float SafeAreaPortion = 0.05f; public RectangleCollisionGame() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; graphics.PreferredBackBufferWidth = 1024; // set this value to the desired width of your window graphics.PreferredBackBufferHeight = 800; // set this value to the desired height of your window graphics.ApplyChanges(); } /// /// Allows the game to perform any initialization it needs to before starting to /// run. This is where it can query for any required services and load any /// non-graphic related content. Calling base.Initialize will enumerate through /// any components and initialize them as well. /// protected override void Initialize() { base.Initialize(); mCurrentState = GameState.Intro; blockTexture.GraphicsDevice.Reset(); if (mCurrentState == GameState.Intro) { mText = Content.Load("FYF"); wText = Content.Load("FYF2"); } // Calculate safe bounds based on current resolution Viewport viewport = graphics.GraphicsDevice.Viewport; safeBounds = new Rectangle( (int)(viewport.Width * SafeAreaPortion), (int)(viewport.Height * SafeAreaPortion), (int)(viewport.Width * (1 - 2 * SafeAreaPortion)), (int)(viewport.Height * (1 - 2 * SafeAreaPortion))); } /// /// Load your graphics content. /// protected override void LoadContent() { // Load textures StartScreen = Content.Load("StartScreen"); blockTexture = Content.Load("CowMan"); personTexture = Content.Load("Main character"); GameOver = Content.Load("GameOver"); mMessageBox = Content.Load("MessageBox"); Pause = Content.Load("Pause"); // Create a sprite batch to draw those textures spriteBatch = new SpriteBatch(graphics.GraphicsDevice); spriteBatchIntro = new SpriteBatch(graphics.GraphicsDevice); spriteBatchPaused = new SpriteBatch(graphics.GraphicsDevice); spriteBatchEnd = new SpriteBatch(graphics.GraphicsDevice); } /// /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input and playing audio. /// /// Provides a snapshot of timing values. protected override void Update(GameTime gameTime) { // Get input KeyboardState keyboard = Keyboard.GetState(); GamePadState gamePad = GamePad.GetState(PlayerIndex.One); // Allows the game to exit if (mCurrentState == GameState.Playing) { if (gamePad.Buttons.Back == ButtonState.Pressed || keyboard.IsKeyDown(Keys.Escape)) { this.Exit(); } // Move the player left and right with arrow keys or d-pad if (keyboard.IsKeyDown(Keys.Left) || gamePad.DPad.Left == ButtonState.Pressed) { personPosition.X -= PersonMoveSpeed; } if (keyboard.IsKeyDown(Keys.Right) || gamePad.DPad.Right == ButtonState.Pressed) { personPosition.X += PersonMoveSpeed; } if (keyboard.IsKeyDown(Keys.Up)) { personPosition.Y -= PersonMoveSpeed; } if (keyboard.IsKeyDown(Keys.Down)) { personPosition.Y += PersonMoveSpeed; } // Prevent the person from moving off of the screen personPosition.X = MathHelper.Clamp(personPosition.X, safeBounds.Left, safeBounds.Right - personTexture.Width); // Spawn new falling blocks if (random.NextDouble() < BlockSpawnProbability) { float x = (float)random.NextDouble() * (Window.ClientBounds.Width - blockTexture.Width); blockPositions.Add(new Vector2(x, -blockTexture.Height)); } // Get the bounding rectangle of the person Rectangle personRectangle = new Rectangle((int)personPosition.X, (int)personPosition.Y, personTexture.Width, personTexture.Height); // Update each block personHit = false; for (int i = 0; i < blockPositions.Count; i++) { // Animate this block falling blockPositions[i] = new Vector2(blockPositions[i].X, blockPositions[i].Y + BlockFallSpeed); Rectangle blockRectangle = new Rectangle((int)blockPositions[i].X, (int)blockPositions[i].Y, blockTexture.Width, blockTexture.Height); // Check collision with person if (personRectangle.Intersects(blockRectangle)) personHit = true; // Remove this block if it have fallen off the screen if (blockPositions[i].Y > Window.ClientBounds.Height) { blockPositions.RemoveAt(i); // When removing a block, the next block will have the same index // as the current block. Decrement i to prevent skipping a block. i--; } } } base.Update(gameTime); if (keyboard.IsKeyDown(Keys.Space) == true) { if (mCurrentState == GameState.Intro) { mCurrentState = GameState.Playing; } else if (mCurrentState == GameState.GameOver) { Initialize(); mCurrentState = GameState.Intro; } } if (keyboard.IsKeyDown(Keys.P)) { if (mCurrentState == GameState.Playing) { blockTexture.GraphicsDevice.Reset(); mCurrentState = GameState.Paused; } } if (keyboard.IsKeyDown(Keys.Space)) { if (mCurrentState == GameState.Paused) { mCurrentState = GameState.Playing; } } if (keyboard.IsKeyDown(Keys.Escape)) { if (mCurrentState == GameState.Intro) { this.Exit(); } } } /// /// This is called when the game should draw itself. /// /// Provides a snapshot of timing values. protected override void Draw(GameTime gameTime) { GraphicsDevice device = graphics.GraphicsDevice; // Change the background to red when the person was hit by a block if (mCurrentState == GameState.Intro) { spriteBatchIntro.Begin(); spriteBatchIntro.Draw(StartScreen, IntroStartScreen, Color.White); spriteBatchIntro.DrawString(mText, "Press 'Space' to start the Infection!", new Vector2(150, 700), Color.White); spriteBatchIntro.End(); } if (mCurrentState == GameState.GameOver) { spriteBatchEnd.Begin(); spriteBatchEnd.Draw(GameOver, new Vector2(0, 0), Color.White); spriteBatchEnd.DrawString(mText, "HAHAHAHA you lost", new Vector2(150, 700), Color.White); device.Clear(Color.Black); spriteBatchEnd.End(); } if (mCurrentState == GameState.Paused) { spriteBatchPaused.Begin(); spriteBatchPaused.Draw(Pause, new Vector2(200, 300), Color.White); spriteBatchPaused.End(); } if (mCurrentState == GameState.Playing) { spriteBatch.Begin(); if (personHit) { mCurrentState = GameState.GameOver; } else { device.Clear(Color.CornflowerBlue); } // Draw person spriteBatch.Draw(personTexture, personPosition, Color.White); // Draw blocks foreach (Vector2 blockPosition in blockPositions) spriteBatch.Draw(blockTexture, blockPosition, Color.White); spriteBatch.End(); } base.Draw(gameTime); } } }