Extra Credit – Arduino + Processing Game

For the Week 3 assignment, I made a game. This game was NYUAD-themed and the player used arrow keys to make Faiza the falcon avoid certain obstacles and get a 4.0 GPA. The link to that post is attached below.

Week 3 – Go, get that 4.0!

This extra credit assignment is an extension of my Week 3 assignment, except that it makes use of buttons instead of arrow keys. There are 4 different buttons, each corresponding to a single direction.

I figured that the purpose of this assignment was to understand serial communication well, so I tried making good use of a game I had already made earlier.

The group exercises which were due on Monday, together with working on this game, have allowed me to understand the communication between Processing and Arduino a lot better.

Arduino code:

const int yellowButtonPin = 2;
const int greenButtonPin = 4;
const int redButtonPin = 7;
const int blueButtonPin = 8;


void setup() {
  Serial.begin(9600);
  Serial.println("0");
  pinMode(yellowButtonPin, INPUT);
  pinMode(greenButtonPin, INPUT);
  pinMode(redButtonPin, INPUT);
  pinMode(blueButtonPin, INPUT);
}

void loop() {
  while (Serial.available()) {
    if (Serial.read() == '\n') {
      int yellow_button = digitalRead(2);
      delay(1);
      int green_button = digitalRead(4);
      delay(1);
      int red_button = digitalRead(7);
      delay(1);
      int blue_button = digitalRead(8);
      delay(1);

      Serial.print(yellow_button);
      Serial.print(",");
      Serial.print(green_button);
      Serial.print(",");
      Serial.print(red_button);
      Serial.print(",");
      Serial.println(blue_button);
    }
  }

}

Processing code:

import java.lang.Math;
import processing.sound.*;
import processing.serial.*;
Serial myPort;
SoundFile file;

String audioName = "intro.mp3";
String path;

PImage[] images;
Game game;

// creating an array for distractions which are used later
Distractions[] distractions;

class Faiza{
  float posX, posY;
  float radius;
  float velocityX;
  float velocityY;
  float imgwidth, imgheight;
  String directionX;
  //String keyY, keyX;
  boolean move_up, move_down, move_right, move_left;
  boolean alive;
  int counter, frame;
  
  Faiza(float x, float y, float r, float img_w, float img_h){
    posX = x;
    posY = y;
    radius = r;
    velocityX = 0;
    velocityY = 0;
    imgwidth = img_w;
    imgheight = img_h;
    directionX = "right";
    move_up = false;
    move_down = false;
    move_right = false;
    move_left = false;
    alive = true;
    counter = 0;
    frame = 0;
  }
  
  void display(){
    update();
    if (directionX == "right"){
      image(images[0], float(int(posX - imgwidth/2)), float(int(posY - imgheight/2)), imgwidth, imgheight, int(frame * imgwidth), 0, int((frame + 1) * imgwidth), int(imgheight));
    }
    else if (directionX == "left"){
      image(images[0], float(int(posX - imgwidth/2)), float(int(posY - imgheight/2)), imgwidth, imgheight, int((frame + 1) * imgwidth), 0, int(frame * imgwidth), int(imgheight));
    }
  }
  
  void update(){
    //The condition below is for when Faiza moves left
    if (move_left == true){
       velocityX = -2;
       directionX = "left";
       if (posX - radius + velocityX < 6){
         velocityX = 0;
       }
       posX += velocityX;
    }
                    
    //The condition below is for when Faiza moves right
    else if (move_right == true){
      velocityX = 2;
      directionX = "right";
      if (posX + radius + velocityX > 1018){
        velocityX = 0;
      }
      posX += velocityX;
    }

    //If none of the left and right keys are being pressed, Faiza stops moving horizontally
    else{
      velocityX = 0;   
    }        
    
    if (move_up == true){
      velocityY = -2;
      if (posY - radius + velocityY <= 5){
        velocityY = 0;
      }
      posY += velocityY;
    }
                    
//The condition below is for when Faiza moves downwards
    else if (move_down == true){
      velocityY = 2;
      if (posY + radius + velocityY >= 762){
        velocityY = 0;
      }      
      posY += velocityY;
    }
                    
//If none of the up and down keys are being pressed, Faiza stops moving vertically
    else{
    velocityY = 0;
    }
  
    if (distance(game.gpa) <= (radius + game.gpa.radius)){
      game.level += 1;
    }
    
    if (!(posX >= 0 && posX <= 100 && posY >= 530 && posY <= 640)){ 
      for (int i = 0; i < 6; i++){
        if (distance(distractions[i]) <= radius + distractions[i].radius){
          counter += 1;
          println(counter);
          alive = false;
        }
      }
    }
  }
  
  // this distance method will be used to check for collisions with distractions
  double distance(Distractions target){
    float a = (posX - target.posX);
    float b = (posY - target.posY);
    double c = Math.pow(a, 2);
    double d = Math.pow(b, 2);
    return Math.pow(c + d, 0.5);
  }
  
   // this distance method will be used to check for collisions with the gpa (marking the end of the game)
   double distance(GPA target){
    float a = (posX - target.posX);
    float b = (posY - target.posY);
    double c = Math.pow(a, 2);
    double d = Math.pow(b, 2);
    return Math.pow(c + d, 0.5);
  }
}

class Distractions{
  float posX, posY;
  float radius;
  float imgwidth, imgheight;
  int frame;
  PImage img;
  float velocityX, velocityY;
  
