Project showcase

Create a Game with Arduino and Processing

Create a game with processing and its controller with an accelerometer and a button.

  • 1,208 views
  • 3 comments
  • 5 respects

Components and supplies

Apps and online services

About this project

Overview

First of all we build the game controller, using a button and an accelerometer. I use a GY-521, so if you use a different accelerometer you will need to change part of the code.

Connections for the accelerometer and the button

  • VCC -> 5 V
  • GND -> GND
  • SCL -> A5
  • SDA -> A4

Connect the button to the digital pin 7 and connect it to ground with a 10 Kohm resistor. Then connect the supply to 5 V.

How to make it

In the code we use the Bounce library in order to avoid the bounce of the signal of the button. Download the library and copy the unzipped folder in the libraries folder of Arduino.

I use a standard breadboard but it's a bit difficult moving the controller. It would be better to use an Arduino Prototyping shield.

To create the game we use Processing, which can be downloaded here. First you run the Arduino code. Then run the Processing code.

Wait for the accelerometer to stabilize. Press the button and the game will start. Moving the accelerometer along the X axis the paddle will move.

Be mindful of port

Check the Processing code. Maybe you need to change the instruction: arduinoPort=new Serial(this, "COM3", 19200); Instead of COM3 you have to use the port you are using with Arduino. Also Processing and Ardruino must have the same baud rate.

Schematics

circuit diagram
Game controller bb v6yjrqcnub

Code

Processing codeProcessing
import processing.serial.*;

Serial arduinoPort;

final int COLUMNS=7;
final int ROWS=4;
final int BALL_RADIUS=8;
final int BALL_DIAMETER=BALL_RADIUS*2;
final int MAX_VELOCITY=8;
final int MARGIN=10;
final int PADDLE_WIDTH=60;
final int PADDLE_HEIGHT=15;
final int BRICK_WIDTH=40;
final int BRICK_HEIGHT=20;
final int HEIGHT=300;
final int LINE_FEED=10;

int px, py;
int vx, vy;
int xpos=150;
int[][] bricks= new int[COLUMNS][ROWS];

boolean buttonPressed=false;
boolean paused=true;
boolean done=true;

void setup(){
  size(300, 300);
  noCursor();
  textFont(loadFont("Verdana-Bold-36.vlw"));
  initGame();
  println(Arduino.list());
  arduinoPort=new Serial(this, "COM3", 19200);
  arduinoPort.bufferUntil(10);
}

void initGame(){
  initBricks();
  initBall();
}

void initBricks(){
  for(int x=0; x<COLUMNS; x++)
  for(int y=0; y<ROWS; y++)
  bricks[x][y]=1;
}

void initBall(){
  px=width/2;
  py=height/2;
  vx=int(random(-MAX_VELOCITY, MAX_VELOCITY));
  vy=-2;
}

void draw(){
  background(0);
  stroke(255);
  strokeWeight(3);
  
  done=drawBricks();
  if(done){
    paused=true;
    printWinMessage();
  }
  if(paused)
    printPauseMessage();
  else
    updateGame();
  
  drawBall();
  drawPaddle();
}

boolean drawBricks(){
  boolean allEmpty=true;
  for(int x=0; x<COLUMNS; x++){
    for(int y=0; y<ROWS; y++){
      if(bricks[x][y]>0){
        allEmpty=false;
        fill(0, 0, 100+y*8);
        rect(
          MARGIN+x*BRICK_WIDTH,
          MARGIN+y*BRICK_HEIGHT,
          BRICK_WIDTH,
          BRICK_HEIGHT
        );
      }
    }
  }
  return allEmpty;
}

void drawBall(){
  strokeWeight(1);
  fill(128, 0, 0);
  ellipse(px, py, BALL_DIAMETER,  BALL_DIAMETER);
}

void drawPaddle(){
  int x=xpos - PADDLE_WIDTH/2;
  int y=height - 25;
  strokeWeight(1);
  fill(128);
  rect(x, y, 60, 15);
}

void printWinMessage(){
  fill(225);
  textSize(36);
  textAlign(CENTER);
  text("YOU WIN", width/2, height*2/3);
}

void printPauseMessage(){
  fill(128);
  textSize(16);
  textAlign(CENTER);
  text("Press button to continue", width/2, height*5/6);
}

void updateGame(){
  if(ballDropped()){
    initBall();
    paused=true;
  } else{
    checkBrickCollision();
    checkWallCollision();
    checkPaddleCollision();
    px+=vx;
    py+=vy;
  }
}

boolean ballDropped(){
  return py+vy> height - BALL_RADIUS;
}

boolean inXRange(final int row, final int v){
  return px + v > row*BRICK_WIDTH&&
         px+v < (row+1)*BRICK_WIDTH+BALL_DIAMETER;
}

boolean inYRange(final int col, final int v){
  return py+v> col*BRICK_HEIGHT&&
         py+v< (col+1)*BRICK_HEIGHT+BALL_DIAMETER;
}

void checkBrickCollision(){
  for(int x=0; x<COLUMNS; x++){
    for(int y=0; y<ROWS; y++){
      if(bricks[x][y]>0){
        if(inXRange(x, vx)&& inYRange(y, vy)){
          bricks[x][y]=0;
          if(inXRange(x, 0))
          vy=-vy;
          if(inYRange(y, 0))
          vx=-vx;
        }
      }
    }
  }
}

void checkWallCollision(){
  if(px+vx < BALL_RADIUS || px+vx > width - BALL_RADIUS)
  vx=-vx;
  
  if(py+vy < BALL_RADIUS || py+vy > height - BALL_RADIUS)
  vy=-vy;
}

void checkPaddleCollision(){
  final int cx=xpos;
  if(py+vy >=height - (PADDLE_HEIGHT + MARGIN + 6)&&
    px >= cx - PADDLE_WIDTH/2 &&
    px <= cx + PADDLE_WIDTH/2)
    {
      vy=-vy;
      vx=int(
        map(
          px - cx,
          -(PADDLE_WIDTH/2), PADDLE_WIDTH/2,
          -MAX_VELOCITY,
          MAX_VELOCITY
        )
      );
    }
}

void serialEvent(Serial port){
  final String arduinoData=port.readStringUntil(LINE_FEED);
  if(arduinoData!=null){
   println(arduinoData);
   final int[] data=int(split(trim(arduinoData), ' '));
    if(data.length==4){
      buttonPressed=(data[3]==1);
    if(buttonPressed){
        paused= !paused;
        if(done){
          done=false;
          initGame();
        }
      }
      
      if(!paused)
      xpos=int(map(data[0]-2000, 252, 443, 0, 300));
    }
  }
}
Arduino codeArduino
#include <Bounce.h>
#include <Wire.h>

const unsigned int Button_Pin=7;
const int MPU=0x68; 
int16_t AcX,AcY,AcZ;
const int NUM_AXES=3;
  
const int BUFFER_SIZE=16;
int buffer[NUM_AXES][BUFFER_SIZE];
int buffer_pos[NUM_AXES]={0};
Bounce button(Button_Pin, 20);

void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B); 
  Wire.write(0);    
  Wire.endTransmission(true);
  Serial.begin(19200);
  pinMode(Button_Pin, INPUT);
}

int get_axis(const int axis){
  delay(1);
  buffer[axis][buffer_pos[axis]]=Wire.read()<<8|Wire.read();
  buffer_pos[axis]=(buffer_pos[axis]+1)%BUFFER_SIZE;
  long sum=0;
  for(int i=0; i<BUFFER_SIZE; i++)
  sum+= buffer[axis][i];
  return round(sum/BUFFER_SIZE);
  }
  
  int get_x(){return get_axis(0);}
  int get_y(){return get_axis(1);}
  int get_z(){return get_axis(2);}
    
void loop(){
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);  
  Wire.endTransmission(false);
  Wire.requestFrom(MPU,6,true);
  Serial.print(get_x());
  Serial.print(" ");
  Serial.print(get_y());
  Serial.print(" ");
  Serial.print(get_z());
  Serial.print(" ");
  if(button.update())
    Serial.println(button.read()==HIGH ? "1" : "0");
  else
    Serial.println("0");
    
  delay(50);
}

Comments

Similar projects you might like

USBcycle: Ride Through Your Virtual World!

Project showcase by Tazling

  • 2,269 views
  • 0 comments
  • 7 respects

Mini CNC: A Handmade Masterpiece

Project showcase by Mr-M

  • 1,842 views
  • 2 comments
  • 13 respects

Arduino UNO High Precision Counting Scale

Project showcase by Fedeasche

  • 3,912 views
  • 5 comments
  • 19 respects

Arduino Controlled Piano Robot: PiBot

Project tutorial by Jeremy Yoo

  • 2,041 views
  • 0 comments
  • 7 respects

DIY Thrust Station

by Vincenzo G.

  • 232 views
  • 0 comments
  • 3 respects

Automation of Railway Models Part 3 - Bidirectional Line

Project showcase by Steve_Massikker

  • 965 views
  • 2 comments
  • 10 respects
Add projectSign up / Login