Code viewer for World: Infinite World Only Ground...

// Cloned by MENGTE ZHU on 2 Mar 2024 from World "Infinite World Only Ground (clone by MENGTE ZHU) (clone by MENGTE ZHU)" by MENGTE ZHU 
// Please leave this clone trail here.
 


// Cloned by MENGTE ZHU on 2 Mar 2024 from World "Infinite World Only Ground (clone by MENGTE ZHU)" by MENGTE ZHU 
// Please leave this clone trail here.
 


// Cloned by MENGTE ZHU on 19 Jan 2024 from World "Infinite World Only Ground" by Nathan Bonnard 
// Please leave this clone trail here.
 
//==============================================================================
//  Welcome to the Infinite world with only grounds !
//==============================================================================

// This program was made by Nathan Bonnard.
// In this world, you can generate an infinite world ! 
// But this isn't really infinite, it would be impossible, 
// the world do a simple loop when the player reach the border. Like in real life !
// This is a little version of the real infinite world that you can find aswell on the enhanced page

//------------------------------ TWEAKER BOX ------------------------------//

const squaresize = 7 ; // The world is like a infinite grid of square. squaresize is the size of a square
var MOVESPEED = 7; // Speed of the player

var viewDistance = 2; // determinate the maximum distance to see ground (viewDistance * squaresize * groundMultiplier)
var groundMultiplier = 551; // The world is divided by zone (grounds) that size groundMultiplier*squaresize
var worldSize = 13; // dimension of the world, it is not really infinite but big and can loop. There is worldSize * worldSize Grounds 

const SKYDISTANCE = 3000; // Distance of stars and sun
const NBSTARS = 100; //number of stars

//Where all textures and objects are
const PATHTEXTURES = "/uploads/meak/";

//------------------------------ END OF TWEAKER BOX ------------------------------//

var newviewDistance = viewDistance; // letiables to re-generate the world with new letiables 
var newGroundMultiplier = groundMultiplier;
var newworldSize = worldSize;

const MAXPOS                = 4000 ;                                 
const startRadiusConst	 	= MAXPOS * 0.5 ;		// distance from centre to start the camera at
const maxRadiusConst 		= MAXPOS * 5 ;		// maximum distance from camera we will render things  

const SKYCOLOR 	= 0x6495ED;
const LIGHTCOLOR = 0xffffff ;

//used to manage the click and give back control to the user when you click on a button/text box 
//and don't want to enter into first person mode
var HUDEVENT = false;
var mouse; // vector2 : position of the mouse on the screen


 

  

// Take screenshot on this step. (All resources should have finished loading.) Default 50.

/**
 * A linear interpolator for hexadecimal colors
 * @param {Int} a
 * @param {Int} b
 * @param {Number} amount
 * @example
 * // returns 0x7F7F7F
 * lerpColor(0x000000, 0xffffff, 0.5)
 * @returns {Int}
 */
function lerpColor(a, b, amount) { 

    let ah = a;
        ar = ah >> 16, ag = ah >> 8 & 0xff, ab = ah & 0xff,
        bh = b;
        br = bh >> 16, bg = bh >> 8 & 0xff, bb = bh & 0xff,
        rr = ar + amount * (br - ar),
        rg = ag + amount * (bg - ag),
        rb = ab + amount * (bb - ab);

    return  ((1 << 24) + (rr << 16) + (rg << 8) + rb | 0);
}

/**/
function map(n, start1, stop1, start2, stop2) 
{
    return ((n-start1)/(stop1-start1))*(stop2-start2)+start2;
}



