// Cloned by Enhanced on 19 Jul 2018 from World "Sampler" by Mathias Bazin
// Please leave this clone trail here.
AB.drawRunControls = false;
const audiofiles = [
"/uploads/mathias/clap.wav",
"/uploads/mathias/crash.wav",
"/uploads/mathias/kick.wav",
"/uploads/mathias/perc.wav",
"/uploads/mathias/snap.wav",
"/uploads/mathias/snare.wav",
"/uploads/mathias/kalimba.mp3",
"/uploads/mathias/hihat.wav"
];
let ColorEnum = Object.freeze({"red":0, "green":1, "blue":2, "yellow":3});
function World()
{
let objects = [];
let selectedAudio = [4];
let grid = new Array(4); //2d array
for(let i = 0; i<4; i++)
{
grid[i] = new Array(16);
for(let j = 0; j<16; j++)
{
grid[i][j] = false;
}
}
let play = false;
let current = 0;
let bpm = 90;
let timeoutNextBeat;
function playSample()
{
let i = this.type;
let a = new Audio(audiofiles[i]);
a.play();
}
function drawButton(x,y,z,width,height,color,name)
{
let cube = new THREE.Mesh(new THREE.BoxBufferGeometry( width, 10, height ), new THREE.MeshBasicMaterial({color:color}));
cube.name = name;
cube.position.set(x, y, z);
threeworld.scene.add(cube);
objects.push(cube);
}
function printGrid() //for debugging
{
s = "";
for(let i = 0; i< 4; i++)
{
for(let j = 0; j< 16; j++)
{
if (grid[i][j]) s+="x";
else s+="-";
}
s+="\n";
}
return s;
}
function switchButton(obj,color,type)
{
// console.log(ColorEnum.red, +type, "grid[ColorEnum.red][+type] : ", grid[ColorEnum.red][+type]);
// console.log(printGrid());
switch(color)
{
case "r":
if (grid[ColorEnum.red][+type] === false)
{
grid[ColorEnum.red][+type] = true;
obj.material.color.setHex(0x8b0000);
}
else
{
grid[ColorEnum.red][+type] = false;
obj.material.color.setHex(0xD3D3D3);
}
break;
case "g":
if (!grid[ColorEnum.green][+type])
{
grid[ColorEnum.green][+type] = true;
obj.material.color.setHex(0x8b0000);
}
else
{
grid[ColorEnum.green][+type] = false;
obj.material.color.setHex(0xD3D3D3);
}
break;
case "b":
if (!grid[ColorEnum.blue][+type])
{
grid[ColorEnum.blue][+type] = true;
obj.material.color.setHex(0x8b0000);
}
else
{
grid[ColorEnum.blue][+type] = false;
obj.material.color.setHex(0xD3D3D3);
}
break;
case "y":
if (!grid[ColorEnum.yellow][+type])
{
grid[ColorEnum.yellow][+type] = true;
obj.material.color.setHex(0x8b0000);
}
else
{
grid[ColorEnum.yellow][+type] = false;
obj.material.color.setHex(0xD3D3D3);
}
break;
}
}
function playAudio(selection)
{
let a = new Audio(selectedAudio[selection]);
a.play();
}
function initDrag ( x, y ) // x,y position on screen
{
let obj = objectClicked( x, y );
if (obj !== null)
{
let color = obj.name.split(".")[0];
let type = obj.name.split(".")[1];
// console.log("Clicked : ", color, type);
if (type == "indicator")
{
switch(color)
{
case "r":
playAudio(ColorEnum.red);
break;
case "g":
playAudio(ColorEnum.green);
break;
case "b":
playAudio(ColorEnum.blue);
break;
case "y":
playAudio(ColorEnum.yellow);
break;
default:
console.error("Error in switch of initdrag()");
break;
}
}
else if (!isNaN(type)) //this checks if the string type contains a number
{
switchButton(obj,color,type);
}
}
}
function objectClicked(x,y)
{
for (let o of objects)
{
if (threeworld.hitsObject(x,y,o))
{
return o;
}
}
// console.log("Clicked : the Void");
return null;
}
function load()
{
for (let f of audiofiles)
{
let a = new Audio(f);
audios.push(a);
}
}
function selectRedAudio()
{
let selectBox = document.getElementById("rselect");
let selectedValue = selectBox.options[selectBox.selectedIndex].value;
selectedAudio[0] = audiofiles[selectedValue];
}
function selectGreenAudio()
{
let selectBox = document.getElementById("gselect");
let selectedValue = selectBox.options[selectBox.selectedIndex].value;
selectedAudio[1] = audiofiles[selectedValue];
}
function selectBlueAudio()
{
let selectBox = document.getElementById("bselect");
let selectedValue = selectBox.options[selectBox.selectedIndex].value;
selectedAudio[2] = audiofiles[selectedValue];
}
function selectYellowAudio()
{
let selectBox = document.getElementById("yselect");
let selectedValue = selectBox.options[selectBox.selectedIndex].value;
selectedAudio[3] = audiofiles[selectedValue];
}
function onClickPlay()
{
play = true;
nextBeat();
}
function onClickPause()
{
play = false;
clearTimeout(timeoutNextBeat);
}
function onClickStop()
{
play = false;
let previous = current-1;
if (previous == -1) previous = 15;
o = threeworld.scene.getObjectByName( "none."+previous );
o.material.color.setHex(0xd3d3d3);
current = 0;
clearTimeout(timeoutNextBeat);
}
function nextBeat()
{
if (grid[ColorEnum.red][current]) playAudio(ColorEnum.red);
if (grid[ColorEnum.green][current]) playAudio(ColorEnum.green);
if (grid[ColorEnum.blue][current]) playAudio(ColorEnum.blue);
if (grid[ColorEnum.yellow][current]) playAudio(ColorEnum.yellow);
let o = threeworld.scene.getObjectByName( "none."+current );
o.material.color.set("chartreuse");
let previous = current-1;
if (previous == -1) previous = 15;
o = threeworld.scene.getObjectByName( "none."+previous );
o.material.color.setHex(0xd3d3d3);
current++;
current %= 16;
if (play) timeoutNextBeat = setTimeout(nextBeat,60000/bpm);
}
function clearTracker()
{
for(let o in objects)
{
if (o.name.includes("none"))
{
o.material.color.setHex(0xd3d3d3);
}
}
}
function reset()
{
for (let i=0; i<4; i++)
{
for (let j=0; j<16; j++)
{
grid[i][j] = false;
}
}
for (let o of objects)
{
let color = o.name.split(".")[0];
let type = o.name.split(".")[1];
if (type !== "indicator" && color !== "none")
{
o.material.color.setHex(0xd3d3d3);
}
}
}
function updateBPM()
{
bpm = document.getElementById("bpm").value;
// console.log(bpm);
}
this.newRun = function()
{
//setup selectors
let s1 = "<p> <font color='red'>Red</font> : <select id='rselect' name='red audio'>";
for (let i = 0; i<audiofiles.length; i++)
{
s1 += '<option value="'+i+'">' +audiofiles[i].replace("/uploads/",'').replace(".mp3",'').replace(".wav",'')+ '</option>';
}
s1 += "</select>"
s1+= " <font color='green'>Green</font> : <select id='gselect' name='green audio'>";
for (let i = 0; i<audiofiles.length; i++)
{
s1 += '<option value="'+i+'">' +audiofiles[i].replace("/uploads/",'').replace(".mp3",'').replace(".wav",'')+ '</option>';
}
s1 += "</select></p>"
$("#user_span1").html(s1);
let s3 = "<p> <font color='blue'>Blue</font> : <select id='bselect' name='blue audio'>";
for (let i = 0; i<audiofiles.length; i++)
{
s3 += '<option value="'+i+'">' +audiofiles[i].replace("/uploads/",'').replace(".mp3",'').replace(".wav",'')+ '</option>';
}
s3 += "</select>"
s3 += "<font color='yellow'>Yellow </font>: <select id='yselect' name='yellow audio'>";
for (let i = 0; i<audiofiles.length; i++)
{
s3 += '<option value="'+i+'">' +audiofiles[i].replace("/uploads/",'').replace(".mp3",'').replace(".wav",'')+ '</option>';
}
s3 += "</select></p>"
$("#user_span3").html(s3);
let s5 = "<p><button id=play> Play </button> <button id=pause> Pause </button> <button id=stop> Stop </button> <button id=reset> Reset </button></p>";
$("#user_span5").html(s5);
let s6 = "<p>BPM : <input id='bpm' type='number' value='80'></p>"
$("#user_span6").html(s6);
if ( AB.runloggedin )
{
$("#user_span7").html ( " <button onclick='AB.saveData();' >Save your work</button> " );
// Check if any data exists, if so make restore button:
AB.queryDataExists(); // will call World.queryDataExists when done
}
else
$("#user_span7").html( " <p> <b> To save your work, go to the World page and run this \"logged in\". </b> </p> " );
//default selected audio
selectedAudio = audiofiles.slice(0,4);
//setup camera
threeworld.camera = new THREE.OrthographicCamera( $(document).width() / - 2, $(document).width() / 2, $(document).height() / 2, $(document).height() / - 2, 1, 1000 );
threeworld.init2d ( 50, 0, 0x000000 ); //0x93A1AC
//drawing the board
drawButton(-$(window).width()/2 + 60,0,0,50,50,"red","r.indicator");
for (let i = 0; i< 16; i++)
{
drawButton(-$(window).width()/2 + 120 + i*30, 0, 0, 20, 40, 0xD3D3D3, "r."+i);
}
drawButton(-$(window).width()/2 + 60,0,70,50,50,"green","g.indicator");
for (let i = 0; i< 16; i++)
{
drawButton(-$(window).width()/2 + 120 + i*30, 0, 70, 20, 40, 0xD3D3D3, "g."+i);
}
drawButton(-$(window).width()/2 + 60,0,140,50,50,"blue","b.indicator");
for (let i = 0; i< 16; i++)
{
drawButton(-$(window).width()/2 + 120 + i*30, 0, 140, 20, 40, 0xD3D3D3, "b."+i);
}
drawButton(-$(window).width()/2 + 60,0,210,50,50,"yellow","y.indicator");
for (let i = 0; i< 16; i++)
{
drawButton(-$(window).width()/2 + 120 + i*30, 0, 210, 20, 40, 0xD3D3D3, "y."+i);
}
for (let i = 0; i< 16; i++)
{
drawButton(-$(window).width()/2 + 120 + i*30, 0, -50, 10, 10, 0xD3D3D3, "none."+i);
}
// drawButton(-$(window).width()/2 + 120 + i*30, 0, -50, 10, 10, 0xD3D3D3, "none.play");
//disabling camera controls
threehandler.mouseZoom = function ( delta ) { };
threehandler.touchDrag = function ( x, y ) { };
threehandler.touchZoom = function ( delta ) { };
threehandler.mouseDrag = function ( x, y ) { };
threehandler.initTouchDrag = initDrag;
threehandler.initMouseDrag = initDrag;
document.getElementById("rselect").addEventListener("change", selectRedAudio);
document.getElementById("yselect").addEventListener("change", selectYellowAudio);
document.getElementById("bselect").addEventListener("change", selectBlueAudio);
document.getElementById("gselect").addEventListener("change", selectGreenAudio);
document.getElementById("play").addEventListener("click", onClickPlay);
document.getElementById("pause").addEventListener("click", onClickPause);
document.getElementById("stop").addEventListener("click", onClickStop);
document.getElementById("bpm").addEventListener("change", updateBPM);
document.getElementById("reset").addEventListener("click", reset);
};
this.nextStep = function()
{
// console.log("play", play, "current", current);
// Code for Three.js re-drawing of objects.
};
this.saveData = function()
{
$("#user_span8").html ( " <button onclick='AB.restoreData();' >Restore your work</button> " );
return { selectedAudio: selectedAudio, grid: grid};
}
this.restoreData = function(a)
{
grid = a.grid;
selectedAudio = a.selectedAudio;
onClickStop();
for (let o of objects)
{
let color = o.name.split(".")[0];
let type = o.name.split(".")[1];
if (!isNaN(type) && color != "none")
{
console.log(color,type);
if (color == "r")
{
console.log("aba")
if (grid[ColorEnum.red][+type]) o.material.color.setHex(0x8b0000);
else o.material.color.setHex(0xd3d3d3);
}
else if (color == "b")
{
if (grid[ColorEnum.blue][+type]) o.material.color.setHex(0x8b0000);
else o.material.color.setHex(0xd3d3d3);
}
else if (color == "y")
{
if (grid[ColorEnum.yellow][+type]) o.material.color.setHex(0x8b0000);
else o.material.color.setHex(0xd3d3d3);
}
else if (color == "g")
{
if (grid[ColorEnum.green][+type]) o.material.color.setHex(0x8b0000);
else o.material.color.setHex(0xd3d3d3);
}
}
}
}
this.queryDataExists = function ( exists )
{
if ( exists )
$("#user_span8").html ( " <button onclick='AB.restoreData();' >Restore your work</button> " );
};
}