// Cloned by Enhanced on 5 Jun 2018 from World "Cloned Enhanced Minecraft world" by Mathias Bazin
// Please leave this clone trail here.
// Cloned by Mathias Bazin on 1 Jun 2018 from World "Enhanced Minecraft world" by Nathan Bonnard
// Please leave this clone trail here.
// Cloned by Nathan Bonnard on 31 May 2018 from World "Minecraft with cursor + better camera" by Mathias Bazin
// Please leave this clone trail here.
// Cloned by Mathias Bazin on 30 May 2018 from World "Minecraft with cursor" by Mathias Bazin
// Please leave this clone trail here.
// Cloned by Mathias Bazin on 29 May 2018 from World "MineCraft" by Starter user
// Please leave this clone trail here.
// ==== Starter World ===============================================================================================
// (c) Ancient Brain Ltd. All rights reserved.
// This code is only for use on the Ancient Brain site.
// This code may be freely copied and edited by anyone on the Ancient Brain site.
// This code may not be copied, re-published or used on any other website.
// To include a run of this code on another website, see the "Embed code" links provided on the Ancient Brain site.
// ==================================================================================================================
// "MineCraft" World
// user adds blocks
// --- not using nextStep() loop for actions, only for rendering: ------------------------
// all actions are taken whenever user hits keys and not any other time
// however, still need to use nextStep() loop for render update
// ====================================================================================================================
// =Added cursor to choose where to place blocks, controls adapt to camera postion, the blocks to place can be chosen=
// =from the info box, buttons draw shapes =
// ====================================================================================================================
// ===================================================================================================================
// === 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?
// These 3 have default values, so this section is optional:
AB.clockTick = 100;
// Speed of run: Step every n milliseconds. Default 100.
AB.maxSteps = 1000000;
// 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.
AB.drawRunControls = false;
threeworld.drawCameraControls = false;
const FILE_ARRAY = [
"/uploads/mathias/dirt.jpg",
"/uploads/mathias/stone.png",
"/uploads/mathias/wood.png",
"/uploads/mathias/glass.png",
"/uploads/mathias/grass.jpg",
"/uploads/mathias/meat.jpg"
];
const SOUND_BLOCK = '/uploads/starter/chamber.mp3' ;
const SOUND_DEL = '/uploads/starter/chamber.mp3'
const SKYCOLOR = 0xFFFFFF; // a number, not a string
const CURSORCOLOR = "red";
const objectsize = 300 ;
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 shortDistance = 2; //used for checking if two vectors are close to be the same
//--- change threeworld defaults: -------------------------------
threehandler.MAXCAMERAPOS = MAXPOS * 10 ; // allow camera go far away
// ===================================================================================================================
// === End of tweaker's box ==========================================================================================
// ===================================================================================================================
// You will need to be some sort of JavaScript programmer to change things below the tweaker's box.
function randomfloatAtoB ( A, B )
{
return ( A + ( Math.random() * (B-A) ) );
}
function randomintAtoB ( A, B )
{
return ( Math.round ( randomfloatAtoB ( A, B ) ) );
}
function World() {
function createCursor()
{
//create cursor
//create shape and material for the edges
var edgeshape = new THREE.CylinderGeometry(10,10,objectsize,32);
var material = new THREE.MeshBasicMaterial( {color: CURSORCOLOR} );
//create edges
var edge1 = new THREE.Mesh( edgeshape, material );
var edge2 = new THREE.Mesh( edgeshape, material );
var edge3 = new THREE.Mesh( edgeshape, material );
var edge4 = new THREE.Mesh( edgeshape, material );
var edge5 = new THREE.Mesh( edgeshape, material );
var edge6 = new THREE.Mesh( edgeshape, material );
var edge7 = new THREE.Mesh( edgeshape, material );
var edge8 = new THREE.Mesh( edgeshape, material );
var edge9 = new THREE.Mesh( edgeshape, material );
var edge10 = new THREE.Mesh( edgeshape, material );
var edge11= new THREE.Mesh( edgeshape, material );
var edge12= new THREE.Mesh( edgeshape, material );
//place edges correctly
edge1.position.set(-objectsize/2,0,-objectsize/2);
edge2.position.set(-objectsize/2,0,+objectsize/2);
edge3.position.set(+objectsize/2,0,+objectsize/2);
edge4.position.set(+objectsize/2,0,-objectsize/2);
edge5.position.set(objectsize/2,objectsize/2,0);
edge5.rotation.x = Math.PI / 2;
edge6.position.set(-objectsize/2,objectsize/2,0);
edge6.rotation.x = Math.PI / 2;
edge7.position.set(objectsize/2,-objectsize/2,0);
edge7.rotation.x = Math.PI / 2;
edge8.position.set(-objectsize/2,-objectsize/2,0);
edge8.rotation.x = Math.PI / 2;
edge9.position.set(0,-objectsize/2,objectsize/2);
edge9.rotation.z = Math.PI / 2;
edge10.position.set(0,-objectsize/2,-objectsize/2);
edge10.rotation.z = Math.PI / 2;
edge11.position.set(0,+objectsize/2,objectsize/2);
edge11.rotation.z = Math.PI / 2;
edge12.position.set(0,+objectsize/2,-objectsize/2);
edge12.rotation.z = Math.PI / 2;
//add all edges to a group,
var cursor = new THREE.Group();
cursor.add(edge1);
cursor.add(edge2);
cursor.add(edge3);
cursor.add(edge4);
cursor.add(edge5);
cursor.add(edge6);
cursor.add(edge7);
cursor.add(edge8);
cursor.add(edge9);
cursor.add(edge10);
cursor.add(edge11);
cursor.add(edge12);
//you can now manipulate the cursor as a unique object
return cursor;
}
var x, y, z; // current location
var cursor = createCursor();
var textureArray;
var blockArray = [];
// Inputs to instantiate Box
var leftInput;
var rightInput;
var forwardInput;
var backwardInput;
var topInput;
var bottonInput;
var currentTexture;
function init()
{
if(FILE_ARRAY.length > 0)
{
currentTexture = 0;
}
leftInput = 65;
rightInput = 68;
forwardInput = 87;
backwardInput = 83;
topInput = 82;
bottomInput = 70;
cursor.position.set(0,0,0);
threeworld.scene.add(cursor);
textureArray = [FILE_ARRAY.length];
for (let i = 0; i < FILE_ARRAY.length; i++)
{
textureArray[i] = new THREE.ImageUtils.loadTexture( FILE_ARRAY[i] );
}
for ( let i = 0; i < textureArray.length; i++ ) // for all textures
{
textureArray[i].minFilter = THREE.LinearFilter;
}
threeworld.camera.lookAt(cursor.position);
}
//=============================================================================
//Useful functions
//=============================================================================
function getBlockIndexAt(position)
{
let index = 0;
for (let block of blockArray)
{
if ( block.position.distanceTo(position) < shortDistance )
{
return index;
}
index++;
}
return -1;
}
function placeBlockAt(pos)
{
//create block at cursor position
var shape = new THREE.BoxGeometry( objectsize, objectsize, objectsize );
var block = new THREE.Mesh( shape );
block.position.x = pos.x;
block.position.y = pos.y;
block.position.z = pos.z;
threeworld.scene.add(block);
paintThis ( block );
// sound effect credit:
// http://soundbible.com/1399-Chambering-A-Round.html
var audioBlock = new Audio( SOUND_BLOCK );
audioBlock.play();
blockArray.push(block)
}
function deleteBlockAt(position)
{
let toDeleteIndex = getBlockIndexAt(position);
if ( toDeleteIndex > -1 )
{
threeworld.scene.remove(blockArray[toDeleteIndex]);
blockArray.splice(toDeleteIndex, 1);
var audioDelete = new Audio( SOUND_DEL );
audioDelete.play();
}
}
function isOccupied(position)
{
for (let block of blockArray)
{
if ( block.position.distanceTo(position) < shortDistance )
{
return true;
}
}
return false;
}
function paintThis( object ) // paint objects with random textures
{
object.material = new THREE.MeshBasicMaterial ( { transparent: true, opacity:1 , map:textureArray[currentTexture] } );
}
function drawPyramid()
{
var startPosition = new THREE.Vector3(cursor.position.x, cursor.position.y, cursor.position.z);
for (let j = 0 ; j<4 ; j++)
{
for(let i=-j ; i <= j ; i++)
{
for(let k = -j ; k <= j ; k++)
{
var where = new THREE.Vector3(startPosition.x + i*objectsize , startPosition.y - j*objectsize, startPosition.z + k*objectsize);
if ( !isOccupied(where) ) placeBlockAt(where);
}
}
}
}
function drawCube()
{
var startPosition = new THREE.Vector3(cursor.position.x, cursor.position.y, cursor.position.z);
var cubePosition = new THREE.Vector3(cursor.position.x - objectsize , cursor.position.y - objectsize , cursor.position.z - objectsize );
for(var i = 0 ; i<3 ; i++)
{
for(var j = 0 ; j<3 ; j++)
{
for(var k = 0 ; k<3 ; k++)
{
var where = new THREE.Vector3(cubePosition.x + i*objectsize , cubePosition.y + j*objectsize, cubePosition.z + k*objectsize);
if ( !isOccupied(where) ) placeBlockAt(where);
}
}
}
cursor.position.set(startPosition.x, startPosition.y + objectsize , startPosition.z);
}
function onChangeSelectTexture()
{
var selectBox = document.getElementById("textureSelector");
var selectedValue = selectBox.options[selectBox.selectedIndex].value;
currentTexture = selectedValue;
let s4 = "<p>Selected block : <img src=\""+ FILE_ARRAY[currentTexture]+"\" height=\"60\" width=\"60\"></p>";
$("#user_span6").html( s4 );
document.getElementById("p1").click();
}
// the main key handling function:
function handleKeyDown (e)
{
if ( e.keyCode == leftInput ) { cursor.position.x += - objectsize ; e.preventDefault(); } // left
if ( e.keyCode == rightInput ) { cursor.position.x += + objectsize ; e.preventDefault(); } // right
if ( e.keyCode == forwardInput ) { cursor.position.z += - objectsize ; e.preventDefault(); } // forward
if ( e.keyCode == backwardInput ) { cursor.position.z += + objectsize ; e.preventDefault(); } // back
if ( e.keyCode == bottomInput ) { cursor.position.y += - objectsize ; e.preventDefault(); }
if ( e.keyCode == topInput ) { cursor.position.y += + objectsize ; e.preventDefault(); }
if ( e.keyCode == 13 ) // Enter key pressed
{
if( !isOccupied( cursor.position )) //if no block at cursor
{
placeBlockAt(cursor.position);
}
e.preventDefault();
}
if ( e.keyCode == 46 ) { //delete button pressed
if (isOccupied(cursor.position))
{
deleteBlockAt(cursor.position);
}
e.preventDefault();
}
}
this.endCondition = false;
this.newRun = function()
{
threeworld.init3d ( startRadiusConst, maxRadiusConst, SKYCOLOR );
var s = "<p id='p1'> Use WASD, r (up) and f(down) to move the cursor. </p>";
$("#user_span2").html( s );
var s1 = "<p> Press Enter to place a block, Del to delete one. </p>";
$("#user_span3").html( s1 );
var s2 = "<p> Use the dropdown menu to change the kind of block you want to use </p>";
$("#user_span4").html( s2 );
var s3 = "<p><select id=\"textureSelector\" name=\"texture\" >";
for(let i = 0; i < FILE_ARRAY.length; i++)
{
s3 += "<option value=\"" + i + "\" style=\"background-image:url(" + FILE_ARRAY[i]+ ") \"> Block </option>";
}
s3 += "</select>";
$("#user_span5").html( s3 );
var s6 = "<p>Selected block : <img src=\""+ FILE_ARRAY[0]+"\" height=\"60\" width=\"60\"></p>"
$("#user_span6").html( s6 );
var s7 = "<p><button id='pyramidButton'>Draw Pyramid</button> <button id='cubeButton'>Draw Cube</button></p>"
$("#user_span7").html( s7 );
init();
// set up the main key handler:
document.addEventListener( 'keydown', handleKeyDown);
document.getElementById("textureSelector").addEventListener("change", onChangeSelectTexture);
document.getElementById("pyramidButton").addEventListener("click", drawPyramid);
document.getElementById("cubeButton").addEventListener("click", drawCube);
};
this.nextStep = function()
{
if((threeworld.camera.rotation.y >= -Math.PI / 4 && threeworld.camera.rotation.y <= Math.PI / 4) &&
(threeworld.camera.rotation.x >= -Math.PI / 2 && threeworld.camera.rotation.x <= 0) &&
(threeworld.camera.rotation.z >= -Math.PI / 4 && threeworld.camera.rotation.z <= Math.PI / 4))
{
leftInput = 65;
rightInput = 68;
forwardInput = 87;
backwardInput = 83;
}
else if((threeworld.camera.rotation.y >= -Math.PI / 4 && threeworld.camera.rotation.y <= Math.PI / 4) &&
(threeworld.camera.rotation.x >= -Math.PI && threeworld.camera.rotation.x <= -Math.PI / 2) &&
(threeworld.camera.rotation.z >= 3 * Math.PI / 4 || threeworld.camera.rotation.z <= -3 * Math.PI / 4))
{
leftInput = 68;
rightInput = 65;
forwardInput = 83;
backwardInput = 87;
}
else if((threeworld.camera.rotation.y >= 0 && threeworld.camera.rotation.y <= Math.PI / 2) &&
(threeworld.camera.rotation.x >= -Math.PI && threeworld.camera.rotation.x <= 0) &&
(threeworld.camera.rotation.z >= 0 && threeworld.camera.rotation.z <= Math.PI))
{
leftInput = 87;
rightInput = 83;
forwardInput = 68;
backwardInput = 65;
}
else if((threeworld.camera.rotation.y >= -Math.PI / 2 && threeworld.camera.rotation.y <= 0) &&
(threeworld.camera.rotation.x >= -Math.PI && threeworld.camera.rotation.x <= 0) &&
(threeworld.camera.rotation.z >= - Math.PI && threeworld.camera.rotation.z <= 0))
{
leftInput = 83;
rightInput = 87;
forwardInput = 65;
backwardInput = 68;
}
};
this.endRun = function(){};
}