//==============================================================================
//  World Definition
//==============================================================================
function World() { 

//==============================================================================
//  All variables
//==============================================================================

var groundTexture; // Texture of the ground

var grounds; // Array2d : Stock all ground of the world
var ai, aj; // position in grounds of the player
var pai, paj; // past position in grounds of the player
var timeRunning = 0; // time updated 
var raycaster; // to determine direction of a click

var camera, controls;

var moveForward = false;
var moveBackward = false;
var moveLeft = false;
var moveRight = false;
var canJump = false;

var prevTime = performance.now();
var velocity = new THREE.Vector3();
var direction = new THREE.Vector3();
var vertex = new THREE.Vector3();
var color = new THREE.Color();

var sun;//sun and all functions with it (also stars)
var loadingManager;//loading manager to load everything and thenrun the program


this.endCondition = false;

//==============================================================================
//==============================================================================

//==============================================================================
//  All Class
//==============================================================================

//==============================================================================
//  Defines the THREE.PointerLockControls class, source at https://threejs.org/
//==============================================================================

THREE.PointerLockControls = function(camera) {

	let scope = this;

	camera.rotation.set( 0, 0, 0 );

	let pitchObject = new THREE.Object3D();
	pitchObject.add( camera );

	let yawObject = new THREE.Object3D();
	yawObject.position.y = 10;
	yawObject.add( pitchObject );
    
    let attachedObject = new THREE.Object3D();
    yawObject.add(attachedObject);
    attachedObject.position.set(0,-yawObject.position.y,-150);
    
    
	let PI_2 = Math.PI / 2;

	let onMouseMove = function ( event ) {
		if ( scope.enabled === false ) return;
	    
		let movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
		let movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;

		yawObject.rotation.y -= movementX * 0.002;
		pitchObject.rotation.x -= movementY * 0.002;

		pitchObject.rotation.x = Math.max( - PI_2, Math.min( PI_2, pitchObject.rotation.x ) );

	};
    
    this.getAttachedObject = function () {

		return attachedObject;

	};

	this.dispose = function () {

		document.removeEventListener( 'mousemove', onMouseMove, false );
	};

	document.addEventListener( 'mousemove', onMouseMove, false );

	this.enabled = false;

	this.getObject = function () {

		return yawObject;

	};

	this.getDirection = function () {

		// assumes the camera itself is not rotated

		let direction = new THREE.Vector3( 0, 0, - 1 );
		let rotation = new THREE.Euler( 0, 0, 0, 'YXZ' );

		return function ( v ) {

			rotation.set( pitchObject.rotation.x, yawObject.rotation.y, 0 );

			v.copy( direction ).applyEuler( rotation );

			return v;

		};

	}();

};
//==============================================================================



// Class to stock Each Objects that were loaded 
// with their combobox size to place them in space
// and to avoid collision ( objects at same place)
class Obj
{
  constructor(nameDoc, sX, sY, sZ) 
  {
      this.path = nameDoc;
      this.sizeX = sX;
      this.sizeY = sY;
      this.sizeZ = sZ;
      this.obj;
  }
}

//==============================================================================
//  Sun Class
//==============================================================================

// Here is the Sun Object. Explanation of parameters :

// target (Object3D) : the player, or camera if you are in first person view. The sun need to be relative to a point
// size (number): the size of the sun & stars
// speed (number): the speed of the rotation of the sun
// skyDistance (number): the distance of the sky from the target.
function Sun(target, size, speed, skyDistance)
{
        this.angle = 0;
        this.object = new THREE.DirectionalLight( 0xffffff, 0.1 );
        this.object.position.set(0, Math.cos(this.angle)*skyDistance, Math.sin(this.angle)*skyDistance);
        this.object.castShadow = true;
        this.object.shadow.mapSize.width = 1024;
        this.object.shadow.mapSize.height = 1024;
        this.object.shadow.camera.near = 10;
        this.object.shadow.camera.far = 4000;
        
        let d = 1000;

        this.object.shadow.camera.left = -d;
        this.object.shadow.camera.right = d;
        this.object.shadow.camera.top = d;
        this.object.shadow.camera.bottom = -d;
        this.object.shadow.bias = -0.0001;
        
        threeworld.scene.add(this.object);
        this.stars = [];
        this.starMaterial = new THREE.MeshBasicMaterial({color : "white", fog: false}) ;
        this.starMaterial.transparent = true;
        this.starMaterial.opacity = 0;
        
        let sunball = new THREE.Mesh( new THREE.SphereGeometry(size,32,32), new THREE.MeshBasicMaterial({color : "yellow", fog: false}) );
        this.object.add( sunball );
        this.starGyroscope = new THREE.Mesh();
        target.add(this.starGyroscope);
        
        //Create all stars

        
        //Use this in nextStep to make the sun move
        this.animate = function()
        {
            this.angle+= 0.001 * speed;
            
            //normalize angle between -PI and PI
            while (this.angle <= -Math.PI) this.angle += Math.PI*2;
            while (this.angle > Math.PI) this.angle -= Math.PI*2;
            
            this.object.position.set(target.position.x, Math.cos(this.angle)*skyDistance, Math.sin(this.angle)*skyDistance + target.position.z);
            
            this.object.intensity = this.getSunIntensity();
            
            let c = new THREE.Color(this.getSkyColor());
            threeworld.scene.background = c;
                    
            this.setStarsOpacity();
            this.starGyroscope.rotation.set(-target.rotation.x, -target.rotation.y, -target.rotation.z);
        }
    
        //change star opacity and fog depending of the position of the sun
        this.setStarsOpacity = function()
        {
            if (this.angle > Math.PI/2  &&  this.angle < Math.PI*3/4)
            {
                this.starMaterial.opacity = map(this.angle, Math.PI/2, Math.PI*3/4, 0, 0.8);
            }
            else if (this.angle > -Math.PI*3/4  &&  this.angle < -Math.PI/2)
            {
                this.starMaterial.opacity = map(this.angle, -Math.PI*3/4, -Math.PI/2, 0.8, 0);
            }
        }
        
        //return the color of the sky depending of the position of the sun (to get the sunrise)
        this.getSkyColor = function()
        {
            if (this.angle > -Math.PI*3/8  &&  this.angle < Math.PI*3/8)
            {
                // console.log("day");
                return 0x7ec0ee;
            }
            else if (this.angle > Math.PI*3/8  &&  this.angle < Math.PI/2)
            {
                // console.log("Sunset 1");
                return lerpColor(0x7ec0ee, 0xfd5e53, map(this.angle, Math.PI*3/8,Math.PI/2,0,1));
            }
            else if (this.angle > Math.PI/2  &&  this.angle < Math.PI*5/8)
            {
                // console.log("Sunset 2");
                return lerpColor(0xfd5e53, 0x0c3166, map(this.angle, Math.PI/2,Math.PI*5/8,0,1));
            }
            else if (this.angle > Math.PI*5/8  ||  this.angle < -Math.PI*3/4)
            {
                // console.log("night");
                return 0x0c3166;
            }
            else if (this.angle > -Math.PI*3/4  &&  this.angle < -Math.PI/2)
            {
                // console.log("Sunrise 1");
                return lerpColor(0x0c3166, 0xfd5e53, map(this.angle, -Math.PI*3/4,-Math.PI/2,0,1));
            }
            else if (this.angle > -Math.PI/2  &&  this.angle < -Math.PI*3/8)
            {
                // console.log("Sunrise 2");
                return lerpColor(0xfd5e53, 0x7ec0ee, map(this.angle, -Math.PI/2, -Math.PI*3/8, 0, 1));
            }
        }
        
        //return intensity of the sun
        this.getSunIntensity = function()
        {
            
            if (this.angle > -Math.PI*3/8  &&  this.angle < Math.PI*3/8)
            {
                return 2;
            }
            else if (this.angle > Math.PI*3/8  &&  this.angle < Math.PI/2)
            {
                return map(this.angle, Math.PI*3/8,Math.PI/2,2,1);
            }
            else if (this.angle > Math.PI/2  &&  this.angle < Math.PI*3/4)
            {
                return map(this.angle, Math.PI/2,Math.PI*3/4,1,0);
            }
            else if (this.angle > Math.PI*3/4  ||  this.angle < -Math.PI*3/4)
            {
                return 0;
            }
            else if (this.angle > -Math.PI*3/4  &&  this.angle < -Math.PI/2)
            {
                return map(this.angle, -Math.PI*3/4,-Math.PI/2,0,1);
            }
            else if (this.angle > -Math.PI/2  &&  this.angle < -Math.PI*3/8)
            {
                return map(this.angle, -Math.PI/2, -Math.PI*3/8, 1, 2);
            }
        }
}

//Just return a ground Elements that receive shadow
function createGround() 
{
    let texture = groundTexture;
    let gr = new THREE.Mesh (
        new THREE.PlaneGeometry ( squaresize*groundMultiplier, squaresize*groundMultiplier ),
        texture );
    gr.receiveShadow = true;
    gr.rotation.x = (Math.PI / 2) * 3;
    return gr;
}

//initialize the ground of the world, to determine all type nd create fake grounds
//around the world to fake a loop
function initGround()
{
    for(let i = 0; i < worldSize; i++)
    {
        for(let j = 0; j < worldSize; j++)
        {
            grounds[i][j] = createGround();
            grounds[i][j].position.set((i- Math.trunc(worldSize/2)) * squaresize * groundMultiplier,0, (j- Math.trunc(worldSize/2)) * squaresize*groundMultiplier);
            threeworld.scene.add(grounds[i][j]);
        }
    }
    
    for(let i = - viewDistance; i < worldSize + viewDistance; i++)
    {
        for(let j = - viewDistance; j < worldSize + viewDistance; j++)
        {
            let b = (worldSize + viewDistance);
            
            if(i < 0 || j < 0 || i >= worldSize || j >= worldSize)
            {
                let tmp;
                if( i < 0)
        		{
        			if(j < 0)
        			{
        				tmp = grounds[worldSize + i][worldSize + j].clone();
        			}
        			else if(j >= worldSize)
        			{
        				tmp = grounds[worldSize + i][j - worldSize].clone();
        			}
        			else
        			{
        				tmp = grounds[worldSize + i][j].clone();
        			}
        			
        		}
        		else if(i >= worldSize)
        		{
        			if(j < 0)
        			{
        				tmp = grounds[i - worldSize][worldSize + j].clone();
        			}
        			else if(j >= worldSize)
        			{
        				tmp = grounds[i - worldSize][j - worldSize].clone();
        			}
        			else
        			{
        				tmp = grounds[i - worldSize][j].clone();
        			}
        		}
        		else if(i >= worldSize)
        		{
        			if(j < 0)
        			{
        				tmp = grounds[i - worldSize][worldSize + j].clone();
        			}
        			else if(j >= worldSize)
        			{
        				tmp = grounds[i - worldSize][j - worldSize].clone();
        			}
        			else
        			{
        				tmp = grounds[i - worldSize][j].clone();
        			}
        		}
        		else if( j < 0)
        		{
        			tmp = grounds[i][worldSize + j].clone();
        		}
        		else if(j >= worldSize)
        		{
        			tmp = grounds[i][j - worldSize].clone();
        		}
        		tmp.position.set((i - Math.trunc(worldSize/2)) * squaresize * groundMultiplier,0, (j - Math.trunc(worldSize/2)) * squaresize*groundMultiplier);
                threeworld.scene.add(tmp);
            }
        }
    }
}
//==============================================================================
//==============================================================================



//==============================================================================
//==============================================================================

//==============================================================================
// Functions link to an event
//==============================================================================

//Create a new infinite world. First destroy the previous one and then recreate one.
function createNewInfiniteWorld()  
{
    viewDistance =  newviewDistance;
    worldSize = newworldSize;
    groundMultiplier = newGroundMultiplier;
    
    while (threeworld.scene.children.length)
    {
        threeworld.scene.remove(threeworld.scene.children[0]);
    }
    threeworld.scene.add(controls.getObject());
    init();
}

function onDocumentTouchStart( event ) 
{
    console.log("onDocumentTouchStart");
	event.preventDefault();

	event.clientX = event.touches[0].clientX;
    event.clientY = event.touches[0].clientY;
	onDocumentMouseDown( event );
}

//Called when a key is up

//==============================================================================
//==============================================================================

//Load all you need
function loader()
{
    planeTex = THREE.ImageUtils.loadTexture( "/uploads/meak/grass.jpg" );
    planeTex.wrapS = planeTex.wrapT = THREE.RepeatWrapping;
    planeTex.repeat.set( 8, 8 );
    
    groundTexture = new THREE.MeshPhongMaterial({map: planeTex, dithering: true });
    groundTexture.wrapAround = true;
    groundTexture.castShadow = true;
    groundTexture.receiveShadow = true;
}

//Initalization before running the world
function init()		 
{
    grounds = new Array(worldSize);
    for (let i = 0; i < worldSize; i++) 
    {
        grounds[i] = new Array(worldSize);
        for (let j = 0; j < worldSize; j++) 
        {
            grounds[i][j] = null;
        }
    }
    ai = parseInt(worldSize/2 + camera.getWorldPosition().x/(squaresize*groundMultiplier));
    aj = parseInt(worldSize/2 + camera.getWorldPosition().z/(squaresize*groundMultiplier));

    pai = ai;
    paj = aj;
    initGround();
    
    // LIGHTS
	let hemiLight = new THREE.HemisphereLight( SKYCOLOR, SKYCOLOR, 0.4 );
	hemiLight.position.set( 0, 50, 0 );
	threeworld.scene.add( hemiLight );
}

function checkPositionPlayer()
{
    //Update the position of the payer in the world so that it can generate ground around the player, depending on the viewDistance
        if(worldSize/2 + camera.getWorldPosition().x/(squaresize*groundMultiplier) < 0)
        {
            ai = -Math.ceil(-(worldSize/2 + camera.getWorldPosition().x/(squaresize*groundMultiplier)));
        }
        else
        {
            ai = Math.trunc(worldSize/2 + camera.getWorldPosition().x/(squaresize*groundMultiplier));
        }
        if(worldSize/2 + camera.getWorldPosition().z/(squaresize*groundMultiplier) < 0)
        {
            aj = -Math.ceil(-(worldSize/2 + camera.getWorldPosition().z/(squaresize*groundMultiplier)));
        }
        else
        {
            aj = Math.trunc(worldSize/2 + camera.getWorldPosition().z/(squaresize*groundMultiplier));
        }
        
        if(ai < 0)
        {
            controls.getObject().position.x = (worldSize/2) * groundMultiplier * squaresize - 0.01;
        }
        if(ai >= worldSize)
        {
            controls.getObject().position.x = - worldSize/2 * groundMultiplier * squaresize;
        }
        if(aj >= worldSize)
        {
            controls.getObject().position.z = - worldSize/2 * groundMultiplier * squaresize;
        }
        if(aj < 0)
        {
           controls.getObject().position.z = (worldSize/2) * groundMultiplier * squaresize - 0.01;
        }
        if(ai != pai || aj != paj)
        {
            pai = ai;
            paj = aj;
        }
}
//==============================================================================
//==============================================================================

//==============================================================================
// Function newRun ,init and endRun
//==============================================================================

this.newRun = function() 
{
    camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, SKYDISTANCE );
    threeworld.camera = camera;
    
    threeworld.init3d ( 0, 0, SKYCOLOR  ); 
    // can adjust renderer:
	threeworld.renderer.shadowMap.enabled = true;
	threeworld.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    
    //load ground texture 
    loader();
    
    //position of mouse in the canvas
    mouse = new THREE.Vector2();
    
    //First person controller
    controls = new THREE.PointerLockControls( camera );
    
 	 //This will handle key presses
    
        let onKeyDown = function ( event ) {

	    	switch ( event.keyCode ) {

				case 38: // up
				case 87: // w
					moveForward = true;
					break;

				case 37: // left
				case 65: // a
					moveLeft = true; break;

				case 40: // down
				case 83: // s
					moveBackward = true;
					break;

				case 39: // right
				case 68: // d
					moveRight = true;
					break;

				case 32: // space
					if ( canJump === true || true ) velocity.y += 350;
					canJump = false; 
					break;
				
				    
				case 82: //Re-generateTheworld (R)
				    createNewInfiniteWorld();
				    threeworld.scene.add(sun.object);
				    break;
			}

		};

		let onKeyUp = function ( event ) {

			switch( event.keyCode ) {

				case 38: // up
				case 87: // w
					moveForward = false;
					break;

				case 37: // left
				case 65: // a
					moveLeft = false;
					break;

				case 40: // down
				case 83: // s
					moveBackward = false;
                    break;

				case 39: // right
				case 68: // d
					moveRight = false;
					break;

			}

		};
 	
 	document.addEventListener('keydown', onKeyDown, false );
	document.addEventListener('keyup', onKeyUp, false );
	
	raycaster = new THREE.Raycaster( new THREE.Vector3(), new THREE.Vector3( 0, - 1, 0 ), 0, 10 );

    //The following handles pointer locking when clicking the window
	    
	let havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document;
    console.log(havePointerLock);
    if ( havePointerLock ) {

		let element = document.body;

		let pointerlockchange = function ( event ) {

			if ( document.pointerLockElement === element || document.mozPointerLockElement === element || document.webkitPointerLockElement === element ) 
			{
			    if(HUDEVENT)
			    {
			        document.exitPointerLock();
			        HUDEVENT = false;
			    }
			    else
			    {
			        if(!controls.enabled && controls.getAttachedObject().children.length !== 0)
                    {
                        controls.getAttachedObject().remove(controls.getAttachedObject().children[1]);
                        controls.getAttachedObject().remove(controls.getAttachedObject().children[0]);
                    }
			        if(!controls.enabled)
                    {
                        controls.enabled = true;
                        $("#user_span10").html("");
                    }
			    }
			} else
			{
				controls.enabled = false;
				$("#user_span10").html("<p><b>Click screen to enable mouse controls</b></p>");

			}

		};
	let pointerlockerror = function ( event ) {

				console.error("pointerlockerror");
			};

			// Hook pointer lock state change events
			document.addEventListener( 'pointerlockchange', pointerlockchange, false );
			document.addEventListener( 'mozpointerlockchange', pointerlockchange, false );
			document.addEventListener( 'webkitpointerlockchange', pointerlockchange, false );

			document.addEventListener( 'pointerlockerror', pointerlockerror, false );
			document.addEventListener( 'mozpointerlockerror', pointerlockerror, false );
			document.addEventListener( 'webkitpointerlockerror', pointerlockerror, false );

			document.addEventListener( 'click', function ( event ) {

				// Ask the browser to lock the pointer
				element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock;
				element.requestPointerLock();

			}, false );

		} else {

			$("#user_span1").html('<p>Your browser doesn\'t seem to support Pointer Lock API</p>');

		}
		    	if ( AB.onDesktop() )
        {
                $("#user_span1").html("<p>Use WASD or Arrows to move, mouse to look around and space to jump.</p>"+
                "<p> If you want to re-generate the world, you can press R !</p>");
                
                $("#user_span10").html("<p><b>Click screen to enable mouse controls</b></p>");
                
                $("#user_span4").html("<p> Size of each parcel of the world (1 to 1000) <input type=\"number\" min=\"1\" max=\"1000\" value=\""+ newGroundMultiplier +"\" class=\"slider\" id=\"groundMultiplierHtml\"></p>");
                
                document.getElementById("groundMultiplierHtml").onchange = function() {
                    newGroundMultiplier = +this.value ;
                    console.log("groundMultiplierHtml " + newGroundMultiplier);
                    HUDEVENT = true;
                }
                document.getElementById("groundMultiplierHtml").onkeypress = function() {
                    newGroundMultiplier = +this.value ;
                    console.log("groundMultiplierHtml " + newGroundMultiplier);
                    HUDEVENT = true;
                }
                
                
                $("#user_span5").html("<p> Size of the world (1 to 50) <input type=\"number\" min=\"1\" max=\"50\" value=\""+ newworldSize +"\" class=\"slider\" id=\"worldSizeHtml\"></p>");
                
                document.getElementById("worldSizeHtml").onchange = function() {
                    newworldSize = +this.value;
                    if((newworldSize - 1) /2 < newviewDistance)
                    {
                        newviewDistance = 0;
                        document.getElementById("viewDistanceHtml").value = 0;
                    }
                    HUDEVENT = true;
                    console.log("worldSizeHtml " + newworldSize);
                }
                document.getElementById("worldSizeHtml").onkeypress = function() {
                    newworldSize = +this.value;
                    if((newworldSize - 1) /2 < newviewDistance)
                    {
                        newviewDistance = 0;
                        document.getElementById("viewDistanceHtml").value = 0;
                    }
                    HUDEVENT = true;
                    console.log("worldSizeHtml " + newworldSize);
                }
                
                $("#user_span6").html("<p> viewDistance in term of parcel (0 to 10) <input type=\"number\" min=\"0\" max=\"10\" value=\""+ newviewDistance +"\" class=\"slider\" id=\"viewDistanceHtml\"></p>");
                
                document.getElementById("viewDistanceHtml").onchange = function() {
                    if(newworldSize/2 >= +this.value)
                    {
                        newviewDistance = +this.value ;
                    }
                    console.log("viewDistanceHtml " + newviewDistance);
                    HUDEVENT = true;
                }
                document.getElementById("viewDistanceHtml").onkeypress = function() {
                    if(newworldSize/2 >= +this.value)
                    {
                        newviewDistance = +this.value ;
                    }
                    console.log("viewDistanceHtml " + newviewDistance);
                    HUDEVENT = true;
                }
        }
        else 
        {
            $("#user_span1").html( "<p> <b> This World currently only works on desktop. </b> </p>" );
        }
 	    createNewInfiniteWorld();
 	    
 	    //add sun
 	    sun = new Sun(controls.getObject(), 100, 3,SKYDISTANCE);
};




