// Cloned by Zak Smith on 5 Dec 2022 from World "3D Shooter" by Senan Warnock
// Please leave this clone trail here.
/*
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.
Collision detection so players cannot run through each other, and
we can check if a player is hit by an opponents bullet, then update the scores and lives.
*/
const skycolor = 'black';
const boxcolor = 'maroon';
const objectsize = 300; // size of object
const startRadius = 1000; // 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();
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 = () => {
bullet.position.z -= bulletSpeed;
requestAnimationFrame(animateBullet);
};
animateBullet();
}
}
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');
}
}
// 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 );
// floor
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");
ABWorld.scene.add(playerOne.model);
playerTwo = new Player("PlayerTwo");
ABWorld.scene.add(playerTwo.model);
};
AB.world.nextStep = function() {
if (playerArray.length >= 2) {
AB.removeLoading();
}
document.onkeydown = keyHandler;
}
// 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);
}