Code viewer for World: University Bird v0.7
/*
Game play: https://www.youtube.com/watch?v=fQoJZuBwrkU
*/

let pipes = [];
let bird;
let playing = false;

let birdImg, pipeImg, pipeRevImg, backgroundImg;




function preload() {
  birdImg = loadImage('uploads/quigln24/bird.png');
  pipeImg = loadImage('uploads/quigln24/pipes.png');
  pipeRevImg = loadImage('uploads/quigln24/pipes_reverse.png');
  backgroundImg = loadImage('uploads/quigln24/background.png');
}

function setup() {
  createCanvas(400, 600);
  frameRate(40);
  bird = new Bird(width/3, height / 3);
  bird.flap();
  angleMode(DEGREES);
  textAlign(CENTER, CENTER);
  textStyle(BOLD);
  textSize(50);
}

function draw() {
  background(backgroundImg);
  if (frameCount % 50 == 0) {
    pipes.push(new Pipe());
    playing = true;
  }

  for (let i = pipes.length - 1; i >= 0; i--) {
    pipes[i].show();
    pipes[i].update();
    if (pipes[i].offScreen()) {
      if (pipes[i].pass(bird)) {
        bird.score++;
      }
      pipes.splice(i, 1);
    }
    if (pipes[i].hit(bird)) {
      strokeWeight(4);
      rectMode(CENTER);
      fill(241, 122, 60);
      rect(width / 2, height / 2, width - 80, 80);
      fill(0);
      text(
        bird.score, width / 2, height / 2);
      playing = false;
      noLoop();
    }
  }
  // draw bird
  bird.show();
  bird.update();
  // show the current score
  if (playing) {
    text(bird.score, width / 2, height / 5);
  }

}

function keyPressed() {
  if (key == ' ') {
    bird.flap();
  }
}

function mousePressed(){
  // click inside the canvas
  if(mouseX > 0 && mouseX < width &&
     mouseY > 0 && mouseY < height) {
    bird.flap();
  }
}


function drawLine() {
  let step = 100;
  stroke(1);
  for (let i = 0; i < height / step; i++) {
    line(0, i * step, width, i * step)
  }
}


// ---------------------------------------- PIPE --------------------------- 


class Pipe {
  constructor() {
    this.x = width;
    this.w = 90;
    this.gap = 120;
    this.min_height = 100;
    this.max_height = height - this.min_height - this.gap;
    this.top = floor(random(this.min_height, this.max_height));
    this.speed = 5;
  }

  show() {
    fill(255, 0, 0);
    /* top pipe */
    // rect(this.x, 0, this.w, this.top);
    image(pipeRevImg, this.x, 0, this.w, this.top);
    /* bottom pipe */
    fill(0, 255, 0);
    let height_b = height - this.gap - this.top;
    let y_b = height - height_b;
    // rect(this.x, y_b, this.w, height_b);
    image(pipeImg, this.x, y_b, this.w, height_b);
  }

  offScreen() {
    if (this.x + this.w + this.speed < 0) {
      return true;
    }
    return false;
  }

  hit(bird) {
    if (bird.x > this.x && bird.x < this.x + this.w) {
      if (bird.y < this.top ||
        bird.y > this.top + this.gap) {
        return true;
      }
    }
    return false;
  }

  pass(bird) {
    if (bird.x > this.x + this.w) {
      return true;
    }
    return false;
  }

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

// ------------------------------ BIRD

class Bird {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.r = 50;
    this.gravity = 2;
    this.velocity = 0;
    this.lift = -30;
    this.friction = 0.1;
    this.score = 0;
    this.up = false;
  }

  show() {
    fill(255);
    push();
    imageMode(CENTER);
    translate(this.x, this.y);
    if (this.up || this.velocity < 0) {
      rotate(-35);
    } else {
      rotate(35);
    }
    // ellipse(this.x, this.y, this.r);
    image(birdImg, 0, 0, this.r, this.r);
    pop();
  }

  update() {
    this.velocity += this.gravity;
    this.velocity = constrain(this.velocity, -25, 25);
    this.y += this.velocity;
    if (this.y > height) {
      this.velocity = 0;
      this.y = height;
    } else if (this.y < 0) {
      this.velocity = 0;
      this.y = 0;
    }
    this.up = false;
  }

  flap() {
    this.velocity += this.lift;
    this.velocity *= (1 - this.friction);
    this.up = true;
  }
}