Skip to content

Instantly share code, notes, and snippets.

@11
Created September 10, 2018 04:51
Show Gist options
  • Save 11/70e14ade29919ebef267e1b3b7a52193 to your computer and use it in GitHub Desktop.
Save 11/70e14ade29919ebef267e1b3b7a52193 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace SpaceInvadersRecurseCenter.src
{
public class Alien: Entity{
private bool dead;
public bool Dead {
get { return dead; }
}
public Alien(int x, int y, int width, int height, Texture2D texture) : base(x, y, width, height) {
this.texture = texture;
dead = false;
}
public override void Draw(SpriteBatch spriteBatch){
// if the alien has not been hit by a bullet
if (!dead){
spriteBatch.Draw(this.texture, new Rectangle(x, y, width, height), Color.White);
}
}
public void UpdateLeft(int speed){
this.x -= speed;
}
public void UpdateRight(int speed) {
this.x += speed;
}
public void MoveDown() {
this.y += 4;
}
}
}
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpaceInvadersRecurseCenter.src
{
public class AlienSwarm{
// width and height of the matrix
private int height;
private int width;
// the actual matrix of aliens
private Alien[,] alienSwarm;
// local variables that will keep track of the left-most and right-most alien every frame
private int? rightMostAlien;
private int? leftrMostAlien;
// bool that keeps track of the direction the swarm is moving
private bool isMovingLeft;
// Counter that updates the speed of the swarm
// every 5 collisions with a wall increases the speed by 1
// the top speed of the swarm is 5
private int speedCounter;
// Speed of the swarm moving left and right
private int swarmSpeed;
public AlienSwarm(int width, int height) {
//sets the width and height
this.width = width;
this.height = height;
// Set the starting direction of the alien swarm to the right
this.isMovingLeft = false;
// default speed of moving left and right is 1
this.swarmSpeed= 1;
this.speedCounter = 0;
// creates grie of aliens and places them in the correct position
this.alienSwarm = InitAliens();
}
// InitAliens creates a matrix of aliens that will then be rendered on sceren
private Alien[,] InitAliens() {
Alien[,] alienSwarm = new Alien[width, height];
for (int i = 0; i < this.width; i++) {
for (int j = 0; j < this.height; j++) {
// depending on the row that we are adding aliens to, we change the texture of the aliens
// The aliens are numbered out of order because I wanted to make the lineup of aliens look faithful to the original game
switch (j) {
case 0:
alienSwarm[i, j] =
new Alien(i * 40, j * 30, 20, 20, Main.content.Load<Texture2D>("alien5"));
break;
case 1:
alienSwarm[i, j] =
new Alien(i * 40, j * 30, 20, 20, Main.content.Load<Texture2D>("alien1"));
break;
case 2:
alienSwarm[i, j] =
new Alien(i * 40, j * 30, 20, 20, Main.content.Load<Texture2D>("alien3"));
break;
case 3:
alienSwarm[i, j] =
new Alien(i * 40, j * 30, 20, 20, Main.content.Load<Texture2D>("alien4"));
break;
case 4:
alienSwarm[i, j] =
new Alien(i * 40, j * 30, 20, 20, Main.content.Load<Texture2D>("alien2"));
break;
}
}
}
return alienSwarm;
}
public void Draw(SpriteBatch spriteBatch){
// iterate over each enemy and render them
for (int i = 0; i < this.width; i++){
for (int j = 0; j < this.height; j++){
alienSwarm[i, j].Draw(spriteBatch);
}
}
}
public void Update(GameTime gameTime) {
// Calculates the left and right most aliens in the swarm of aliens
// this is done so the game knows when the change the swarm's direction when it hits the edge of the screen
FindLeftAndRightMostAliens();
// After finding the left and rightmost aliens, determine if the swarm should change directions
UpdateSwarmDirection();
// Update the speed of the swarm every 5 collisions with either wall
if (speedCounter >= 5 && swarmSpeed < 5){
speedCounter = 0;
this.swarmSpeed++;
}
// actually move the enemies on screen
for (int i = 0; i < this.width; i++){
for (int j = 0; j < this.height; j++){
if (this.isMovingLeft)
alienSwarm[i, j].UpdateLeft(swarmSpeed);
else
alienSwarm[i, j].UpdateRight(swarmSpeed);
}
}
}
// move the entire swarm closer to the player
private void MoveDown(){
for (int i = 0; i < this.width; i++){
for (int j = 0; j < this.height; j++){
alienSwarm[i, j].MoveDown();
}
}
}
private void UpdateSwarmDirection() {
// helps us determine which direction the alien swarm should move
// this determines when the aliens should move closer to the player
if (leftrMostAlien <= 0){
this.isMovingLeft = false;
this.MoveDown();
this.speedCounter++;
}
else if (rightMostAlien >= Main.graphics.PreferredBackBufferWidth){
this.isMovingLeft = true;
this.MoveDown();
this.speedCounter++;
}
}
private void FindLeftAndRightMostAliens() {
int? lowX = null;
int? largeX = null;
// find left-most and right-most enemy left in the grid
// this will determine when the enemies will flip directions
for (int i = 0; i < this.width; i++)
{
for (int j = 0; j < this.height; j++)
{
if (lowX == null && alienSwarm[i, j].Dead == false)
lowX = alienSwarm[i, j].X;
if (largeX == null && alienSwarm[i, j].Dead == false)
largeX = alienSwarm[i, j].X;
if (largeX != null && alienSwarm[i, j].Dead == false && alienSwarm[i, j].X < lowX)
lowX = alienSwarm[i, j].X;
if (largeX != null && alienSwarm[i, j].Dead == false && alienSwarm[i, j].X > largeX)
largeX = alienSwarm[i, j].X;
}
}
// if either lowX or largeX is null, the game.
// this is because of either of these values are null, there are no more enemies left in the grid
if (lowX == null || largeX == null){
// all the enemies are dead and the game is over
}
// otherwise assign leftMostAlien and rightMostAlien to the X value of either alien.
else{
this.leftrMostAlien = lowX;
this.rightMostAlien = largeX + 20;
}
}
}
}
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpaceInvadersRecurseCenter.src
{
// Used as a base class for all game objects
public abstract class Entity{
protected int x;
protected int y;
protected int width;
protected int height;
protected Texture2D texture;
public int X {
get { return this.x; }
set { this.x = value; }
}
public int Y{
get { return this.y; }
set { this.y = value; }
}
public Entity(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public Entity(int x, int y, int width, int height, Texture2D texture) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.texture = texture;
}
public virtual void Update(GameTime gameTime) { }
public abstract void Draw(SpriteBatch spriteBatch);
}
}
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpaceInvadersRecurseCenter.src
{
public class GameStage
{
private Player player;
private AlienSwarm alienSwarm;
public void Init() {
player = new Player();
alienSwarm = new AlienSwarm(11, 5); // 11 by 5 grid of enemies
}
public void Draw(SpriteBatch spriteBatch) {
spriteBatch.Begin();
player.Draw(spriteBatch);
alienSwarm.Draw(spriteBatch);
spriteBatch.End();
}
public void Update(GameTime gameTime) {
player.Update(gameTime);
alienSwarm.Update(gameTime);
}
}
}
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using SpaceInvadersRecurseCenter.src;
namespace SpaceInvadersRecurseCenter{
public class Main : Game{
// Used to adjust screen settings and grab viewport information
public static GraphicsDeviceManager graphics;
// Used to load assets into the game
public static ContentManager content;
// Game Stage objects
private SpriteBatch spriteBatch;
private GameStage gameStage;
public Main(){
graphics = new GraphicsDeviceManager(this);
// Setting the screen ratio to standard defition -- 480p
graphics.PreferredBackBufferWidth = 640;
graphics.PreferredBackBufferHeight = 480;
// Setting the directory to read pictures to be "Content"
Content.RootDirectory = "Content";
content = Content;
}
protected override void Initialize(){ base.Initialize(); }
protected override void LoadContent(){
// Object used to render sprites
// Initializing here to allow to be reused for any game state
spriteBatch = new SpriteBatch(GraphicsDevice);
// Class that contains all the game logic
gameStage = new GameStage();
gameStage.Init(); // Initalizing all the objects in that class
}
protected override void UnloadContent(){}
protected override void Update(GameTime gameTime){
// if the player pressed <ESC>, quit th game
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
// Update the GameStage every frame
gameStage.Update(gameTime);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime){
// Clear the render buffer with the color black
GraphicsDevice.Clear(Color.Black);
// Render to the GameStage every frame
gameStage.Draw(spriteBatch);
base.Draw(gameTime);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace SpaceInvadersRecurseCenter.src
{
public class Player : Entity{
// Starting coordinate constants
private static int START_X = Main.graphics.PreferredBackBufferWidth/2 - 20;
private static int START_Y = Main.graphics.PreferredBackBufferHeight - 50;
// In game width and height
private const int WIDTH = 40;
private const int HEIGHT = 25;
public Player():base(START_X, START_Y, WIDTH, HEIGHT){
this.texture = Main.content.Load<Texture2D>("player");
}
public override void Draw(SpriteBatch spriteBatch){
spriteBatch.Draw(this.texture, new Rectangle(x, y, width, height) , Color.White);
}
public override void Update(GameTime gameTime){
// update the position of the player when the <LEFT> and <RIGHT> keys are pressed
if (Keyboard.GetState().IsKeyDown(Keys.Right))
this.x += 3;
if(Keyboard.GetState().IsKeyDown(Keys.Left))
this.x -= 3;
// check if the player is going out of bounds
if (this.x < 0)
this.x = 0;
else if (this.x > Main.graphics.PreferredBackBufferWidth - WIDTH)
this.x = Main.graphics.PreferredBackBufferWidth - WIDTH;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment