// Cloned by Yiming Fu on 1 Dec 2022 from World "Don't Move" by Finnian O'Neill
// Please leave this clone trail here.
/* =============================================================================================
Don't Move
3d-effect Maze World (really a 2-D problem)
Finnian O'Neill, 2016.
Dont Move is a user controlled game, where you can move your white cube around the stage.
The aim of the game is to fill the floor with the falling cubes while avoiding getting hit by them.
// =============================================================================================
// =============================================================================================
I declare that this material, which I now submit for assessment, is entirely my
own work and has not been taken from the work of others, save and to the extent that such
work has been cited and acknowledged within the text of my work. I understand
that plagiarism, collusion, and copying are grave and serious offences in the university and
accept the penalties that would be imposed should I engage in plagiarism, collusion or
copying. I have read and understood the Assignment Regulations. I have identified
and included the source of all facts, ideas, opinions, and viewpoints of others in the
assignment references. Direct quotations from books, journal articles, internet sources,
module text, or any other source whatsoever are acknowledged and the source cited are
identified in the assignment references. This assignment, or any part of it, has not been
previously submitted by me or any other person for assessment on this or any other
course of study.
Finnian O'Neill (13430512)
// =============================================================================================
*/
const CLOCKTICK = 100; // Speed of run: Step every n milliseconds.
const MAXSTEPS = 1000; // Length of run: Maximum length of run in steps.
const SCREENSHOT_STEP = 50;
function World() { //------------Word Start-------------
const gridsize = 150; // length of each side
const noSquares = 10; // size of square in pixels
const MAXPOS = gridsize * noSquares; // length of one side in pixels
const MAX = 135;
const SKYCOLOR = 0x000000; // a number, not a string
const startRadiusConst = MAXPOS*0.2 ; // distance from centre to start the camera at
const maxRadiusConst = MAXPOS * 3 ; // maximum distance from camera we will render things
var grid;
var floor;
var player;
var playerX =5;
var playerZ =0;
var playerY =0;
var occupied = false;
var difficulty = 1;
var noCubes = 5 + difficulty;
var cubeHeight = difficulty;
var floorSpacesLeft;
var collided = false;
//----------------------Grid Start-------------------------
function random(lowerLimit, upperLimit){
return Math.floor(Math.random() * upperLimit) + lowerLimit;
}
//----------------------Grid Start-------------------------
function initGrid(){
grid = new THREE.GridHelper(gridsize,noSquares);//create the 2d grid on the floor.
threeworld.scene.add(grid);
grid = new Array(noSquares);
for (var x = 0; x < noSquares ; x++){//create a 3d array to store which spaces are occupied by cubes.
grid[x] = new Array(noSquares);
for (var z = 0; z < noSquares ; z++){
grid[x][z] = new Array(noSquares);
for(var y=-1; y<noSquares; y++){
grid[x][z][y] = occupied;// start by setting them all to be unoccupied.
}
}
}
floor = new Array(noSquares);//Store each cube for the floor.
for(var fx=0; fx<noSquares; fx++){
floor[fx] = new Array(noSquares);
for(var fz=0; fz<noSquares; fz++){
floor[fx][fz] = false;
}
}
}
//----------------------Grid End-------------------------
//----------------------Cube Manipulation Start-------------------------
function drawCube(size,height,x,z){//draw a cube/
var side = size*2;
var geometry = new THREE.BoxGeometry(side,side*height,side);
var material = new THREE.MeshNormalMaterial();
var cube = new THREE.Mesh( geometry, material );
cube.position.y=(gridsize/noSquares)+((height-1)*size);
cube.position.z=(gridsize-size)-(side*z);
cube.position.x=(gridsize-size)-(side*x);
threeworld.scene.add( cube );
return cube;
}
function drawPlayerCube(size,height,x,z){//Draw the players cube.
var material = new THREE.MeshBasicMaterial({color: 0xffffff});
var cube = drawCube(size,height,x,z);
cube.material = material;
threeworld.scene.add( cube );
player = cube;
}
function randomCube(y,height){//randomise the position of each cube.
var size = 15;
if(height >= 10){
height = random(1,10);
}
var x = random(0,10);
var z = random(0,10);
var cube = drawCube(size,height,x,z);
cube.position.y = cube.position.y + (y*30);
grid[x][z][y] = cube;
}
function spawnCube(y, cubeNo,cubeHeight){//spawn in cubes.
for(var i=0; i<cubeNo; i++)
randomCube(y,cubeHeight);
}
function move(){//moves all falling cubes down and if they hit the floor, change their color.
for (var x = 0; x < noSquares ; x++){
for (var z = 0; z < noSquares ; z++){
for(var y=-1; y<noSquares; y++){
if(grid[x][z][-1] != occupied){
grid[x][z][-1].material = new THREE.MeshBasicMaterial({color: 0xffffff, wireframe: true});
floor[x][z] = true;
}
if((grid[x][z][y] != occupied) && (y>=0)){
grid[x][z][y].position.y = grid[x][z][y].position.y - 30;
grid[x][z][y-1] = grid[x][z][y];
grid[x][z][y] = occupied;
}
}
}
}
}
function isFloorFull(){//returns the number of squares on the floor left to fill.
var fullFloor = noSquares*noSquares;
for(var x=0; x<noSquares; x++){
for(var z=0; z<noSquares; z++){
if(floor[x][z] === true){
fullFloor--;
}
}
}
return fullFloor;
}
//----------------------Cube Manipulation End-------------------------
//--------------Controls start-----------------
function handleKeyDown (event){
var code = event.keyCode;
if (code == 37){ // left
if(player.position.x <= -MAX){
//console.log("x: "+player.position.x) ;
}else{
playerX--;
spawnCube(4,noCubes,cubeHeight);
move();
moveSound();
player.position.x = player.position.x -30;
}
}
if (code == 38){ // right == up (based on inital camera position)
if(player.position.z <= -MAX){
//console.log("z: "+player.position.z) ;
}else{
playerZ++;
spawnCube(4,noCubes,cubeHeight);
move();
moveSound();
player.position.z = player.position.z -30;
}
}
if (code == 39){ // up == right (based on inital camera position)
if(player.position.x >= MAX){
//console.log("x: "+player.position.x) ;
}else{
playerX++;
spawnCube(4,noCubes,cubeHeight);
move();
moveSound();
player.position.x = player.position.x +30;
}
}
if (code == 40){ // back
if(player.position.z >= MAX){
// console.log("z: "+player.position.z) ;
}else{
playerZ--;
spawnCube(4,noCubes,cubeHeight);
move();
moveSound();
player.position.z = player.position.z +30;
}
}
}
//--------------Controls End-----------------
function gameOver(){//When the game ends, remove instructions and say if they won/lost.
var s = "<h2> </h2>";
$("#user_span1").html( s );
var text = "";
$("#user_span3").text( text );
if(collided == true){
var s = "<font color=red><center> <h1> You Lose! </h1> </center></font>";
$("#user_span1").html( s );
}else{
var s = "<font color=green><center> <h1> You Win! </h1> </center></font>";
$("#user_span1").html( s );
}
for (var x = 0; x < noSquares ; x++){
for (var z = 0; z < noSquares ; z++){
for(var y=0; y<noSquares; y++){
threeworld.scene.remove(grid[x][z][y]);// remove all cubes in the air.
}
}
}
threeworld.scene.remove(player);//remove the player from the scene so they dont try to keep playing.
}
function initInstructions(){//display instructions
var s = "<center> <strong>Instructions:</strong>Use arrow keys to move, each time you move so do the falling blocks... don't get hit!<hr><strong>Aim:</strong> to fill the floor with boxes. </center>";
$("#user_span1").html( s );
}
function printDetails(){//display number of spaces in the floor left to fill.
floorSpaceLeft = isFloorFull();
text = "Floor Spaces Left: "+floorSpaceLeft;
$("#user_span3").text( text );
}
//----------------------Running Functions Start-------------------------
this.endCondition;
this.newRun = function()
{
this.endCondition = false;
if ( true )
{
threeworld.init3d ( startRadiusConst,maxRadiusConst, SKYCOLOR );//init 3d world
document.addEventListener( 'keydown', handleKeyDown );//add arrow key listeners
initMusic();//start music.
initGrid();//init the grids
initInstructions();//display instructions.
drawPlayerCube(15,1,playerX,playerZ);//Draw the player cube.
}
};
this.getState = function()
{
state = true;
return ( state ); // State format defined by this World.
};
this.nextStep = function()
{
var action = 4;
if ( true ){
printDetails();
if(grid[playerX][playerZ][playerY] != occupied){//if a falling cube && the player are in the same space, end the game
collided = true;
this.endCondition = true;
}
}
if(isFloorFull() == 0){//if the floor is full, end the game.
this.endCondition = true;
}
};
this.endRun = function()
{
if(true){
if(this.endCondition==true){
if((isFloorFull() == 0) || (collided == true)){
gameOver();
}
}
}
};
this.getScore = function()
{
return (isFloorFull());
};
//----------------------Running Functions End-------------------------
}//------------Word End-------------
function initMusic(){//init the background music
var x="<audio id=gameSound src=/uploads/oneilf27/dark-techno-city.mp3 autoplay >";
$("#user_span6").html( x );
}
function moveSound(){
x = "</audio><audio id=moveSound src=/uploads/oneilf27/beepmult.mp3 autoplay > </audio>";
$("#user_span5").html( x );
}