-
-
Save robbiewoods05/4661196fd2396db230d3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Xna.Framework; | |
using Microsoft.Xna.Framework.Graphics; | |
using System.Collections.Generic; | |
namespace Shooter | |
{ | |
public class Bullet : GameEntity | |
{ | |
// List of bullets | |
private static List<Bullet> bullets = new List<Bullet>(); | |
public static List<Bullet> Bullets { get { return bullets; } } | |
new public static Texture2D sprite; | |
static Bullet managerInstance; | |
new static int speed; | |
/// <summary> | |
/// Create a new bullet object | |
/// </summary> | |
/// <param name="x">X position</param> | |
/// <param name="y">Y position </param> | |
public Bullet(int x, int y, int speed) | |
{ | |
position.X = x; | |
position.Y = y; | |
Enemy.speed = speed; | |
} | |
/// <summary> | |
/// Returns a single instance of Bullet to allow function usage | |
/// </summary> | |
/// <returns>Returns a single bullet object</returns> | |
public static Bullet GetManagerInstance() | |
{ | |
if (managerInstance == null) | |
managerInstance = new Bullet(); | |
return managerInstance; | |
} | |
private Bullet() | |
{ | |
} | |
/// <summary> | |
/// Adds a bullet to the list of bullets | |
/// </summary> | |
/// <param name="b">Bullet object</param> | |
public static void Add(Bullet b) | |
{ | |
bullets.Add(b); | |
} | |
/// <summary> | |
/// Draws bullets to screen | |
/// </summary> | |
/// <param name="sb">Spritebatch object</param> | |
public override void Draw(SpriteBatch sb) | |
{ | |
for (int i = 0; i < bullets.Count; i++) | |
{ | |
sb.Draw(sprite, bullets[i].position, Color.White); | |
} | |
} | |
/// <summary> | |
/// Updates the bullets' positions | |
/// </summary> | |
/// <param name="gTime">Game timing object</param> | |
public override void Update(GameTime gTime) | |
{ | |
for (int i = 0; i < bullets.Count; i++) | |
{ | |
bullets[i].position.Y -= (float)(Enemy.speed * 0.016); | |
if (bullets[i].position.Y < 0) | |
bullets.RemoveAt(i); | |
} | |
} | |
/// <summary> | |
/// Remove bullet | |
/// </summary> | |
/// <param name="b">Index of bullet to remove</param> | |
public static void Remove(int b) | |
{ | |
// TODO: Use remove not remove at | |
bullets.RemoveAt(b); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Xna.Framework; | |
using Microsoft.Xna.Framework.Graphics; | |
using System; | |
using System.Collections.Generic; | |
namespace Shooter | |
{ | |
public class Enemy : GameEntity | |
{ | |
// Time left to next spawn, total respawn timer | |
new static float timer = 0.9f, maxTimer = 0.9f; | |
// Enemy image | |
new public static Texture2D sprite; | |
// Random number generator for X position | |
static readonly Random randomX = new Random(); | |
new static int speed = 140; | |
// List of enemies | |
private static List<Enemy> enemies = new List<Enemy>(); | |
public static List<Enemy> Enemies | |
{ | |
get { return enemies; } | |
} | |
static Enemy enemyManager; | |
public static Enemy GetManagerInstance() | |
{ | |
if (enemyManager == null) | |
enemyManager = new Enemy(); | |
return enemyManager; | |
} | |
/// <summary> | |
/// Creates a new enemy object | |
/// </summary> | |
/// <param name="x">X position</param> | |
/// <param name="y">Y position</param> | |
private Enemy(int x, int y) | |
{ | |
position.X = x; | |
position.Y = y; | |
} | |
private Enemy() | |
{ } | |
/// <summary> | |
/// Create and add an enemy to the list of enemies | |
/// </summary> | |
/// <param name="gt">Game timing object</param> | |
public static void CreateEnemy(GameTime gt) | |
{ | |
// Subtracts time between frames from respawn timer | |
timer -= (float)gt.ElapsedGameTime.TotalSeconds; | |
// Respawn timer is less than or equal to 0 and less than 5 enemies | |
if (timer <= 0 && enemies.Count < 5) | |
{ | |
// Reset respawn timer | |
timer = maxTimer; | |
// Get random number between (0, 0+ScreenWidth)= | |
int xPos = randomX.Next(0, 696); | |
// Add a new enemy at random X, 60px before 0 so enemies appear to fly in | |
enemies.Add(new Enemy(xPos, -60)); | |
} | |
} | |
/// <summary> | |
/// Moves the enemies | |
/// </summary> | |
/// <param name="gt">Game timing object</param> | |
public override void Update(GameTime gt) | |
{ | |
// Iterate through list of enemies | |
for (int i = 0; i < enemies.Count; i++) | |
{ | |
// Add enemy speed to Y position after multiplying speed by delta time in order to find distance travelled per frame | |
enemies[i].position.Y += (int)(speed * (float)gt.ElapsedGameTime.TotalSeconds); | |
// If enemy is off screen, remove it | |
if (enemies[i].position.Y > 660) | |
enemies.RemoveAt(i); | |
} | |
} | |
/// <summary> | |
/// Draws enemies to the screen | |
/// </summary> | |
/// <param name="sb">Spritebatch object</param> | |
public override void Draw (SpriteBatch sb) | |
{ | |
// Loop through enemies to draw them | |
for (int i = 0; i < enemies.Count; i++) | |
sb.Draw(sprite, enemies[i].position, Color.White); | |
} | |
/// <summary> | |
/// Removes a given enemy from the list of enemies | |
/// </summary> | |
/// <param name="en">Enemy to remove</param> | |
public static void Remove(Enemy en) | |
{ | |
enemies.Remove(en); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Xna.Framework; | |
using Microsoft.Xna.Framework.Audio; | |
using Microsoft.Xna.Framework.Graphics; | |
using Microsoft.Xna.Framework.Input; | |
using Microsoft.Xna.Framework.Media; | |
namespace Shooter | |
{ | |
/// <summary> | |
/// This is the main type for your game. | |
/// </summary> | |
public class Shooter : Game | |
{ | |
private GraphicsDeviceManager graphics; | |
private SpriteBatch spriteBatch; | |
private Player player; | |
private KeyboardState keyState; | |
private SoundEffect firesound; | |
#region Object Managers | |
private GameStateManager gameState; | |
private Bullet bulletManager; | |
private PlayerStateManager playerState; | |
private Enemy enemyManager; | |
#endregion | |
public Shooter() | |
{ | |
graphics = new GraphicsDeviceManager(this); | |
Content.RootDirectory = "Content"; | |
} | |
/// <summary> | |
/// 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. | |
/// </summary> | |
protected override void Initialize() | |
{ | |
// TODO: Add your initialization logic here | |
player = new Player(0, 0); | |
gameState = new GameStateManager("Menu"); | |
bulletManager = Bullet.GetManagerInstance(); | |
enemyManager = Enemy.GetManagerInstance(); | |
playerState = new PlayerStateManager("idle"); | |
base.Initialize(); | |
} | |
/// <summary> | |
/// LoadContent will be called once per game and is the place to load | |
/// all of your content. | |
/// </summary> | |
protected override void LoadContent() | |
{ | |
// Create a new SpriteBatch, which can be used to draw textures. | |
spriteBatch = new SpriteBatch(GraphicsDevice); | |
#region Menu Assets | |
Menu.BGMusic = Content.Load<Song>("bgmusic"); | |
Menu.MenuSound = Content.Load<SoundEffect>("menuChange"); | |
Menu.MSound = Menu.MenuSound.CreateInstance(); | |
Menu.Button = Content.Load<Texture2D>("button"); | |
Menu.MenuPanel = Content.Load<Texture2D>("menuPanel"); | |
Menu.MenuFont = Content.Load<SpriteFont>("menuFont"); | |
Menu.TitleFont = Content.Load<SpriteFont>("titleFont"); | |
Menu.Cursor = Content.Load<Texture2D>("mouse_cursor"); | |
Menu.CreateButton("Play"); | |
Menu.CreateButton("Options"); | |
Menu.CreateButton("Credits"); | |
Menu.CreateButton("Exit"); | |
#endregion | |
Bullet.sprite = Content.Load<Texture2D>("laserRed"); | |
#region Player Assets | |
player.PlayerSprite = Content.Load<Texture2D>("player"); | |
firesound = Content.Load<SoundEffect>("laser"); | |
player.FireSound = firesound.CreateInstance(); | |
// Debug stuff, probably should remove this | |
player.sFont = Content.Load<SpriteFont>("sFont"); | |
#endregion | |
Enemy.sprite = Content.Load<Texture2D>("enemyShip"); | |
Menu.PlayMusic(0.15f); | |
// TODO: use this.Content to load your game content here | |
} | |
/// <summary> | |
/// UnloadContent will be called once per game and is the place to unload | |
/// game-specific content. | |
/// </summary> | |
protected override void UnloadContent() | |
{ | |
// TODO: Unload any non ContentManager content here | |
} | |
/// <summary> | |
/// Allows the game to run logic such as updating the world, | |
/// checking for collisions, gathering input, and playing audio. | |
/// </summary> | |
/// <param name="gameTime">Provides a snapshot of timing values.</param> | |
protected override void Update(GameTime gameTime) | |
{ | |
keyState = Keyboard.GetState(); | |
// If we are not in credits or otions and the player presses escape | |
if ((gameState.CurrentState != "Options" || gameState.CurrentState != "Credits") && (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))) | |
Exit(); | |
// Do menu stuff | |
if (gameState.CurrentState == "Menu") | |
Menu.HandleInput(ref gameState, this); | |
// Do play stuff | |
if (gameState.CurrentState == "Play") | |
{ | |
player.HandleInput(keyState, gameTime, ref playerState); | |
bulletManager.Update(gameTime); | |
Enemy.CreateEnemy(gameTime); | |
enemyManager.Update(gameTime); | |
// Iterate through bullets, if bullet ccollides with enemy, remove both | |
for (int i = 0; i < Bullet.Bullets.Count; i++) | |
{ | |
for (int j = 0; j < Enemy.Enemies.Count; j++) | |
{ | |
if (Collisions.IsColliding((int)Bullet.Bullets[i].position.X, (int)Bullet.Bullets[i].position.Y, Bullet.sprite.Width, Bullet.sprite.Height, | |
(int)Enemy.Enemies[j].position.X, (int)Enemy.Enemies[j].position.Y, Enemy.sprite.Width, Enemy.sprite.Height)) | |
{ | |
Enemy.Remove(Enemy.Enemies[j]); | |
Bullet.Remove(i); | |
} | |
} | |
} | |
// Iterate through enemies, if enemy hits player remove enemy | |
for (int i = 0; i < Enemy.Enemies.Count; i++) | |
{ | |
if (Collisions.IsColliding((int)player.Position.X, (int)player.Position.Y, player.PlayerSprite.Width, player.PlayerSprite.Height, | |
(int)Enemy.Enemies[i].position.X, (int)Enemy.Enemies[i].position.Y, Enemy.sprite.Width, Enemy.sprite.Height)) | |
Enemy.Remove(Enemy.Enemies[i]); | |
} | |
} | |
if (gameState.CurrentState == "Credits") | |
Credits.HandleInput(ref gameState); | |
// TODO: Add your update logic here | |
base.Update(gameTime); | |
} | |
/// <summary> | |
/// This is called when the game should draw itself. | |
/// </summary> | |
/// <param name="gameTime">Provides a snapshot of timing values.</param> | |
protected override void Draw(GameTime gameTime) | |
{ | |
spriteBatch.Begin(); | |
GraphicsDevice.Clear(new Color(99, 63, 132)); | |
// Menu drawing stuff | |
if (gameState.CurrentState == gameState.States[0]) | |
Menu.Draw(spriteBatch); | |
// Game drawing stuff | |
if (gameState.CurrentState == gameState.States[2]) | |
{ | |
bulletManager.Draw(spriteBatch); | |
player.Draw(spriteBatch); | |
enemyManager.Draw(spriteBatch); | |
} | |
// Credits drawing stuff | |
if (gameState.CurrentState == "Credits") | |
Credits.Draw(spriteBatch); | |
// TODO: Add your drawing code here | |
spriteBatch.End(); | |
base.Draw(gameTime); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
namespace Shooter | |
{ | |
public class GameStateManager : StateManager | |
{ | |
private List<string> states = new List<string> { "Menu", "Options", "Play", "Credits" }; | |
public List<string> States { get { return states; } } | |
public GameStateManager(string state) : base(state) | |
{ | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Xna.Framework; | |
using Microsoft.Xna.Framework.Audio; | |
using Microsoft.Xna.Framework.Graphics; | |
using Microsoft.Xna.Framework.Input; | |
using Microsoft.Xna.Framework.Media; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace Shooter | |
{ | |
public static class Menu | |
{ | |
// Holds old state to facilitate checking for button releases so menu doesn't change too quickly | |
private static KeyboardState oldState = Keyboard.GetState(); | |
// Store allthe sounds for the menu | |
#region Sounds | |
private static Song bgMusic; | |
public static Song BGMusic { get { return bgMusic; } set { bgMusic = value; } } | |
private static SoundEffect menuSound; | |
public static SoundEffect MenuSound { get { return menuSound; } set { menuSound = value; } } | |
public static SoundEffectInstance MSound { get; set; } | |
#endregion | |
// Stores everything needed for buttons - Images, the currently selected button, the text on the buttons, the current button being drawn, total buttons, the menu panel as well as the font | |
#region Menu Buttons | |
private static Texture2D button; | |
public static Texture2D Button | |
{ | |
get { return button; } | |
set { button = value; } | |
} | |
private static string _selected; | |
private static string[] buttonText = new string[4]; | |
private static int drawIndex = 0, buttonCount = 0; | |
private static Texture2D menuPanel; | |
public static Texture2D MenuPanel; | |
private static SpriteFont menuFont; | |
public static SpriteFont MenuFont | |
{ | |
get { return menuFont; } | |
set { menuFont = value; } | |
} | |
#endregion | |
// Stores the image for the mouse cursor | |
private static Texture2D cursor; | |
public static Texture2D Cursor | |
{ | |
get { return cursor; } | |
set { cursor = value; } | |
} | |
// Stores the font for the title | |
private static SpriteFont titleFont; | |
public static SpriteFont TitleFont | |
{ | |
get { return titleFont; } | |
set { titleFont = value; } | |
} | |
/// <summary> | |
/// Creates a button on the menu | |
/// </summary> | |
/// <param name="buttonName">Name and text of the button</param> | |
public static void CreateButton(string buttonName) | |
{ | |
// If this is the first button, it will be selected by default | |
if (buttonText.Length == 0) | |
_selected = buttonName; | |
buttonText[buttonCount] = buttonName; | |
buttonCount++; | |
} | |
/// <summary> | |
/// Handles the intput for the menu | |
/// </summary> | |
/// <param name="state">State of the game</param> | |
/// <param name="game"></param> | |
public static void HandleInput(ref GameStateManager state, Game game) | |
{ | |
// The state of the keyboard after it last got state | |
KeyboardState newState = Keyboard.GetState(); | |
// Gets the state of the mouse | |
MouseState ms = Mouse.GetState(); | |
// If key is pressed and released | |
if (newState.IsKeyDown(Keys.Down)) | |
{ | |
if (!oldState.IsKeyDown(Keys.Down)) | |
{ | |
// If the index of the button to draw as selected is not the last, go to next button, if it is the last go to the first button | |
if (drawIndex != buttonText.Length - 1) | |
drawIndex++; | |
else | |
drawIndex = 0; | |
// Play the button switching sound | |
MSound.Play(); | |
_selected = buttonText[drawIndex]; | |
} | |
} | |
else if (newState.IsKeyDown(Keys.Up)) | |
{ | |
if (!oldState.IsKeyDown(Keys.Up)) | |
{ | |
// If not first button, go up, else go to last button | |
if (drawIndex != 0) | |
drawIndex--; | |
else | |
drawIndex = buttonText.Length - 1; | |
MSound.Play(); | |
_selected = buttonText[drawIndex]; | |
} | |
} | |
else if (newState.IsKeyDown(Keys.Enter)) | |
{ | |
// Perform the selected buttons action | |
if (_selected == "Play") | |
state.Set(_selected); | |
else if (_selected == "Exit") | |
game.Exit(); | |
else | |
state.Push(_selected); | |
MSound.Play(); | |
} | |
// If the mouse is inside the button, it will be colliding. If LMB is clicked, perform button's action | |
if (Collisions.IsColliding(ms.X, ms.Y, 0, 0, 305, 205, button.Width, button.Height)) | |
{ | |
_selected = "Play"; | |
if (ms.LeftButton == ButtonState.Pressed) | |
state.Set("Play"); | |
} | |
else if (Collisions.IsColliding(ms.X, ms.Y, 0, 0, 365, 258, button.Width, button.Height)) | |
{ | |
_selected = "Options"; | |
if (ms.LeftButton == ButtonState.Pressed) | |
state.Push("Options"); | |
} | |
else if (Collisions.IsColliding(ms.X, ms.Y, 0, 0, 425, 311, button.Width, button.Height)) | |
{ | |
_selected = "Credits"; | |
if (ms.LeftButton == ButtonState.Pressed) | |
state.Push("Credits"); | |
} | |
else if (Collisions.IsColliding(ms.X, ms.Y, 0, 0, 485, 364, button.Width, button.Height)) | |
{ | |
if (ms.LeftButton == ButtonState.Pressed) | |
game.Exit(); | |
} | |
// Set old state to the latest state when done | |
oldState = newState; | |
} | |
/// <summary> | |
/// Draw the menu to the screen | |
/// </summary> | |
/// <param name="spriteBatch">Spritebatch object</param> | |
public static void Draw(SpriteBatch spriteBatch) | |
{ | |
// Draw the title to screen | |
spriteBatch.DrawString(titleFont, "Star Shooter", new Vector2(20, 20), Color.White); | |
// Start X & Y positons of buttons, move word left if it's long | |
int x = 365, y = 220, xOffset; | |
// Colour to draw the button text in | |
Color colour; | |
// TODO: Get rid of this | |
//spriteBatch.Draw(menuPanel, new Vector2(80, 0), null, Color.White, 2f, Vector2.Zero, 0f, SpriteEffects.None, 0f); | |
// Loop through all buttons | |
foreach (string b in buttonText) | |
{ | |
// If the button is selected, draw its text in black | |
colour = (_selected == b) ? Color.Black : Color.Gray; | |
// If it's a longer word, distance to move left by | |
xOffset = (b == "Options" || b == "Credits") ? 5 : -10; | |
// Draw button image and button text | |
spriteBatch.Draw(button, new Vector2(x - 60, y - 15), null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); | |
spriteBatch.DrawString(menuFont, b, new Vector2(x - xOffset, y), colour); | |
// Move to Y position of next button | |
y += 53; | |
} | |
// Draw mouse cursor image to location of cursor | |
MouseState ms = Mouse.GetState(); | |
spriteBatch.Draw(cursor, new Vector2(ms.X, ms.Y), Color.White); | |
} | |
/// <summary> | |
/// Play the menu music | |
/// </summary> | |
/// <param name="vol">Volume</param> | |
public static void PlayMusic(float vol) | |
{ | |
MediaPlayer.IsRepeating = true; | |
MediaPlayer.Volume = vol; | |
MediaPlayer.Play(bgMusic); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace Shooter | |
{ | |
public class PlayerStateManager : StateManager | |
{ | |
public string[] states = { "firing", "idle" }; | |
public PlayerStateManager(string state):base(state) | |
{ | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
namespace Shooter | |
{ | |
public class StateManager | |
{ | |
Stack<string> states = new Stack<string>(); | |
public string CurrentState { get { return states.Peek(); } } | |
/// <summary> | |
/// Create a new state manager | |
/// </summary> | |
/// <param name="state">Default state</param> | |
public StateManager(string state) | |
{ | |
states.Push(state); | |
} | |
/// <summary> | |
/// Return to last state | |
/// </summary> | |
public virtual void Pop() | |
{ | |
states.Pop(); | |
} | |
/// <summary> | |
/// Push the given state onto the top of the state stack. | |
/// </summary> | |
/// <param name="state">State to push on</param> | |
public virtual void Push(string state) | |
{ | |
states.Push(state); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment