วันพฤหัสบดีที่ 30 สิงหาคม พ.ศ. 2561

(งาน20)https://create.arduino.cc/projecthub/Nicholas_N/create-a-game-with-arduino-and-processing-0fbed3?ref=tag&ref_id=sensor&offset=45


Create a Game with Arduino and Processing

Create a game with processing and its controller with an accelerometer and a button.
  • 3,776 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.

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));
    }
  }
}

SCHEMATICS

circuit diagram
Game controller bb v6yjrqcnub