// Cloned by Liam on 29 Nov 2022 from World "First Person Controls (clone by David L)" by David L
// Please leave this clone trail here.
// Customise AB run parameters (optional).
// The following parameters can be customised. (They have default values.)
AB.clockTick = 1; // Speed of run: Step every n milliseconds. Default 100.
AB.maxSteps = 65545; // Length of run: Maximum length of run in steps. Default 1000.
AB.screenshotStep = 50;
AB.drawRunControls = false;
threeworld.drawCameraControls = false;
const floorTextureFile = "/uploads/goobert/grass2.png" // const floorTextureFile = "/uploads/mathias/grass.jpg"
var MOVESPEED = 3;
var GRAVITY = 15;
var FogDistance = 3000;
var FOV = 120;
// Defines the THREE.PointerLockControls class, source at https://threejs.org/
THREE.PointerLockControls = function ( camera ) {
var scope = this;
// camera.rotation.set( 0, 0, 0 );
var pitchObject = new THREE.Object3D();
pitchObject.add( camera );
var yawObject = new THREE.Object3D();
yawObject.position.y = 10;
yawObject.add( pitchObject );
var PI_2 = Math.PI / 2;
var onMouseMove = function ( event ) {
if ( scope.enabled === false ) return;
var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
yawObject.rotation.y -= movementX * 0.002;
pitchObject.rotation.x -= movementY * 0.002;
// pitchObject.rotation.x = Math.max( - PI_2, Math.min( PI_2, pitchObject.rotation.x ) );
};
this.dispose = function () {
document.removeEventListener( 'mousemove', onMouseMove, false );
};
document.addEventListener( 'mousemove', onMouseMove, false );
this.enabled = false;
this.getObject = function () {
return yawObject;
};
this.getDirection = function () {
// assumes the camera itself is not rotated
var direction = new THREE.Vector3( 0, 0, 0 );
var rotation = new THREE.Euler( 0, 0, 0 );
// return function ( v ) {
// rotation.set( pitchObject.rotation.x, yawObject.rotation.y, 0 );
// v.copy( direction ).applyEuler( rotation );
// return v;
// };
}();
};
//==============================================================================
function loadResources() // asynchronous file loads - call initScene() when all finished
{
// load skeleton - OBJ that we will paint with a texture
var loader = new THREE.OBJLoader ( new THREE.LoadingManager() );
loader.load ( OBJ_SKELETON, function ( object )
{
theenemy = object; // canonical enemy object - may be copied multiple times
if ( asynchFinished() ) initScene();
});
THREE.DefaultLoadingManager.addHandler ( /\.tga$/i, new THREE.TGALoader() );
var m = new THREE.MTLLoader();
m.setResourcePath ( OBJPATH );
m.setPath ( OBJPATH );
m.load ( MTLNAME, function ( materials )
{
materials.preload();
var o = new THREE.OBJLoader();
o.setMaterials ( materials );
o.setPath ( OBJPATH );
o.load ( OBJNAME, function ( object )
{
theagent = object;
if ( asynchFinished() ) initScene();
});
});
// load textures
var loader2 = new THREE.TextureLoader();
loader2.load ( TEXTURE_SKELETON, function ( thetexture )
{
thetexture.minFilter = THREE.LinearFilter;
skeleton_texture = thetexture;
if ( asynchFinished() ) initScene();
});
}
function asynchFinished() // all file loads returned
{
if ( skeleton_texture && theenemy && theagent ) return true;
else return false;
}
function initScene() // all file loads have returned
{
// add agent model
// start at center
theagent.position.y = 0;
theagent.position.x = 0;
theagent.position.z = 0;
theagent.scale.multiplyScalar ( SCALE_HERO ); // scale it
ABWorld.scene.add( theagent );
// set up lookat and follow in direction agent is pointing in
setLookatFollow();
// add enemies
// first paint and size the canonical enemy object
theenemy.traverse ( function ( child )
{
if ( child instanceof THREE.Mesh )
child.material.map = skeleton_texture ;
});
theenemy.scale.multiplyScalar ( SCALE_SKELETON ); // scale it
// add perhaps multiple enemy models, starting near outside of arena
for ( var i = 0; i < NO_SKELETONS ; i++ )
{
var object = theenemy.clone(); // copy the object multiple times
object.position.y = 0;
object.position.x = AB.randomPick ( AB.randomIntAtoB ( -MAXPOS/2, -MAXPOS/3 ), AB.randomIntAtoB ( MAXPOS/3, MAXPOS/2 ) );
object.position.z = AB.randomPick ( AB.randomIntAtoB ( -MAXPOS/2, -MAXPOS/3 ), AB.randomIntAtoB ( MAXPOS/3, MAXPOS/2 ) );
ABWorld.scene.add( object );
// save in array for later
THESKELETONS[i] = object;
}
}
const zombiePOS = new THREE.Vector3 ( 12, 0, 0);
// const buuPosition = new THREE.Vector3 ( 9, 0, 6 );
// can load 3D models of other user:
loader.load ( '/uploads/goobert/zombie.glb', gltf => onLoad ( gltf, zombiePOS ) );
// loader.load ( '/uploads/chris/kid_buu.glb', gltf => onLoad ( gltf, buuPosition ) );
function loadStayModels(){
const Sloader = new THREE.GLTFLoader();
const SonLoad = ( gltf, Sposition ) => {
const Smodel = gltf.scene.children[ 0 ];
Smodel.position.copy( Sposition );
ABWorld.scene.add( Smodel );
};
const zombiePOS = new THREE.Vector3 ( 12, 0, 0);
// const brolyPosition = new THREE.Vector3 ( 0, 1, -8 );
// const smallgokuPosition = new THREE.Vector3(-4, 5, -16);
// const dragonPosition = new THREE.Vector3( 0, 0, 0 );
// const androidPosition = new THREE.Vector3 ( -3, 0, 10 );
Sloader.load ( '/uploads/goobert/zombie.glb', gltf => SonLoad ( gltf, zombiePOS ) );
// Sloader.load ( '/uploads/chris/bulma_-_dragon_ball.glb', gltf => SonLoad ( gltf, brolyPosition ) );
// Sloader.load ( '/uploads/chris/son_goku_and_kintoun_nimbus.glb', gltf => SonLoad ( gltf, smallgokuPosition ) );
// Sloader.load ( '/uploads/chris/kame_house.glb', gltf => SonLoad ( gltf, dragonPosition ) );
// Sloader.load ( '/uploads/chris/dragon_ball_z_-_android_18.glb', gltf => SonLoad ( gltf, androidPosition ) );
}
function World() {
var camera, controls;
var objects = [];
var raycaster;
var moveForward = false;
var moveBackward = false;
var moveLeft = false;
var moveRight = false;
var canJump = false;
var prevTime = performance.now();
var velocity = new THREE.Vector3();
var direction = new THREE.Vector3();
var vertex = new THREE.Vector3();
var color = new THREE.Color();
this.newRun = function()
{
// loadModels();
// loadStayModels();
// this handles key presses
var onKeyDown = function ( event ) {
switch ( event.keyCode ) {
case 38: // up
case 87: // w
moveForward = true;
break;
case 38: // up
case 16: // shift
MOVESPEED = 5; //
break;
// case 38: // up
case 80: // P
FOV = 500;
break;
case 37: // left
case 65: // a
moveLeft = true; break;
case 40: // down
case 83: // s
moveBackward = true;
break;
case 39: // right
case 68: // d
moveRight = true;
break;
case 32: // space
if ( canJump === true ) velocity.y += 350;
canJump = false;
break;
}
};
var onKeyUp = function ( event ) {
switch( event.keyCode ) {
case 38: // up
case 87: // w
moveForward = false;
break;
case 38: // up
case 16: // shift
MOVESPEED = 10; //
break;
case 37: // left
case 65: // a
moveLeft = false;
break;
case 40: // down
case 83: // s
moveBackward = false;
break;
case 39: // right
case 68: // d
moveRight = false;
break;
}
};
camera = new THREE.PerspectiveCamera( FOV );
threeworld.camera = camera;
threeworld.init3d ( 0,0, 0x7ec0ee );
var light = new THREE.HemisphereLight( 0xeeeeff, 0x777788, 0.75 );
light.position.set( 0.5, 1, 0.75 );
threeworld.scene.add( light );
threeworld.scene.fog = new THREE.Fog( 0xffffff, 0, FogDistance );
controls = new THREE.PointerLockControls( camera );
threeworld.scene.add( controls.getObject() );
// event listener for key presses
document.addEventListener( 'keyup', onKeyUp, false );
document.addEventListener( 'keydown', onKeyDown, false );
raycaster = new THREE.Raycaster( new THREE.Vector3(), new THREE.Vector3( 0, - 1, 0 ), 0, 10 );
$("#user_span1").html("Use <b>WASD</b> or <b>Arrows</b> to move and <b>shift</b> to run any direction.");
// var blocker = $("#user_span2");
$("#user_span2").html("<p><b>Click screen to enable mouse controls</b></p>");
//The following handles pointer locking when clicking the window
// handles the pointer locking (game return feature) when clicking back onto the game.
var havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document;
console.log(havePointerLock);
if ( havePointerLock ) {
var element = document.body;
var pointerlockchange = function ( event ) {
if ( document.pointerLockElement === element || document.mozPointerLockElement === element || document.webkitPointerLockElement === element ) {
controls.enabled = true;
$("#user_span2").html("");
} else
{
controls.enabled = false;
$("#user_span2").html("<p><b>Click onto the game to return playing.</b></p>");
}
};
var pointerlockerror = function ( event ) {
console.error("pointerlockerror");
};
// Hook pointer lock state change events
document.addEventListener( 'pointerlockchange', pointerlockchange, false );
document.addEventListener( 'mozpointerlockchange', pointerlockchange, false );
document.addEventListener( 'webkitpointerlockchange', pointerlockchange, false );
document.addEventListener( 'pointerlockerror', pointerlockerror, false );
document.addEventListener( 'mozpointerlockerror', pointerlockerror, false );
document.addEventListener( 'webkitpointerlockerror', pointerlockerror, false );
document.addEventListener( 'click', function ( event ) {
// Ask the browser to lock the pointer
element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock;
element.requestPointerLock();
}, false );
} else {
$("#user_span1").html('<p>Your browser doesn\'t seem to support Pointer Lock API</p>');
}
//The following draws a simple scene
//floor
var WorldSize = 20000;
var BlockSize = 50;
var floorGeometry = new THREE.PlaneBufferGeometry( WorldSize, WorldSize );
floorGeometry.rotateX( - Math.PI / 2 );
// loading the floor texture
var floorTexture = new THREE.ImageUtils.loadTexture ( floorTextureFile );
floorTexture.minFilter = THREE.LinearFilter;
floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
// world floor texture size and location
floorTexture.offset.set( 0, 0 );
floorTexture.repeat.set( WorldSize / BlockSize, WorldSize / BlockSize );
var floor = new THREE.Mesh(floorGeometry, new THREE.MeshBasicMaterial({map : floorTexture}));
floor.position.set(0,-20,0);
threeworld.scene.add(floor);
};
this.nextStep = function()
{
//======================================================================
//This will handle moving the player and the camera
//======================================================================
raycaster.ray.origin.copy( controls.getObject().position );
raycaster.ray.origin.y -= 10;
var intersections = raycaster.intersectObjects( objects );
var onObject = intersections.length > 0;
var time = performance.now();
var delta = ( time - prevTime ) / 1000;
velocity.x -= velocity.x * 10.0 * delta;
velocity.z -= velocity.z * 10.0 * delta;
velocity.y -= GRAVITY;
direction.z = Number( moveForward ) - Number( moveBackward );
direction.x = Number( moveLeft ) - Number( moveRight );
direction.normalize(); // this ensures consistent movements in all directions
if ( moveForward || moveBackward ) velocity.z -= direction.z * 400.0 * MOVESPEED * delta;
if ( moveLeft || moveRight ) velocity.x -= direction.x * 400.0 * MOVESPEED * delta;
if ( onObject === true ) {
velocity.y = Math.max( 0, velocity.y );
canJump = true;
}
controls.getObject().translateX( velocity.x * delta );
controls.getObject().translateY( velocity.y * delta );
controls.getObject().translateZ( velocity.z * delta );
if ( controls.getObject().position.y < 10 ) {
velocity.y = 0;
controls.getObject().position.y = 10;
canJump = true;
}
prevTime = time;
};
}