this.nextStep = function()
{
        //======================================================================
        //This will handle moving the player and the camera
        //======================================================================
        
            sun.animate();
			raycaster.ray.origin.copy( controls.getObject().position );
			raycaster.ray.origin.y -= 10;

			let time = performance.now();
			let delta = ( time - prevTime ) / 1000;

			velocity.x -= velocity.x * 10.0 * delta;
	    	velocity.z -= velocity.z * 10.0 * delta;

			velocity.y -= 9.8 * 100.0 * delta; // 100.0 = mass

			direction.z = Number( moveForward ) - Number( moveBackward );
			direction.x = Number( moveLeft ) - Number( moveRight );
			direction.normalize(); // this ensures consistent movements in all directions

			if ( moveForward || moveBackward ) velocity.z -= direction.z * 400.0 * MOVESPEED * delta;
			if ( moveLeft || moveRight ) velocity.x -= direction.x * 400.0 * MOVESPEED * delta;

			controls.getObject().translateX( velocity.x * delta );
			controls.getObject().translateY( velocity.y * delta );
			controls.getObject().translateZ( velocity.z * delta );

			if ( controls.getObject().position.y < 10 ) {

				velocity.y = 0;
				controls.getObject().position.y = 10;

				canJump = true;

			}
			prevTime = time;
			
			//Function to do the loop if the player is at the edge of the world
            checkPositionPlayer();
};
//==============================================================================
//==============================================================================

}