ABWorld;
AB.clockTick =100;
AB.maxSteps =10000;
AB.screenshotStep =50;
AB.drawRunControls =true;// default AB paramtersconst show3d =true;const OBJPATH ="/uploads/linr2/";const PLAYER1OBJ ="Quigon.obj";const PLAYER1MTL ="Quigon.mtl";const WALLOBJ ="farm_type_wall.obj";const WALLMTL ="farm_type_wall.mtl";const WALL_TEXTURE ='/uploads/linr2/farm_type_wall_wall_Height.png';// constants for uploadsvar cam;var meshFloor;var keyboard ={};var updatedPosX;var updatedPosZ;var play;var player ={ height:2, speed:0.3, turnSpeed:0.09};var playerspeed=0;var scene =new THREE.Scene();var sky_texture =new THREE.TextureLoader().load('uploads/linr2/milky.jpg');
scene.background = sky_texture;var startTime = performance.now();var renderer =new THREE.WebGLRenderer();//inialise WEBGL
startTime=performance.now();// begins timing the uservar wall_texture;function render(){
renderer.setSize(window.innerWidth, window.innerHeight);// sets how big to render the game in browser window
document.body.appendChild(renderer.domElement);}function camera(){
cam =new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight,0.1,1000);
cam.position.set(0,3.5,-90);// sets camera positioning (x,y,z)
cam.lookAt(scene.position);}function create_player(){
THREE.DefaultLoadingManager.addHandler (/\.tga$/i,new THREE.TGALoader());var m =new THREE.MTLLoader();
m.setResourcePath ( OBJPATH );
m.setPath ( OBJPATH );
m.load ( PLAYER1MTL,function( materials ){
materials.preload();var o =new THREE.OBJLoader();// imports the player uploaded to AB,
o.setMaterials ( materials );// credit to tomi210 here: https://free3d.com/3d-model/lego-qui-gon-18960.html
o.setPath ( OBJPATH );
o.load ( PLAYER1OBJ,function( object ){
play = object;
play.scale.multiplyScalar(0.05);// sets the scale and location of where to place player model
play.position.set(0,player.height,-160);
scene.add(play);});});}function loadtextures(){var loader2 =new THREE.TextureLoader();
loader2.load ( WALL_TEXTURE,function( thetexture ){// loads textures of the wall
thetexture.minFilter = THREE.LinearFilter;
wall_texture = thetexture;});}function generateWall(){
THREE.DefaultLoadingManager.addHandler (/\.tga$/i,new THREE.TGALoader());var m =new THREE.MTLLoader();
m.setResourcePath ( OBJPATH );
m.setPath ( OBJPATH );
m.load ( WALLMTL,function( materials ){
materials.preload();var o =new THREE.OBJLoader();
o.setMaterials ( materials );// generates the wall obstacles using a 3D model
o.setPath ( OBJPATH );// Credit to g3ordie, link here : https://free3d.com/3d-model/farm-type-wall-and-gate-47186.html
o.load ( WALLOBJ,function( object ){Wall= object;Wall.scale.multiplyScalar(0.1);Wall.position.set(-10,0,100);
scene.add(Wall);});});
m.load ( WALLMTL,function( materials ){
materials.preload();var o =new THREE.OBJLoader();
o.setMaterials ( materials );
o.setPath ( OBJPATH );
o.load ( WALLOBJ,function( object ){Wall2= object;Wall2.scale.multiplyScalar(0.1);Wall2.position.set(10,0,50);Wall2.rotation.y =330;
scene.add(Wall2);});});
m.load ( WALLMTL,function( materials ){
materials.preload();var o =new THREE.OBJLoader();
o.setMaterials ( materials );
o.setPath ( OBJPATH );
o.load ( WALLOBJ,function( object ){Wall3= object;Wall3.scale.multiplyScalar(0.1);Wall3.position.set(-10,0,30);Wall3.rotation.y =0;
scene.add(Wall3);});});
m.load ( WALLMTL,function( materials ){
materials.preload();var o =new THREE.OBJLoader();
o.setMaterials ( materials );
o.setPath ( OBJPATH );
o.load ( WALLOBJ,function( object ){Wall4= object;Wall4.scale.multiplyScalar(0.15);Wall4.position.set(10,0,-15);Wall4.rotation.y =330;
scene.add(Wall4);});});
m.load ( WALLMTL,function( materials ){
materials.preload();var o =new THREE.OBJLoader();
o.setMaterials ( materials );
o.setPath ( OBJPATH );
o.load ( WALLOBJ,function( object ){Wall5= object;Wall5.scale.multiplyScalar(0.1);Wall5.position.set(-10,0,-60);Wall5.rotation.y =0;
scene.add(Wall5);var light =new THREE.DirectionalLight("#3fe293",5);
light.position.set(0,10,-180);
scene.add( light );});});
m.load ( WALLMTL,function( materials ){
materials.preload();var o =new THREE.OBJLoader();
o.setMaterials ( materials );
o.setPath ( OBJPATH );
o.load ( WALLOBJ,function( object ){Wall6= object;Wall6.scale.multiplyScalar(0.1);Wall6.position.set(10,0,-125);Wall6.rotation.y =330;
scene.add(Wall6);});});}function collisionCheck(){var firstObject = play;var secondObject =Wall;var thirdObject =Wall2;var fourthObject =Wall3;var fifthObject =Wall4;var sixthObject =Wall5;var seventhObject =Wall6;
firstBB =new THREE.Box3().setFromObject(firstObject,true);
secondBB =new THREE.Box3().setFromObject(secondObject,true);
thirdBB =new THREE.Box3().setFromObject(thirdObject,true);
fourthBB =new THREE.Box3().setFromObject(fourthObject,true);
fifthBB =new THREE.Box3().setFromObject(fifthObject,true);
sixthBB =new THREE.Box3().setFromObject(sixthObject,true);
seventBB =new THREE.Box3().setFromObject(seventhObject,true);//collision check using boundingBox on each wall and checking if their rays intersectvar collision = secondBB.intersectsBox(firstBB);
collision = fourthBB.intersectsBox(firstBB);
collision = fifthBB.intersectsBox(firstBB);
collision = sixthBB.intersectsBox(firstBB);
collision = seventBB.intersectsBox(firstBB);if(collision){
play.position.set(0,player.height,-160);
collision =false;}}function floor(){var texture =new THREE.TextureLoader().load('uploads/linr2/ground.jpeg');
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.offset.set(2,2);
texture.repeat.set(10,10);// loads in the jpeg image as floor texture and repeats it so it isn't stretched.
meshFloor =new THREE.Mesh(new THREE.PlaneGeometry(100,400),// creates a plane/floor of 100x400new THREE.MeshBasicMaterial({map:texture}));
meshFloor.rotation.x -=Math.PI /2;// rotates floor so it's not vertical
scene.add(meshFloor);}function checkLocation(){if(play.position.z >=160){const e=Math.floor((performance.now()-startTime)/1e3);// checks for position of the player, if passes the point of the finish line
AB.newSplash()// sends out time to socketout and calls the game to be over.
AB.splashHtml(`<h1>It took you ${e} seconds to reach the end!</h1>`)
AB.socketOut({
data :{
time: e,}})
AB.socket.destroy();GameOver();}}functionAddFinishLine(){var finishL =new THREE.BoxGeometry(100,70,25);varFinishLine=new THREE.Mesh( finishL );FinishLine.material.color.setHex(0xff2d00);// adds finish line mesh that can be clearly seenFinishLine.position.x =0;FinishLine.position.z =180;FinishLine.position.y =0;
scene.add(FinishLine);var light =new THREE.DirectionalLight("#7fe093",4);
light.position.set(0,1,0);
scene.add( light );}function movement(){
requestAnimationFrame(movement);if(keyboard[87]|| keyboard[38]){// W or up arrow key in order to move forward and to update the position of the player amplified by the player speedif(play.position.x<=180&& play.position.x>=-180){
play.position.x -=Math.sin(play.rotation.y)* player.speed/1.5;
play.position.z -=-Math.cos(play.rotation.y)* player.speed/1.5;
collisionCheck();// sends the user position to be checked for collisions}else{
play.position.x +=Math.sin(play.rotation.y)* player.speed/1.5;
collisionCheck();}if(play.position.z<=180&& play.position.z>=-180){
play.position.x -=Math.sin(play.rotation.y)* player.speed/1.5;
play.position.z -=-Math.cos(play.rotation.y)* player.speed/1.5;
collisionCheck();}else{
play.position.z +=-Math.cos(play.rotation.y)* player.speed/1.5;
collisionCheck();}
playerspeed++;
checkLocation();
collisionCheck();}if(keyboard[83]|| keyboard[40]){// S or down arrow key, same as above but with Sif(play.position.x<=160&& play.position.x>=-160){
play.position.x +=Math.sin(play.rotation.y)* player.speed/1.5;
play.position.z +=-Math.cos(play.rotation.y)* player.speed/1.5;
collisionCheck();}else{
play.position.x -=Math.sin(play.rotation.y)* player.speed/1.5;}if(play.position.z<=200&& play.position.z>=-160){
play.position.x +=Math.sin(play.rotation.y)* player.speed/1.5;
play.position.z +=-Math.cos(play.rotation.y)* player.speed/1.5;
collisionCheck();}else{
play.position.z -=-Math.cos(play.rotation.y)* player.speed/1.5;
collisionCheck();}
playerspeed++;
checkLocation();
collisionCheck();}if(keyboard[65]|| keyboard[37]){// A or left arrow key, same as above however if player goes too far left off the platform, teleports them back to middle.if(play.position.x <=50&& play.position.x >=-50)// introduces horizonal movement to the left{
play.position.x +=Math.sin(play.rotation.y +Math.PI/2)* player.speed/1.5;
play.position.z +=-Math.cos(play.rotation.y +Math.PI/2)* player.speed/1.5;
collisionCheck();}else{
play.position.x =Math.sin(play.rotation.y -Math.PI/2)* player.speed/1.5;
collisionCheck();}if(play.position.z <=200&& play.position.z >=-200){
play.position.x +=Math.sin(play.rotation.y +Math.PI/2)* player.speed/1.5;
play.position.z +=-Math.cos(play.rotation.y +Math.PI/2)* player.speed;
collisionCheck();}else{
play.position.z =-Math.cos(play.rotation.y -Math.PI/2)* player.speed/1.5;
collisionCheck();}
playerspeed++;
checkLocation();// collision check and finish line check
collisionCheck();}if(keyboard[68]|| keyboard[39]){// D or right arrow key, same as A key and but checks for right horizonal movementif(play.position.x<=50&& play.position.x>=-50){// teleports user back to middle if too far right.
play.position.x +=Math.sin(play.rotation.y -Math.PI/2)* player.speed/1.5;
play.position.z +=-Math.cos(play.rotation.y -Math.PI/2)* player.speed/1.5;
collisionCheck();}else{
play.position.x =Math.sin(play.rotation.y +Math.PI/2)* player.speed/1.5;
collisionCheck();}if(play.position.z<=200&& play.position.z>=-200){
play.position.x +=Math.sin(play.rotation.y -Math.PI/2)* player.speed/1.5;
play.position.z +=-Math.cos(play.rotation.y -Math.PI/2)* player.speed;
collisionCheck();}else{
play.position.z =-Math.cos(play.rotation.y +Math.PI/2)* player.speed/1.5;
collisionCheck();}
playerspeed++;
checkLocation();
collisionCheck();}
cam.position.x = play.position.x ;
cam.position.z = play.position.z -5;
cam.position.y =4;
renderer.render(scene, cam);}function keyDown(event){
keyboard[event.keyCode]=true;}function keyUp(event){
keyboard[event.keyCode]=false;}
window.addEventListener('keydown', keyDown);// checks for if key is held down or lifted up in order to implement smooth movement
window.addEventListener('keyup', keyUp);
AB.world.newRun =function(){
AB.socketStart();
loadtextures();
render();
create_player();
camera();
floor();AddFinishLine();
generateWall();
movement();
AB.showRunHeader();
welcome();};function welcome(){
AB.newSplash();// Welcome screen for all users, introducing game and controls.
AB.runReady =false
AB.splashHtml (`<h1>Welcome to 3DPlatformer!</h1>TheGoal is to reach the Finish line in the fastest time.<br>Press WASD to move,If you touch any of the obstacles you get reset to the beginning (not working)!<p><button onclick='AB.removeSplash();'class=ab-largenormbutton >Start</button><p>`)}
AB.socketIn =function(element){
AB.newSplash();// socket to receive information, if information is received, it means player reached finish line
AB.splashHtml (`<h1>GameOver!<h1><p>Other player finished in:`+ element.data.time +` seconds.</p>`);if(playonce !=1){var congrats =newAudio("/uploads/linr2/congratulations.mp3");
backgroundM.volume =0;
congrats.volume =0.04;
congrats.play();
playonce +=1;Object.freeze(play);}}var playonce =0;// variable to make sure congratulation sound is only played once.functionGameOver(){if(playonce !=1){// gameover function to play sound and mute background musicvar congrats =newAudio("/uploads/linr2/congratulations.mp3");
backgroundM.volume =0;
congrats.volume =0.04;
congrats.play();
playonce +=1;Object.freeze(play);}}
welcome();var backgroundM =newAudio("/uploads/linr2/background.mp3");
backgroundM.volume =0.025;
backgroundM.play();