// Cloned by Fionn Gallahar Hall on 5 Dec 2022 from World "Websockets boxes lab (clone by Okikiola Sanni)" by Okikiola Sanni // Please leave this clone trail here.// Cloned by Okikiola Sanni on 13 Nov 2022 from World "Websockets boxes" by Starter user // Please leave this clone trail here.
AB.clockTick =100;// Speed of run: Step every n milliseconds. Default 100.
AB.maxSteps =1000;// Length of run: Maximum length of run in steps. Default 1000.
AB.screenshotStep =100;// Take screenshot on this step. (All resources should have finished loading.) Default 50.const MUSIC_BACK ="/uploads/kikisanni/arcade.mp3"const FILE_ARRAY =["/uploads/kikisanni/white.png",// array 1-5 are default boxes "/uploads/kikisanni/white.png","/uploads/kikisanni/white.png","/uploads/kikisanni/white.png","/uploads/kikisanni/white.png","/uploads/kikisanni/red.jpg","/uploads/kikisanni/yellow.jpeg","/uploads/kikisanni/blue.png","/uploads/kikisanni/green.png",];const SKYBOX_ARRAY =["/uploads/kikisanni/flame_bk.jpg","/uploads/kikisanni/flame_ft.jpg","/uploads/kikisanni/flame_up.jpg","/uploads/kikisanni/flame_dn.jpg","/uploads/kikisanni/flame_lf.jpg","/uploads/kikisanni/flame_rt.jpg"];var timer =new THREE.Clock();const SKYCOLOR =0xd3d3d3;const ARMYSIZE =100;// an "army" of objects const objectsize =500;const WALKSTEP =100;// bounds of the random move per timestep // try 50 (vibrating sheet) versus 1000 (cloud)const MAXPOS =4000;// start things within these bounds const startRadiusConst = MAXPOS *1.5;// distance from centre to start the camera atconst maxRadiusConst = MAXPOS *5;// maximum distance from camera we will render things ABHandler.MAXCAMERAPOS = MAXPOS *10;// allow camera go far away ABWorld.drawCameraControls =false;
AB.drawRunControls =false;var THEARMY =newArray( ARMYSIZE );var textureArray =newArray( FILE_ARRAY.length );function initLights(){const ambientLight =new THREE.AmbientLight(0xffffff,1);ABWorld.scene.add( ambientLight );const frontLight =new THREE.DirectionalLight(0xffffff,1);
frontLight.position.set(10,10,10);const backLight =new THREE.DirectionalLight(0xffffff,1);
backLight.position.set(-10,10,-10);ABWorld.scene.add( frontLight, backLight );}function loadResources()// asynchronous file loads - call initScene() when all finished {for(var i =0; i < FILE_ARRAY.length; i++)
startFileLoad ( i );// launch n asynchronous file loads}function startFileLoad ( n )// asynchronous file load of texture n {var loader =new THREE.TextureLoader();
loader.load ( FILE_ARRAY[n],function( thetexture ){
thetexture.minFilter = THREE.LinearFilter;
textureArray[n]= thetexture;if( asynchFinished()) initScene();});}function asynchFinished()// all file loads returned {for(var i =0; i < FILE_ARRAY.length; i++)if(! textureArray[i])returnfalse;returntrue;}function initArmy()// called when all textures ready {var t =0;for(var c=1; c <= ARMYSIZE ; c++){// var shape = new THREE.SphereGeometry ( objectsize, 30, 30 ); var shape =new THREE.BoxGeometry( objectsize, objectsize, objectsize );var theobject =new THREE.Mesh( shape );
theobject.position.x = AB.randomIntAtoB (-MAXPOS, MAXPOS );
theobject.position.z = AB.randomIntAtoB (-MAXPOS, MAXPOS );
theobject.position.y =0;// var r = AB.randomIntAtoB ( 0, textureArray.length - 1 ); // random texture var r = AB.randomIntAtoB (0,4);// random one of the earths
theobject.material =new THREE.MeshBasicMaterial({ map: textureArray[r]});ABWorld.scene.add(theobject);
THEARMY[t]= theobject;// save it for later
t++;}ABWorld.render();
AB.removeLoading();
AB.runReady =true;
let listElement = document.createElement("li");
listElement.innerHTML
AB.msg (" <hr> <p> Colour Rush. Each user will pick a colour. Spam your button to change the boxes to your colour, most boxes filled wins.</hr> <p>"+" <button onclick='red();' class=ab-largenormbutton > Red </button> <p>"+"<button onclick='yellow();' class=ab-largenormbutton > Yellow </button><p>"+"<button onclick='blue();' class=ab-largenormbutton > Blue </button><p>"+"<button onclick='green();' class=ab-largenormbutton > Green </button><p>"+"<br> Timer: "+Math.round(timer.getElapsedTime())+"<h1> Chat Opponent </h1>"+"If you are logged in, chat is tagged with your name."+"<div style=width:60vw; background-color:#add8e6; border: 1px solid black; margin:5; padding: 10px>"+"<h3> Me </h3>"+"<INPUT style=width:15vw; id=me>"+"<button onclick=sendchat(); class=ab-normbutton > Send </button>"+"</div>"+"<div style=width:60vw; background-color:darkgrey; border: 1px solid black; margin:5; padding: 10px;>"+"<h3> Them </h3>"+"<div id=them > </div>"+"</div>"+"<div style=width:60vw; background-color:blue; border: 1px solid black; margin:5; padding: 10px;>"+"<h3> Players online </h3>"+"<div id=themlist > </div>"+"</div>");}function startClock(){
timer.start();}function stopClock(){
timer.stop();}function initScene(){
initArmy();ABWorld.scene.background =new THREE.CubeTextureLoader().load ( SKYBOX_ARRAY,function(){ABWorld.render();
AB.removeLoading();
AB.runReady =true;});}function moveArmy()// move all the objects {for(var i =0; i < THEARMY.length; i++){if( THEARMY[i])// in case initArmy() not called yet {
THEARMY[i].position.x = THEARMY[i].position.x + AB.randomIntAtoB(-WALKSTEP,WALKSTEP);
THEARMY[i].position.z = THEARMY[i].position.z + AB.randomIntAtoB(-WALKSTEP,WALKSTEP);
THEARMY[i].position.y = THEARMY[i].position.y + AB.randomIntAtoB(-WALKSTEP,WALKSTEP);ABWorld.scene.add( THEARMY[i]);}}}
AB.world.newRun =function(){
AB.loadingScreen();
AB.runReady =false;ABWorld.init3d ( startRadiusConst, maxRadiusConst, SKYCOLOR );
loadResources();// aynch file loads
initLights();};
AB.world.nextStep =function(){
moveArmy();};//--- Socket functionality -----------------------------------------------------// start socket
AB.socketStart();// functions called by buttonsfunction red(){ changeBox(5); AB.socketOut (5);}function yellow(){ changeBox(6); AB.socketOut (6);}function blue(){ changeBox(7); AB.socketOut (7);}function green(){ changeBox(8); AB.socketOut (8);}function changeBox(n)// change a random box to texture n {var i = AB.randomIntAtoB (0, THEARMY.length -1);// pick a random box to change
THEARMY[i].material =new THREE.MeshBasicMaterial({ map: textureArray[n]});}// --- music ----------------------------------------var backmusic = AB.backgroundMusic ( MUSIC_BACK );function musicPlay(){ backmusic.play();}function musicPause(){ backmusic.pause();}// // --- Send my line of text to server --------------function sendchat(){var theline = $("#me").val();var data ={
userid: AB.myuserid,
username: AB.myusername,
line: theline
};
AB.socketOut ( data );// server gets this, and sends the data to all clients running this World}function userlink ( userid, username ){if( userid =="none")return("Anon user");elsereturn("<a target='_blank' href='https://ancientbrain.com/user.php?userid="+ userid +"'>"+ username +"</a>");}
AB.socketIn =function(n)// incoming data from other users {
changeBox(n);};
AB.socketIn =function(data){var userhtml = userlink ( data.userid, data.username );
$("#them").html ( userhtml +": "+ data.line );};// // At startup, and when list of users changes, server will trigger AB.socketUserlist. // // Here I define what to do for it.
AB.socketUserlist =function( a ){
console.log ("Got user list: ");
console.log ( JSON.stringify ( a,null,' '));if( a.length <2){
$("#themlist").html ("<h3 style='color:red'> You are alone. Get someone else to run this World. </h3>");return;}// else var str =" <ol> ";for(var i =0; i < a.length; i++){var userhtml = userlink ( a[i][0], a[i][1]);
str = str +" <li> "+ userhtml ;}
$("#themlist").html ( str +" </ol> ");};