javascriptclassp5.jsflappy-bird-clone

Objects not shown on screen & keyPressed not working (Flappy Bird Code Challenge)


I created flappy bird game following The Coding Train's tutorial on Youtube. (https://www.youtube.com/watch?v=cXgA1d_E-jY)

The original instruction created pipes and ball as objects, but I modified mine to be created as classes instead.

I have two problems. 1)The pipes indices I created in pipes array did not show on screen, 2)ball.goup();, which would be triggered by keyPressed() does nothing on screen, but console.log shows it is working. How should I revise my code? Thanks.

let ball;
let pipes = [];

function setup() {
  createCanvas(700, 600);
  ball = new Ball();
  pipes.push(new Pipe());
}

function draw() {
  background(0);

  ball.show();
  ball.falldown();

  if (frameCount % 60 == 0) {
    pipes.push(new Pipe());
  }
  
  //since have splice, count from back to avoid uncounted indices
  for (let i = pipes.length - 1; i >= 0; i--) {
     pipes[i].show();
     pipes[i].move();

     if (pipes[i].hits(ball)) {
       console.log("hit");
     }

     if (pipes[i].offscreen()) {
       pipes.splice(i, 1);
     }
   }
}

function keyPressed() {
  if (key == ' ') {
    ball.goup;
    console.log('up');
  }
}


class Ball {
  constructor(x = 50, y = height / 2, g = 0.6, v = 0, l = -20) {
    this.x = x;
    this.y = y;
    this.gravity = g;
    this.velocity = v;
    this.lift = l;
  }

  goup() {
    this.velocity += this.lift;
  }

  falldown() {
    this.velocity += this.gravity;
    this.velocity *= 0.9;
    this.y += this.velocity;

    if (this.y > height) {
      this.y = height;
      this.velocity = 0;
    }

    if (this.y < 0) {
      this.y = 0;
      this.velocity = 0;
    }

  }

  show() {
    noStroke();
    fill(255);
    ellipse(this.x, this.y, 25, 25);
  }

}


class Pipe {
  constructor(x =width, y=0, w=100, t=random(2/height), b=random(2/height), s=2, c=false) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.top = t;
    this.bottom = b;
    this.speed = s;
    this.colorchange = c;
  }

  hits(ball) {
    if (ball.y < this.top || ball.y > height - this.bottom) {
      if(ball.x > this.x && ball.x < this.x + this.w){
      this.colorchange = true;
      return true;
      }
    }
    this.colorchange = false;
    return false
  }

  move() {
    this.x -= this.speed;
  }

  show() {
    fill(255);
    if (this.colorchange) {
      fill(255, 0, 0);
    }
      rect(this.x, this.y, this.w, this.top);
      rect(this.x, height - this.bottom, this.w, this.bottom);
    }
  
  //delete pipe indices from the array when pipes are off screen
  offscreen() {
    if (this.x < -this.w) {
      return true;
    } else {
      return false;
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.min.js"></script>


Solution

  • The logic is sound, but there are a couple of typos. First, the ball isn't going up because by using this.goup you're not executing the method: the parenthesis are missing. Change that line (inside the keyPressed() function) for: this.goup() and the ball will start responding to the keyboard input.

    As for the pipes, they are drawing, but the default top and bottom are being defined as random(2 / height), and, being that height is equal to 600, it will result in a final value between 0 and 0.003333. To fix that, just rewrite the value assignment as t=random(height/2), b=random(height/2).

    let ball;
    let pipes = [];
    
    function setup() {
      createCanvas(700, 600);
      ball = new Ball();
      pipes.push(new Pipe());
    }
    
    function draw() {
      background(0);
    
      ball.show();
      ball.falldown();
    
      if (frameCount % 60 == 0) {
        pipes.push(new Pipe());
      }
    
      //since have splice, count from back to avoid uncounted indices
      for (let i = pipes.length - 1; i >= 0; i--) {
        pipes[i].show();
        pipes[i].move();
    
        if (pipes[i].hits(ball)) {
          //console.log("hit");
        }
    
        if (pipes[i].offscreen()) {
          pipes.splice(i, 1);
        }
      }
    }
    
    function keyPressed() {
      if (key == ' ') {
        ball.goup();
        //console.log('up');
      }
    }
    
    
    class Ball {
      constructor(x = 50, y = height / 2, g = 0.6, v = 0, l = -20) {
        this.x = x;
        this.y = y;
        this.gravity = g;
        this.velocity = v;
        this.lift = l;
      }
    
      goup() {
        this.velocity += this.lift;
      }
    
      falldown() {
        this.velocity += this.gravity;
        this.velocity *= 0.9;
        this.y += this.velocity;
    
        if (this.y > height) {
          this.y = height;
          this.velocity = 0;
        }
    
        if (this.y < 0) {
          this.y = 0;
          this.velocity = 0;
        }
    
      }
    
      show() {
        noStroke();
        fill(255);
        ellipse(this.x, this.y, 25, 25);
      }
    
    }
    
    
    class Pipe {
      constructor(x = width, y = 0, w = 100, t = random(height/2), b = random(height / 2), s = 2, c = false) {
        this.x = x;
        this.y = y;
        this.w = w;
        this.top = t;
        this.bottom = b;
        this.speed = s;
        this.colorchange = c;
      }
    
      hits(ball) {
        if (ball.y < this.top || ball.y > height - this.bottom) {
          if (ball.x > this.x && ball.x < this.x + this.w) {
            this.colorchange = true;
            return true;
          }
        }
        this.colorchange = false;
        return false
      }
    
      move() {
        this.x -= this.speed;
      }
    
      show() {
        fill(255);
        if (this.colorchange) {
          fill(255, 0, 0);
        }
        rect(this.x, this.y, this.w, this.top)
        rect(this.x, height - this.bottom, this.w, this.bottom);
      }
    
      //delete pipe indices from the array when pipes are off screen
      offscreen() {
        if (this.x < -this.w) {
          return true;
        } else {
          return false;
        }
      }
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.min.js"></script>