Code viewer for World: University Bird (clone by ...

// Cloned by Colm McCarthy on 5 Dec 2022 from World "University Bird" by Niall Cian Quigley 
// Please leave this clone trail here.
 
/*
Game play: https://www.youtube.com/watch?v=fQoJZuBwrkU
*/
AB.socketStart();

let pipes = [];
let player1;
let player2;
let playing = false;

let birdImg, pipeImg, pipeRevImg, backgroundImg;


function preload() {
  birdImg = loadImage('uploads/quigln24/bird.png');
  birdImg2 = loadImage('uploads/quigln24/bird2.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);
  player1 = new Bird(width/3, height / 3);
  player1.flap();
  player2= new Bird(width/3, height / 3);
  player2.flap();
  player2.isTwo = true;
  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();
    //get rid of them pipes
    if (pipes[i].offScreen()) {
      if (pipes[i].pass(player1)&& player1.isAlive) {
        player1.score++;
      }
      pipes.splice(i, 1);
    }
    //endgame
    if (pipes[i].hit(player1)) {
      AB.socketOut(player1.score);
      AB.socketOut(player1.isAlive);
      
      player1.isAlive = false;
    }
    if (!player1.isAlive && !player2.isAlive){
      strokeWeight(4);
      rectMode(CENTER);
      fill(241, 122, 60);
      rect(width / 2, height / 2, width - 80, 80);
      fill(255);
      text(player1.score, ((width / 2) - 80), height / 2);
      text("vs", width / 2, height / 2);
      text(player2.score, ((width / 2) + 80), height / 2);
      let title = "Final Score:"
      text(title, width / 2, ((height / 2) -70));
      playing = false;
      noLoop();
    }

  }
  // draw player1 & 2
  player1.show();
  player1.update();
  player2.show();
  player2.update();
  // show the current score
  if (playing) {
    text(player1.score, width / 2, height / 5);
  }

}

function keyPressed() {
  if (key == ' ') {
    player1.flap();
    AB.socketOut("flap");
  }
}

function mousePressed(){
  // click inside the canvas
  if(player1.isAlive){
      if(mouseX > 0 && mouseX < width &&
         mouseY > 0 && mouseY < height) {
        player1.flap();
        AB.socketOut("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(player1) {
    if (player1.x > this.x && player1.x < this.x + this.w) {
      if (player1.y < this.top ||
        player1.y > this.top + this.gap) {
        return true;
      }
    }
    return false;
  }

  pass(player1) {
    if (player1.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.isTwo = false;
    this.isAlive = true;
    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);
    if(this.isTwo){
        image(birdImg2, 0, 0, this.r, this.r);
    }else{
        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;
  }
}

//SOCKETS MATE
function updatePlayer(flap2){
       player2.flap();
}
function updateScore(score2){
       player2.score = score2;
       console.log(player2.score);
}
AB.socketIn = function(n){
    if ( ! AB.runReady ) return;
    if (n == "flap"){
        updatePlayer(n);
    }
    else if(Number.isInteger(n)){
        updateScore(n);
    }
    else{
        player2.isAlive = false;
    }
}