  Distractions(float x, float y, float r, String _img, float img_w, float img_h){
    posX = x;
    posY = y;
    radius = r;
    img = loadImage(_img);
    imgwidth = img_w;
    imgheight = img_h;
    frame = 0;
    velocityX = random(2,5);
    velocityY = -1 * random(2,5);
  }
  
  void update(){
    if (posX + radius >= 1024){
      velocityX *= -1;
    }
    if (posX - radius <= 0){
      velocityX *= - 1;
    }
    if (posY - radius <= 10){
      velocityY *= -1;
    }
    if (posY + radius >= 780){
      velocityY *= -1;
    }
    
    posX += velocityX;
    posY += velocityY;
  }
  
  void display(){
    update();
    image(img, float(int(posX - imgwidth/2)), float(int(posY - imgheight/2)), imgwidth, imgheight, int(frame * imgwidth), 0, int((frame + 1) * imgwidth), int(imgheight));
  }
}

class GPA{
  float posX, posY;
  float radius;
  float imgwidth, imgheight;
  int frame;
  
  GPA(float x, float y, float r, float img_w, float img_h){
    posX = x;
    posY = y;
    radius = r;
    imgwidth = img_w;
    imgheight = img_h;
    frame = 0;
  }
  
  void display(){
    image(images[1], float(int(posX - imgwidth/2)), float(int(posY - imgheight/2)), imgwidth, imgheight, int(frame * imgwidth), 0, int((frame + 1) * imgwidth), int(imgheight));
  }
}

class Game{
  float game_width, game_height;
  Faiza faiza;
  GPA gpa;
  int level;
  
  Game(float game_wth, float game_hght){
    level = 1;
    game_width = game_wth;
    game_height = game_hght;
    faiza = new Faiza(34, 585, 27, 66, 66);
    gpa = new GPA(990, 35, 25, 70, 56);
  }
  
  void update(){
    if (faiza.alive == false){
      faiza.posX = 34;
      faiza.posY = 585;
      faiza.alive = true;
    }
  }
  
  void display(){
    update();
    
    image(images[2], 0, 0);
    
    if (level == 1){
      textMode(CENTER);
      textSize(40);
      fill(255, 213, 43);
      text("GET THAT 4.0!", 310, 65);
    }
    
    if (level != 1){
      textSize(150);
      fill(255, 213, 43);
      text("GAME", 270, 220); 
      text("OVER", 290,350);
      textSize(50);
      text(faiza.counter + " distractions later,", 240, 550);
      text("you achieved that 4.0 GPA!", 200, 600);
    }
    
    if (level == 1){
      faiza.display();
      gpa.display();
    }
    
    for (int i = 0; i < 6; i++){
      distractions[i].display();
    }
    
  }
}
  

void setup(){
 size(1024,768);
 
 printArray(Serial.list());
 String portname=Serial.list()[1];
 println(portname);
 myPort = new Serial(this,portname,9600);
 myPort.clear();
 myPort.bufferUntil('\n');
 
 game = new Game(1024, 768);
 path = sketchPath(audioName);
 file = new SoundFile(this, path);
 file.loop();
 images = new PImage[3];
 images[0] = loadImage("faiza.png");
 images[1] = loadImage("gpa.png");
 images[2] = loadImage("background.png");
 
 distractions = new Distractions[6];
 distractions[0] =  new Distractions(100, 300, 58, "jake.png", 120, 120);
 distractions[1] =  new Distractions(444, 333, 48, "insta.png", 100, 100);
 distractions[2] =  new Distractions(900, 120, 48, "facebook.png", 100, 100);
 distractions[3] =  new Distractions(887, 635, 48, "netflix.png", 100, 100);
 distractions[4] =  new Distractions(134, 587, 48, "youtube.png", 100, 100);
 distractions[5] =  new Distractions(55, 100, 48, "ps.png", 120, 120);
}

void draw(){
  background(255, 255, 255);
  game.display();
}

// allowing key presses to dictate Faiza's movement
void keyPressed(){
  if (key == CODED){
    if (keyCode == RIGHT){
      game.faiza.move_right = true;
    }
    if (keyCode == LEFT){
      game.faiza.move_left = true;
    }
    if (keyCode == UP){
      game.faiza.move_up = true;
    }
    if (keyCode == DOWN){
      game.faiza.move_down = true;
    }
  }
}
    
    
void keyReleased(){
  if (key == CODED){
    if (keyCode == RIGHT){
      game.faiza.move_right = false;
    }
    if (keyCode == LEFT){
      game.faiza.move_left = false;
    }
    if (keyCode == UP){
      game.faiza.move_up = false;
    }
    if (keyCode == DOWN){
      game.faiza.move_down = 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 == 4){
      if (values[0] == 1){
        game.faiza.move_left = true;
      }
      else{
        game.faiza.move_left = false;
      }
      
      if (values[1] == 1){
        game.faiza.move_down = true;
      }
      else{
        game.faiza.move_down = false;
      }
      
      if (values[2] == 1){
        game.faiza.move_up = true;
      }
      else{
        game.faiza.move_up = false;
      }
      
      if (values[3] == 1){
        game.faiza.move_right = true;
      }
      else{
        game.faiza.move_left = false;
      }
    }
  }
  
  myPort.write("\n");
  
}

 

Leave a Reply