Code viewer for World: Don't Move
/* =============================================================================================
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 );
}