Y0/FMCC/W3 – Flappy Bird 0

This week I am looking at interaction in p5. I wanted to code a simple ‘jump’ game. Something that could be done in less than an hour so: Flappy Bird.

Setup

I first declare some needed variables:

const speed = 3;
let score = 0;
let highscore = 0;

function setup() {
  createCanvas(400, 400);
  strokeWeight(0);
  textAlign(CENTER,CENTER)
  
  thefloor = height;
  theceiling = 0;
}

Speed will be used to determine the difficulty of the game. Pipes will move at this speed. I set it as a constant but if I wanted to make the difficulty variable I could declare it using ‘let’.

player object

I first created the player object. I called it ‘frog’ because it jumps though I should have probably called it bird.

To create an object in JavaScript is simple. I simply need to declare it as a class and write the constructor method.

class freg{
  constructor(){
    this.x = width/2;
    this.y = height/2;
    this.yvel = 0;
    this.pressed = false;
  }
}

I am giving my player a position (x,y) and y-velocity. I am also setting a variable to determine whether an input was given.

I will next add a drawself() method

drawself(){
  circle(this.x,this.y,32);
}

and a step() method. This will run every frame.

step(){
  this.yvel -= 0.2; //gravity
  if(keyIsPressed && !this.pressed){
    this.pressed = true;
    if(keyCode == 32){
      this.yvel = 4;
    }
  }
  if(!keyIsPressed){ this.pressed = false; }

  this.y = (this.y - this.yvel) //apply movement
  
  if(this.y < theceiling || this.y >= thefloor){
    this.die();
  };
  this.drawself(); //draw
}

The step method includes gravity calculation and input handling. When a key is being pressed and the flag for already having pressed that key is not set, it will grant the player some upwards velocity.

The step method also handles crashing into the ceiling and floor.

The final thing it does is call the ‘die’ method.

die(){
  score = 0;
  this.y = height/2;
  this.yvel = 0;

  pipes.x = width;
  pipes.hei = random(height);
  pipes.cleared = false;
}

Dying will reset the score and position of the player/pipes.

Pipes

I’m defining pipes as a single object with height, width and gap. These will affect the pipe object as such:

Made using Aseprite
class pipe{
  constructor(hei,gap){
    this.hei = hei;
    this.gap = gap;
    this.x = width;
    
    this.wid = 64;
    this.cleared = false;
  }
}

The draw function is slightly more involved than drawing the player. It draws two rectangles for each pipe (top and bottom).

drawself(){
  rect(this.x,0,this.wid,this.hei-this.gap/2);
  rect(this.x,this.hei+this.gap/2,this.wid,height);
}

The step function handles collision checking and increasing the score when the player successfully flies through the gap. It also moves the pipe to the right of the canvas when it is fully off-screen to the left.

step(){
  this.drawself(); //draw
  this.x -= speed;
    
  if(this.x < -64){
    this.x = width;
    this.hei = random(height);
    this.cleared = false;
  }
  
  if(frog.x > this.x &&
    frog.x < this.x + this.wid &&
    frog.y > 0 &&
    frog.y < this.hei-(this.gap/2)){
    
    frog.die();
  }
  if(frog.x > this.x &&
    frog.x < this.x + this.wid &&
    frog.y > this.hei+this.gap/2 &&
    frog.y < height){
    
    frog.die();
  }
    
  if(this.x+this.wid < frog.x && this.cleared == false){ 
    this.cleared = true; 
    score++;
  }
}

Causing the pipes to wrap around means that there doesn’t need to be multiple pipe objects, just one which reduces memory usage and lag.

Final Steps

All that remains is to assign the two objects to variables in the setup function

function setup() {
  ...
  frog = new freg();
  pipes = new pipe(200,128); 
}

And step them in the draw function. I will also add some logic to deal with scoring.

function draw() {
  background(220);
  
  highscore = max(score,highscore);
  textSize(100);
  text(score,width/2,64);
  textSize(32);
  text("HI: "+highscore,width/2,128)
  
  frog.step();
  pipes.step();
}

The game is complete.

Made using p5.js

Link to Project/ Code

https://editor.p5js.org/woojinJang_/sketches/RV2tZzt4h

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *