Code viewer for World: 3D Shooter
/*

How the game should work:

1. When player loads the game, user id should be pushed to a players array.
2. There should be a loading screen until there are two players.
3. Once there are two players, we should load the game resources.
4. Players then shoot the shit out of each other, the game ends when one player loses all lives.
5. Game over, option to reload the game and start from step 1.

THINGS TO DO:
Create different positions to load the two players.
Fix camera position so that the camera is looking at the back of each player, and following them.
Background design and platform. The world is has no design atm.
Players rotation.
Shooting bullets in the directiont the player is facing, currently only shooting in one direction.

*/

const skycolor          = 'lightblue';           
const boxcolor          = 'maroon';

const objectsize    = 300;                  // size of object   

const startRadius   = 3000;                 // distance from centre we start the camera at

const maxRadius     = startRadius * 10;     // maximum distance from camera we render things 

var playerArray = [];

function createPlayer() {
    var shape       = new THREE.BoxGeometry ( objectsize, objectsize, objectsize );
    var material    = new THREE.MeshBasicMaterial ( { color: AB.randomColor()} );
    var theobject   = new THREE.Mesh ( shape, material );
    return theobject;
}
/*
var material    = new THREE.MeshBasicMaterial ( { color: boxcolor.toLowerCase() } );
var bulletShape = new THREE.SphereGeometry(100, 100, 100);
var bullet = new THREE.Mesh(bulletShape, material);
*/
class Player {
    
    constructor(name) {
        this.name = name;
        this.lives = 3;
        this.score = 0;
        this.model = createPlayer();
        this.hasHitOpponent = false;
        console.log(this.name, this.model.position);
    }
    
    get playerCoords() {
        return this.model.position;
    }
    
    movePlayer(pos) {

        switch (pos) {
            case 'left':
                this.model.position.x -= 50;
                break;
            case 'right':
                this.model.position.x += 50;
                break;
            case 'up':
                this.model.position.z -= 50;
                break;
            case 'down':
                this.model.position.z += 50;
                break;
        }
    }
    
    shoot() {
      var bullet = createBullet(this.model);
      ABWorld.scene.add(bullet);

      var bulletSpeed = 30;  // adjust this value to control the bullet's speed
      var animateBullet = () => {
          if (this == playerOne) {
              bullet.position.z -= bulletSpeed;
          }
          else {
              bullet.position.z += bulletSpeed;
          }
        
        var opp = this == playerOne ? playerTwo : playerOne;
        var distance = bullet.position.distanceTo(opp.model.position);
        if (distance < 100) {  // adjust this threshold value as needed
            ABWorld.scene.remove(bullet);
            
            this.hasHitOpponent = true;
        }
        requestAnimationFrame(animateBullet);
      };
        var bang = new Audio('uploads/senanw95/gunshot.mp3');
        bang.play();
      animateBullet();
      
      if (this.hasHitOpponent) {
          this.score++;
          var opp = this == playerOne ? playerTwo : playerOne;
          opp.lives--;
          console.log("GOTCHA");
          
          if (this == playerOne) {
              AB.msg(this.name + " score:" + this.score + "lives: " + this.lives, 1);
          }
          else {
            AB.msg(this.name + ":" + this.score + "lives: " + this.lives, 2);
          }
      }
      return;
    }

}


function createBullet(player)
{
    var shape = new THREE.BoxGeometry( 50, 50, 50 );		//creating the layout for the bullet.	 
    var material    = new THREE.MeshBasicMaterial ( { color: boxcolor} );
    var bullet = new THREE.Mesh ( shape, material );
    bullet.position.set(player.position.x, 35 ,player.position.z );
    return bullet;
    
}



function keyHandler(e) {
    if (e.keyCode == 37 && AB.myuserid == playerArray[0]) {
        playerOne.movePlayer('left');
        AB.socketOut('left'); 
    }
    else if (e.keyCode == 37 && AB.myuserid == playerArray[1]) {
        playerTwo.movePlayer('left');
        AB.socketOut('left2');
    }
    if (e.keyCode == 38 && AB.myuserid == playerArray[0]) {
        playerOne.movePlayer('up');
        AB.socketOut('up');

    }
    else if (e.keyCode == 38 && AB.myuserid == playerArray[1]) {
        playerTwo.movePlayer('up');
        AB.socketOut('up2');
    }
    if (e.keyCode == 39 && AB.myuserid == playerArray[0]) {
        playerOne.movePlayer('right');
        AB.socketOut('right');
    }
    else if (e.keyCode == 39 && AB.myuserid == playerArray[1]) {
        playerTwo.movePlayer('right');
        AB.socketOut('right2');
    }
    if (e.keyCode == 40 && AB.myuserid == playerArray[0]) {
        playerOne.movePlayer('down');
        AB.socketOut('down'); 
    }
    else if (e.keyCode == 40 && AB.myuserid == playerArray[1]) {
        playerTwo.movePlayer('down');
        AB.socketOut('down2');
    }
    if (e.keyCode == 32 && AB.myuserid == playerArray[0]) {
        playerOne.shoot();
        AB.socketOut('shoot');
    }
    else if (e.keyCode == 32 && AB.myuserid == playerArray[1]) {
        playerTwo.shoot();
        AB.socketOut('shoot2');
    }

}

AB.backgroundMusic('uploads/senanw95/ChrisSpedding-Gunfight.mp3');

// Define what the World does at the start of a run: 

AB.world.newRun = function() {
    
    
    
    AB.loadingScreen();
    
    // start a 3D scene: 
    ABWorld.init3d ( startRadius, maxRadius, skycolor );
    
    const planeGeometry = new THREE.PlaneGeometry(10000, 10000);
    const planeMaterial = new THREE.MeshBasicMaterial({
    map: new THREE.TextureLoader().load('uploads/zak86/ground-terrain-gravel-pbr-texture-02.jpg')
    });
    const plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.position.set(-150, -150, -150);


    // Rotate the floor so that it lies flat on the ground
    plane.rotateX(-Math.PI / 2);
    plane.rotateZ(-Math.PI / 2);


    ABWorld.scene.add(plane);


    // add the object to the scene:
    playerOne = new Player("Playerone");
    playerOne.model.position.set(0, 0, 1000)
    ABWorld.scene.add(playerOne.model);
    playerTwo = new Player("PlayerTwo");
    playerTwo.model.position.set(0, 0, -1000);
    ABWorld.scene.add(playerTwo.model);
    
    

};

AB.world.nextStep = function() {
    
    
    if (playerArray.length >= 2) {
        AB.removeLoading();
    }
    
    document.onkeydown = keyHandler;
    
    if (playerOne.lives === 0 || playerTwo.lives === 0) {
        AB.runReady = false;
        AB.newSplash();
        var splashScreenButton = document.getElementById('splashbutton');
        if (playerOne.lives === 0) {
            splashScreenButton.innerHTML = "Player Two wins! Click to reload."
        }
        else {
            splashScreenButton.innerHTML = "Player One wins! Click to reload."
        }
        
        splashScreenButton.addEventListener('click', onSplashScreenButtonClick);
    }
}
// get a reference to the splash screen button

function onSplashScreenButtonClick() {
    // reload the page when the splash screen button is clicked
    window.location.reload();
}


// socket functionality

AB.socketStart();

AB.socketIn = function(data) {
    switch(data) {
        case 'left':
            playerOne.movePlayer('left');
            break;
        case 'left2':
            playerTwo.movePlayer('left');
            break;
        case 'right':
            playerOne.movePlayer('right');
            break;
        case 'right2':
            playerTwo.movePlayer('right');
            break;
        case 'up':
            playerOne.movePlayer('up');
            break;
        case 'up2':
            playerTwo.movePlayer('up');
            break;
        case 'down':
            playerOne.movePlayer('down');
            break;
        case 'down2':
            playerTwo.movePlayer('down');
            break;
        case 'shoot':
            playerOne.shoot();
            break;
        case 'shoot2':
            playerTwo.shoot();
            break;
    }
}


AB.socketUserlist = function (a) {
    for (i = 0; i < a.length; i++) {
        console.log(a[i][0] + " has joined.");
        if (playerArray.indexOf(a[i][0]) === -1) {
           playerArray.push(a[i][0]); 
        }
        
    }
    console.log(playerArray);
}