Space Shooter Game – Extra Credit

For this extra credit project, I wanted to test my knowledge of the handshake between processing and arduino and so I came up with a space shooter game. It is a pretty basic game in which the space ship has to shoot the incoming meteoroids and if it shoots 10 of them the game is over.

 

Processing

The processing part is basically the interface of the game, which includes the start screen, the space ship, the asteroid and the whole shooting mechanism and also the end screen.

The game starts with the start screen in which the player clicks within a box to start playing.

The code basically spawns random sizes of asteroids, that fall at random speeds too. If the player is able to shoot 10 asteroids, the game is over and the player is prompted to either restart the game or click on game over to return to the start screen.

Processing Code:

import processing.serial.*;
Serial myPort;
ArrayList<Asteroid> asteroids = new ArrayList<Asteroid>(); //gives the list of asteroids
Player player; //player object
boolean shoot = false; // ensures that the player only shoots when commanded
ArrayList<Player.Bullet> bullets = new ArrayList<Player.Bullet>(); //bullet list
float timer = 0;
float timerlength  = 4000;
boolean game_over = false; 
boolean start = false; 
int count = 0; 
int currentButtonState = 0;
int prevButtonState = 0;
float mover = width/2; 

void setup()
{
  size(1280, 960);
  
  imageMode(CENTER);
  //asteroids.add(new Asteroid(random(width*0.25, width*0.75), 0, int(random(1, 3)))); //initialising the list of asteroids to spawn in between the roads of the game
  player = new Player();
  printArray(Serial.list());
  String portname=Serial.list()[6];
  println(portname);
  myPort = new Serial(this,portname,9600);
  myPort.clear();
  myPort.bufferUntil('\n');
  
}

void draw()

{
  PImage bg;  
  bg = loadImage("space.jpeg");
  bg.resize(int(width),int(height));
  background(bg); //background is the top down view of a road
  if (start == false)
  {
    textAlign(BASELINE);
  rectMode(CENTER);
  fill(255);
  stroke(230,153,0);
  rect(width/2,height/2,700,500,10);
  rect(width/2, height/2,680,480,10);
  
  fill(0);
  textSize(50); 
  text("Welcome", 480, 410);   
  fill(255);
  rect(625,580,600,100,10);
  fill(0);
  text("Click to Play", 420, 610);
  if ((mouseX >= 325 && mouseX <= 925) && (mouseY >= 530 && mouseY <= 630) && (mousePressed == true))
   {
     start = true;
   }
  }
  
  else{  
  if(game_over == false)
  {
   
    Player_Mechanics();
    Asteroid_Mechanics(); 
    Shoot();
    Mover();
    
    if( millis() > timer)
    {
      asteroids.add(new Asteroid(random(width*0.25, width*0.75), 0, int(random(1, 3)))); //initialising the list of asteroids to spawn 
      timerlength = random(1000,5000);
      timer = millis() + timerlength;
    }
  }
  
  else{
   textAlign(BASELINE);
  rectMode(CENTER);
  fill(255);
  stroke(230,153,0);  
  rect(width/2,height/2,700,500,10);
  rect(width/2, height/2,680,480,10);
  
  fill(0);
  textSize(50); 
  stroke(0);
  text("Game Over!", 420, 410);   
  fill(255);
  rect(625,580,600,100,10);
  fill(0);
  text("Restart", 420, 610);
  if ((mouseX >= 325 && mouseX <= 925) && (mouseY >= 530 && mouseY <= 630) && (mousePressed == true))
   {
     game_over = false;
     count = 0; 
   }
   
   if ((mouseX >= 325 && mouseX <= 925) && (mouseY >= 330 && mouseY <= 430) && (mousePressed == true))
   {
     start = false;
   }
   
  }
  }
}

void serialEvent(Serial myPort){
  String s=myPort.readStringUntil('\n');
  s=trim(s);
  if (s!=null){
    println(s);
    int values[]=int(split(s,','));
    if (values.length==3){
      currentButtonState=(int)values[0];
      prevButtonState=(int)values[1];
      mover = map(values[2], 0, 1023, player.size/2, width-player.size/2);
    }
  }
  myPort.write("\n");
}

void Player_Mechanics()
{
  
  player.drawPlayer();  //draws the Player on Screen
  
  for(int i =0; i< bullets.size(); i++)
  {
    
    bullets.get(i).draw_Bullet();
    bullets.get(i).shoot_Bullet();  //if bullets are present, draws them and shoots them
    if(bullets.get(i).bullet_posY_1 < 0 )
      bullets.remove(i); //removes the bullet once they are out of frame
  }
  

}


