<repo_name>ArshiaSoni/Multiplayer-Game<file_sep>/Form.js
class Form{
    constructor(){
        this.title = createElement('h1');
        this.input = createInput('Name');
        this.button = createButton('Play');
        this.greeting = createElement('h2');
    }

    hide(){
        // hide all the elements
        this.title.hide();
        this.input.hide();
        this.button.hide();
        this.greeting.hide();
    }

    display(){
        this.title.html('Car Racing Game');
        this.title.position((displayWidth- 50)/2, 0);

        this.input.position((displayWidth- 50)/2, 150);
        this.button.position((displayWidth- 50)/2, 200);

        this.button.mousePressed(() => {
            this.input.hide();
            this.button.hide();

            // get name of the player, increase pC as it starts from 0 and update the database
            var name = this.input.value();

            this.greeting.html('Hello ' + name);
            this.greeting.position((displayWidth- 50)/2, 150);

            player.name = name;
            playerCount ++;
           
            player.index = playerCount;
            player.updatePlayerCount(playerCount);
            player.updatePlayerInfo();
        })
    }
}<file_sep>/sketch.js
var database;
var player, form, game;
var allPlayers;
var resetButton;
var gameState, playerCount, carsAtEnd;
var cars, car1, car2, car3, car4;
var tracks, car1_img, car2_img, car3_img, car4_img;

function preload(){
  tracks = loadImage("track.jpg");
  car1_img = loadImage("car1.png");
  car2_img = loadImage("car2.png");
  car3_img = loadImage("car3.png");
  car4_img = loadImage("car4.png");
}

function setup(){
  createCanvas(displayWidth- 50, displayHeight - 100);

  database = firebase.database();
  console.log(database);

  game = new Game();
  game.getGameState();
  game.start();

  // easy reseting of values
  resetButton = createButton('Reset');
  resetButton.position(50, 50);

}

function draw(){

  background(146, 124, 111);
  imageMode (CENTER);
  image (tracks, (displayWidth- 50)/2, (displayHeight - 100)/2, displayWidth- 50, displayHeight*5);

  resetButton.mousePressed(() =>{
    console.log("Reset button pressed");
    game.updateGameState(0);
    player.updatePlayerCount(0);
    player.updateCarsAtEnd(0);
    database.ref('players').remove();
  })

  if(playerCount == 4){
    game.updateGameState(1);
    
  }

  if(gameState == 1){
    clear ();
    game.play();
  }

  if(gameState == 2){
    game.end();
    // If you update gameState in database then car doesn't stop some glitch
    //game.updateGameState(2);
  }

  drawSprites();
}<file_sep>/Game.js
class Game{
  constructor(){

  }

  getGameState(){
    var gameStateRef = database.ref('gameState');
    gameStateRef.on("value", (data) =>{
      gameState = data.val();
      console.log("GameState in dB is : " + gameState);
    })
  }

  updateGameState(state){
    database.ref('/').update({
      gameState: state
    })
  }

 start(){
   // as the gameState value is not fetched 
    var gameStateRef = database.ref('gameState');
    gameStateRef.on("value", (data) =>{
      gameState = data.val();

      if(gameState == 0){
        console.log("in start");
        player = new Player();
        player.getPlayerCount();

        form = new Form();
        form.display();
      }

    })

    car1 = createSprite(350, 600);
    car1.addImage(car1_img);

    car2 = createSprite(550, 600);
    car2.addImage(car2_img);

    car3 = createSprite(750, 600);
    car3.addImage(car3_img);

    car4 = createSprite(950, 600);
    car4.addImage(car4_img);

    cars = [car1, car2, car3, car4];
  
  }

  play(){
    form.hide();

    background(146, 124, 111);
    imageMode (CENTER);
    image (tracks, (displayWidth- 50)/2, (displayHeight - 100)/2, displayWidth- 50, displayHeight*5);

    Player.getPlayerInfo();
    player.getCarsAtEnd();

    // for allPlayers JSON
    var plr;
    var ySpacing = 50;

    // for cars array
    var index = 0;
    // x is needed to capture x coordinate for drawing the circle not to display car
    var x = 350;

   // starting position of all cars
    var y = 600;

    for(plr in allPlayers){

      // fill the data from database into cars array for y position for all players so that position of cars are consistent
      cars[index].x = x;
      y = 600 - allPlayers[plr].distance;
      cars[index].y = y;
      

      // spot the car player index has the no eg 1, 2, 3, 4 and index starts from 0 for cars array
      if(player.index == index + 1){

        camera.position.y = cars[index].y;

        fill ("red");
        circle(x, y, 60);
      }

      // so that only the current car text is in red
      else fill ("black");
      
      // update the x position for car and index for cars array
      x += 200;
      index ++;

      // redundant
      text (allPlayers[plr].name + " : " + allPlayers[plr].distance, (displayWidth- 50)/2, ySpacing);
      ySpacing += 50;
    }

    // move cars up
    if(keyIsDown(UP_ARROW)){
      player.distance += 50;
      player.updatePlayerInfo();
    }

    // ranks
    if(player.distance >= 2000){
      gameState = 2;
      player.rank ++;

      // update rank in database for each player
      player.updatePlayerInfo();

      player.updateCarsAtEnd(player.rank);
    }

  }

  end(){
    alert("Game Ends");
    alert("Rank is: " + player.rank);
  }

}
<file_sep>/Player.js
class Player{
    constructor(){
        this.name = null;
        this.distance = 0;
        // to see the index clearly
        this.index = 0;
        this.rank = 0;
    }

    getPlayerCount(){
        var playerCountRef = database.ref('playerCount');
        playerCountRef.on("value", (data) =>{
            playerCount = data.val();
            console.log("PlayerCount in dB is : " + playerCount);
        })
    }

    updatePlayerCount(count){
        database.ref('/').update({
            playerCount: count
        })
    }

    // we want player info at once without refering to each player in a loop so create a static function that can be called for class 
    static getPlayerInfo(){
        database.ref('players').on("value", (data) => {
            allPlayers = data.val();
            
        })
    }

    updatePlayerInfo(){
        database.ref('players/player' + this.index).update({
            name: this.name,
            distance: this.distance,
            rank: this.rank,
            index: this.index
        })
    }

    getCarsAtEnd(){
        var carsRef = database.ref('carsAtEnd');
        carsRef.on("value", (data) => {
            carsAtEnd = data.val();
            console.log("Cars at end in dB : " + carsAtEnd);
            this.rank = carsAtEnd;
        })
    }

    // no need to create a static function each player will update his own rank
    updateCarsAtEnd(rank){
        database.ref('/').update({
            carsAtEnd: rank
        })
    }
}