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);
}
}
}