// Cloned by Cian sullivan on 26 Nov 2022 from World "Simple World" 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.
// ====================================================================================================================
// ==========================================================================
// Simple starter World
// 3d-effect World (really a 2-D problem)
//
// Hero = agent = pacman.
// Enemy moves randomly.
// Movement is on an invisible grid of squares
//
// This simple World shows:
// - Texture load from files (asynchronous file reads)
// - Write status to <span> in run window
//
// It also shows functionality that is built-in to every World:
// - Camera control buttons
// - Pause/step run
// ==========================================================================
// =============================================================================================
// Scoring:
// Bad steps = steps where enemy is within one step of agent.
// Good steps = steps where enemy is further away.
// Score = good steps.
// =============================================================================================
// ===================================================================================================================
// === Start of tweaker's box ========================================================================================
// ===================================================================================================================
// The easiest things to modify are in this box.
// You should be able to change things in this box without being a JavaScript programmer.
// Go ahead and change some of these. What's the worst that could happen?
AB.clockTick = 5;
// 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 = 50;
// Take screenshot on this step. (All resources should have finished loading.) Default 50.
//---- global constants: -------------------------------------------------------
const TEXTURE_WALL = '/uploads/ciansullivan1/image_part_001.jpg' ;
const TEXTURE_AGENT = '/uploads/starter/pacman.jpg' ;
// Snake Textures
const TEXTURE_AGENT2 = '/uploads/ciansullivan1/snake.jpg';
const TEXTURE_AGENT3 = '/uploads/ciansullivan1/snake.jpg';
const TEXTURE_AGENT4 ='/uploads/ciansullivan1/snake.jpg';
const TEXTURE_AGENT5 ='/uploads/ciansullivan1/snake.jpg';
const TEXTURE_AGENT6 ='/uploads/ciansullivan1/snake.jpg';
// Ladder Textures
const TEXTURE_LADDER2 = '/uploads/ciansullivan1/ladder.png';
const TEXTURE_LADDER3 = '/uploads/ciansullivan1/ladder.png';
const TEXTURE_LADDER4 ='/uploads/ciansullivan1/ladder.png';
const TEXTURE_LADDER5 ='/uploads/ciansullivan1/ladder.png';
const TEXTURE_LADDER6 ='/uploads/ciansullivan1/ladder.png';
var i = 1;
// credits:
// http://commons.wikimedia.org/wiki/File:Old_door_handles.jpg
// https://commons.wikimedia.org/wiki/Category:Pac-Man_icons
// https://commons.wikimedia.org/wiki/Category:Skull_and_crossbone_icons
const gridsize = 10; // number of squares along side of world
const squaresize = 100; // size of square in pixels
const SKYCOLOR = 0xffffcc; // a number, not a string
const MAXPOS = gridsize * squaresize; // length of one side in pixels
const startRadiusConst = MAXPOS * 0.8 ; // distance from centre to start the camera at
const maxRadiusConst = MAXPOS * 3 ; // maximum distance from camera we will render things
//--- change ABWorld defaults: ----------------------------------------------
ABHandler.GROUNDZERO = true; // "ground" exists at altitude zero
// ===================================================================================================================
// === End of tweaker's box ==========================================================================================
// ===================================================================================================================
// You will need to be some sort of JavaScript programmer to change things below the tweaker's box.
var GRID = new Array(gridsize); // can query GRID about whether squares are occupied, will in fact be initialised as a 2D array
var theagent;
var agent_texture;
var wall_texture;
var agent2_texture, agent3_texture, agent4_texture, agent5_texture, agent6_texture;
var ladder2_texture, ladder3_texture, ladder4_texture, ladder5_texture, ladder6_texture;
// enemy and agent position on squares
var ax, ay;
var badsteps;
var goodsteps;
var randomNum;
function loadResources() // asynchronous file loads - call initScene() when all finished
{
var loader1 = new THREE.TextureLoader();
var loaderAgent = new THREE.TextureLoader();
var loaderAgent2 = new THREE.TextureLoader();
var loaderAgent3 = new THREE.TextureLoader();
var loaderAgent4 = new THREE.TextureLoader();
var loaderAgent5 = new THREE.TextureLoader();
var loaderAgent6 = new THREE.TextureLoader();
var loaderLadder2 = new THREE.TextureLoader();
var loaderLadder3 = new THREE.TextureLoader();
var loaderLadder4 = new THREE.TextureLoader();
var loaderLadder5 = new THREE.TextureLoader();
var loaderLadder6 = new THREE.TextureLoader();
// load walls
loader1.load ( TEXTURE_WALL, function ( thetexture )
{
thetexture.minFilter = THREE.LinearFilter;
wall_texture = thetexture;
if ( asynchFinished() ) initScene();
});
// load agent
loaderAgent.load ( TEXTURE_AGENT, function ( thetexture )
{
thetexture.minFilter = THREE.LinearFilter;
agent_texture = thetexture;
if ( asynchFinished() ) initScene();
});
// load snakes
loaderAgent2.load ( TEXTURE_AGENT2, function ( thetexture )
{
thetexture.minFilter = THREE.LinearFilter;
agent2_texture = thetexture;
if ( asynchFinished() ) initScene();
});
loaderAgent3.load ( TEXTURE_AGENT3, function ( thetexture )
{
thetexture.minFilter = THREE.LinearFilter;
agent3_texture = thetexture;
if ( asynchFinished() ) initScene();
});
loaderAgent4.load ( TEXTURE_AGENT4, function ( thetexture )
{
thetexture.minFilter = THREE.LinearFilter;
agent4_texture = thetexture;
if ( asynchFinished() ) initScene();
});
loaderAgent5.load ( TEXTURE_AGENT5, function ( thetexture )
{
thetexture.minFilter = THREE.LinearFilter;
agent5_texture = thetexture;
if ( asynchFinished() ) initScene();
});
loaderAgent6.load ( TEXTURE_AGENT6, function ( thetexture )
{
thetexture.minFilter = THREE.LinearFilter;
agent6_texture = thetexture;
if ( asynchFinished() ) initScene();
});
// load ladders
loaderLadder2.load ( TEXTURE_LADDER2, function ( thetexture )
{
thetexture.minFilter = THREE.LinearFilter;
ladder2_texture = thetexture;
if ( asynchFinished() ) initScene();
});
loaderLadder3.load ( TEXTURE_LADDER3, function ( thetexture )
{
thetexture.minFilter = THREE.LinearFilter;
ladder3_texture = thetexture;
if ( asynchFinished() ) initScene();
});
loaderLadder4.load ( TEXTURE_LADDER4, function ( thetexture )
{
thetexture.minFilter = THREE.LinearFilter;
ladder4_texture = thetexture;
if ( asynchFinished() ) initScene();
});
loaderLadder5.load ( TEXTURE_LADDER5, function ( thetexture )
{
thetexture.minFilter = THREE.LinearFilter;
ladder5_texture = thetexture;
if ( asynchFinished() ) initScene();
});
loaderLadder6.load ( TEXTURE_LADDER6, function ( thetexture )
{
thetexture.minFilter = THREE.LinearFilter;
ladder6_texture = thetexture;
if ( asynchFinished() ) initScene();
});
}
function asynchFinished()
{
if ( wall_texture && agent_texture ) return true;
///if ( agent_texture ) return true;
else return false;
}
//--- grid system -------------------------------------------------------------------------------
// my numbering is 0 to gridsize-1
function snakeSquare () // is this square occupied
{
var hit = 0;
// Snake Squares
if ( (ax === 3) && (ay === 0) )
{
ay=ay+1;
hit = 1;
}
else if ( (ax === 2) && (ay === 2) )
{
ay=ay+1;
hit = 1;
}
else if ( (ax === 7) && (ay === 4) )
{
ay=ay+1;
hit = 1;
}
else if ( (ax === 8) && (ay === 7) )
{
ay=ay+1;
hit = 1;
}
// Ladder Squares
if ( (ax === 4) && (ay === 2) )
{
ay=ay-1;
hit = 2;
}
else if ( (ax === 5) && (ay === 3) )
{
ay=ay-1;
hit = 2;
}
else if ( (ax === 1) && (ay === 5) )
{
ay=ay-1;
hit = 2;
}
else if ( (ax === 3) && (ay === 7) )
{
ay=ay-1;
hit = 2;
}
else if ( (ax === 7) && (ay === 9) )
{
ay=ay-1;
hit = 2;
}
if ( hit == 1 )
{
AB.msg(` <hr> <p> Oh No! You rolled ` + randomNum + `, and landed on a Snake ! <p>
You move back 10 spaces!
` + `Your position is ` + ax + ` , ` + ay + ` <p>
Click roll to roll dice. <p>
<button onclick='roll();' class=ab-largenormbutton > Roll </button> <p>` );
drawAgent();
}
else if ( hit == 2 )
{
AB.msg(` <hr> <p> Horrah! You rolled ` + randomNum + `, and landed on a Ladder ! <p>
You move forward 10 spaces!
` + `Your position is ` + ax + ` , ` + ay + ` <p>
Click roll to roll dice. <p>
<button onclick='roll();' class=ab-largenormbutton > Roll </button> <p>` );
drawAgent();
}
else if (ay < 0)
{
AB.msg(` <hr> <p> You Win! <p>`);
}
else
{
AB.msg(` <hr> <p> You rolled ` + randomNum + `! <p>` +
`Ax is ` + ax + ` Ay is ` + ay + `<p>` +
` Click roll to roll dice. <p>
<button onclick='roll();' class=ab-largenormbutton > Roll </button> <p>` );
}
drawAgent();
}
// translate my (i,j) grid coordinates to three.js (x,y,z) coordinates
// logically, coordinates are: y=0, x and z all positive (no negative)
// logically my dimensions are all positive 0 to MAXPOS
// to centre everything on origin, subtract (MAXPOS/2) from all dimensions
function translate ( i, j )
{
var v = new THREE.Vector3();
v.y = 0;
v.x = ( i * squaresize ) - ( MAXPOS/2 );
v.z = ( j * squaresize ) - ( MAXPOS/2 );
return v;
}
function initScene() // all file loads have returned
{
var i,j, shape, thecube;
// set up GRID as 2D array
// GRID = new Array(gridsize);
// now make each element an array
for ( i = 0; i < gridsize ; i++ )
GRID[i] = new Array(gridsize);
// set up board
for ( i = 0; i < gridsize ; i++ )
for ( j = 0; j < gridsize ; j++ )
{
GRID[i][j] = true;
shape = new THREE.BoxGeometry ( squaresize, squaresize, squaresize );
thecube = new THREE.Mesh( shape );
ax = 0; // this square will be free
ay = 9;
shape = new THREE.BoxGeometry ( squaresize, squaresize, squaresize );
theagent = new THREE.Mesh( shape );
theagent2 = new THREE.Mesh( shape );
theagent3 = new THREE.Mesh( shape );
theagent4 = new THREE.Mesh( shape );
theagent5 = new THREE.Mesh( shape );
theagent6 = new THREE.Mesh( shape );
theladder2 = new THREE.Mesh( shape );
theladder3 = new THREE.Mesh( shape );
theladder4 = new THREE.Mesh( shape );
theladder5 = new THREE.Mesh( shape );
theladder6 = new THREE.Mesh( shape );
//theagent2.position.copy ( translate(0,0) ); // translate my (i,j) grid coordinates to three.js (x,y,z) coordinates
theagent3.position.copy ( translate(3,0) );
theagent4.position.copy ( translate(2,2) );
theagent5.position.copy ( translate(7,4) );
theagent6.position.copy ( translate(8,7) );
theladder2.position.copy ( translate(4,2) );
theladder3.position.copy ( translate(5,3) );
theladder4.position.copy ( translate(1,5) );
theladder5.position.copy ( translate(3,7) );
theladder6.position.copy ( translate(7,9) );
theagent.material = new THREE.MeshBasicMaterial( { map: agent_texture } );
theagent2.material = new THREE.MeshBasicMaterial( { map: agent2_texture } );
theagent3.material = new THREE.MeshBasicMaterial( { map: agent3_texture } );
theagent4.material = new THREE.MeshBasicMaterial( { map: agent4_texture } );
theagent5.material = new THREE.MeshBasicMaterial( { map: agent5_texture } );
theagent6.material = new THREE.MeshBasicMaterial( { map: agent6_texture } );
theladder2.material = new THREE.MeshBasicMaterial( { map: ladder2_texture } );
theladder3.material = new THREE.MeshBasicMaterial( { map: ladder3_texture } );
theladder4.material = new THREE.MeshBasicMaterial( { map: ladder4_texture } );
theladder5.material = new THREE.MeshBasicMaterial( { map: ladder5_texture } );
theladder6.material = new THREE.MeshBasicMaterial( { map: ladder6_texture } );
ABWorld.scene.add(theagent);
ABWorld.scene.add(theagent2);
ABWorld.scene.add(theagent3);
ABWorld.scene.add(theagent4);
ABWorld.scene.add(theagent5);
ABWorld.scene.add(theagent6);
ABWorld.scene.add(theladder2);
ABWorld.scene.add(theladder3);
ABWorld.scene.add(theladder4);
ABWorld.scene.add(theladder5);
ABWorld.scene.add(theladder6);
thecube.material = new THREE.MeshBasicMaterial( { map: wall_texture } );
thecube.position.copy ( translate(i,j) ); // translate my (i,j) grid coordinates to three.js (x,y,z) coordinates
ABWorld.scene.add(thecube);
}
drawAgent();
// can start the run loop
ABWorld.render();
AB.runReady = true;
AB.msg ( ` <hr> <p> Multi-user game. Click roll to roll dice. Drag the camera. <p>
<button onclick='roll();' class=ab-largenormbutton > Roll </button> <p> ` );
}
function roll()
{
moveLogicalAgent();
}
// --- draw moving objects -----------------------------------
function drawAgent() // given ai, aj, draw it
{
// AB.msg(' getting in ');
// AB.msg(ax + ' ' + ay);
theagent.position.copy ( translate(ax,ay) ); // translate my (i,j) grid coordinates to three.js (x,y,z) coordinates
ABWorld.follow.copy ( theagent.position ); // follow vector = agent position (for camera following agent)
}
// --- take actions -----------------------------------
function moveLogicalAgent() // this is called by the infrastructure that gets action a from the Mind
{
var min = Math.ceil(0);
var max = Math.floor(7);
randomNum = Math.floor(Math.random() * (max - min) + min);
//randomNum = 6
AB.msg ( ` <hr> <p> Multi-user game. Click roll to roll dice. Drag the camera. <p>
<button onclick='roll();' class=ab-largenormbutton > Roll </button> <p>
You rolled ` + randomNum + `!` + ax + ' ' + ay);
if (ay == 8 || ay == 6 || ay == 8 || ay == 2 || ay === 0)
{
if ( (ax - randomNum) < 0)
{
ay = ay - 1;
ax = ax - randomNum;
if (ax < 0)
{
ax = ax * -1;
}
ax = ax - 1;
}
else
ax = ax - randomNum;
}
else
{
if ( (ax + randomNum) >= 10)
{
ay = ay - 1;
testVar = (10 - ax);
ax = (randomNum - testVar);
Math.abs(ax);
ax = ((10 - ax) - 1);
}
else
{
ax = ax + randomNum;
}
}
drawAgent();
snakeSquare();
}
// --- score: -----------------------------------
function updateStatus()
{
var score = AB.world.getScore();
AB.msg ( " Step: " + AB.step + " out of " + AB.maxSteps + ". Score: " + score );
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> ` );
}
AB.world.newRun = function()
{
AB.runReady = false;
badsteps = 0;
goodsteps = 0;
ABWorld.init3d ( startRadiusConst, maxRadiusConst, SKYCOLOR );
loadResources(); // aynch file loads
// calls initScene() when it returns
};
AB.world.getState = function()
{
// return ( 0 ); // MH edit
var x = [ ax, ay, ei, ej ];
return ( x );
};
AB.world.getScore = function()
{
return goodsteps;
};