void Asteroid_Mechanics()
{
  for (int i = 0; i < asteroids.size(); i++)
  {   
    asteroids.get(i).drawAsteroid();
    asteroids.get(i).moveAsteroid(); //draws and moves asteroids on screen
    if(asteroids.get(i).posY > height + asteroids.get(i).size)
      asteroids.remove(i);  //removes the asteroids once they are out of frame
    if( bullets.size() > 0 && asteroids.size() > 0 )
    {
      for(int j=0; j<bullets.size(); j++)
      {
        if( bullets.size() > 0 && asteroids.size() > 0 )
        {
          if(asteroids.get(i).vicinty_check(bullets.get(j).bullet_posX,bullets.get(j).bullet_posY_2))
            {
              asteroids.remove(i); //destroys the asteroid and removes it once bullet touches it
              count++;
            }
        }
      }
    }
  }
  if (count == 10){
    game_over = true;
  }   
}

void keyPressed()
{
  if (key == ' ')
  {
    asteroids.add(new Asteroid(random(width*0.25, width*0.75), 0, int(random(1, 3)))); //spawns an asteroid
  }

  if (key == 'a')
  {
    player.moveLeft(); //player goes left
  }

  if (key == 'd')
  {
    player.moveRight(); //player goes right
  }
  
  if (key == 'f')
  {
    bullets.add(player.new Bullet(0));  //shoots bullets
  }
}

void Shoot()
{
  if (currentButtonState == 1 && prevButtonState == 0) {
    bullets.add(player.new Bullet(0));     
    println("cheeky");
  }
}


void Mover()
{
  player.posX = mover;
}
class Asteroid {

  float posX;
  float posY;
  int speed = (int)random(2,6);
  int size;
  PImage asteroid;




  Asteroid(float x, float y, int s)
  {
    posX = x;
    posY = y;
    size = s*100;
    asteroid = loadImage("asteroid_brown.png");
    imageMode(CENTER);
  }

  void drawAsteroid()
  {

    asteroid.resize(size, 0);
    image(asteroid, posX, posY);  //resizes and draws the asteroid
  }

  void moveAsteroid()
  {
    posY += speed;  //moves the asteroid
  }

  boolean vicinty_check(float x, float y)
  {
    if ((x < posX+size/2 && x > posX-size/2) && (y < posY+size/2 && y > posY-size/2))  //checks if anything exists in the vicintiy of the asteroid's body
      return true;
    else
      return false;
  }
}
class Player {

  public float posX = width/2;  
  public float posY = height-100;
  PImage player;  
  int movement=20;
  int size =100;


  Player()
  {

    player = loadImage("Spaceship_tut.png");
    imageMode(CENTER);
  }



  void drawPlayer()
  {
    player.resize(size, 0);
    pushMatrix();
    translate(posX, posY);
    //rotate(radians(270));
    image(player, 0, 0);
    popMatrix(); //resizes and rotates the image of the player on screen so that it is appropriate for the game
  }

  void moveLeft()
  {
    
    if (posX > size/2)
      posX -= movement; //player moves left
  }

  void moveRight()
  {
    
    if (posX < width-size/2)
      posX += movement; //player moves right
  }


  class Bullet {    //nested bullet class in player class

    float  bullet_posX = posX ;
    float  bullet_posY_1 = posY - size/2; 
    float  bullet_size = size * 0.1; 
    float  bullet_posY_2 = posY - size/2 - bullet_size; 
    int bullet_speed = 20; 


    Bullet(float y)
    {
      bullet_posY_1 -= y;
      bullet_posY_2 -= y;    //assigns intial position to bullet
    } 
    void draw_Bullet()
    {
      stroke(102,255,102);
      strokeWeight(6);
      line(bullet_posX, bullet_posY_1, bullet_posX, bullet_posY_2);  //draws a line for a bullet
    } 

    void shoot_Bullet()  

    {
      bullet_posY_1 -= bullet_speed;
      bullet_posY_2 -= bullet_speed;  //moves bullet
    }
  }
}

 

Game Display

Arduino

The Arduino part involves the controls for the game in which the potentiometer is used to move the spaceship around and the push button is used to shoot the missiles from the spaceship.

 

Arduino Code:

int buttonPin = 2;
int prevButtonState = LOW;

void setup() {
  pinMode(buttonPin, INPUT);
  Serial.begin(9600);
  Serial.println("0,0");
}

 void loop() {
  while (Serial.available()) {
    if (Serial.read() == '\n') {
      int currentButtonState = digitalRead(buttonPin);
      delay(1);      
      Serial.print(currentButtonState);
      Serial.print(',');
      Serial.print(prevButtonState);
      Serial.print(',');      
      prevButtonState = currentButtonState;
      int mover = analogRead(A0);
      delay(1);
      Serial.println(mover);
    }
  }
  
  //Serial.println(sensor);

}

 

Circuit:

Arduino Circuit

Videos:

This is the video of me showing the way the game works:

This is a video of me actually playing the game:

Difficulties:

In certain instances, I felt that the button was not responding in the way I wanted it to but I believe that is primarily because I hadn’t plugged it well or the communication of information was slow.

Overall:

This project was actually really fun and it made me feel so cool to create my own joystick for my game. This has also motivated me quite a lot for my final project which I am really looking forward to!

Leave a Reply