// Cloned by Dave on 19 Nov 2022 from World "Websockets boxes" by Starter user // Please leave this clone trail here.// ==== Starter World =================================================================================================// This code is designed for use on the Ancient Brain site.// This code may be freely copied and edited by anyone on the Ancient Brain site.// To include a working run of this program on another site, see the "Embed code" links provided on Ancient Brain.// ====================================================================================================================// Demo of Websockets functionality added to a 3D World// Run with two or more users// Click button to change a random box's texture on all clients running this World// Pick a side and compete against an opponent! // You can annoy the other player by reloading the page!
AB.clockTick =100;// Speed of run: Step every n milliseconds. Default 100.
AB.maxSteps =100000;// 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 FILE_ARRAY =["/uploads/1663672411.png",// array 0 to 4 are the earths "/uploads/starter/earth.2.jpg","/uploads/starter/earth.3.jpg","/uploads/starter/earth.4.jpg","/uploads/starter/earth.5.jpg","/uploads/starter/baby.1.png",// array 5"/uploads/starter/ghost.3.png"// array 6 ];const SKYCOLOR =0xccffcc;// a number, not a string const ARMYSIZE =50;// an "army" of objects const objectsize =500;const WALKSTEP =200;// 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 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()) initArmy();});}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++;}// can start the run loopABWorld.render();
AB.removeLoading();
AB.runReady =true;
AB.msg (`<hr><p>Multi-user game.Pick a side.Click buttons to change boxes on all users' machines.Drag the camera.<p><button onclick='baby();'class=ab-largenormbutton >Baby</button><button onclick='skull();'class=ab-largenormbutton >Skull</button><p>`);}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 // calls initArmy() when it returns };
AB.world.nextStep =function(){
moveArmy();};//--- Socket functionality -----------------------------------------------------// start socket
AB.socketStart();// functions called by buttons// baby and skull are textures 5 and 6 in the array:function baby(){ changeBox(5); AB.socketOut (5);}function skull(){ changeBox(6); AB.socketOut (6);}function changeBox(n)// change a random box to texture n (5 or 6) {var i = AB.randomIntAtoB (0, THEARMY.length -1);// pick a random box to change
THEARMY[i].material =new THREE.MeshBasicMaterial({ map: textureArray[n]});}
AB.socketIn =function(n)// incoming data on socket, i.e. clicks of other player {if(! AB.runReady )return;
changeBox(n);};