Skip to content

Instantly share code, notes, and snippets.

@chris-creditdesign
Last active August 29, 2015 14:16
Show Gist options
  • Save chris-creditdesign/abb2cd1e8f37603062f0 to your computer and use it in GitHub Desktop.
Save chris-creditdesign/abb2cd1e8f37603062f0 to your computer and use it in GitHub Desktop.
Three js demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Three JS Cube game</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="hud">
<h1 id="level"></h1>
<p>Click on the boxes to make them go away!</p>
<p id="score"></p>
</div>
<div id="webgl-container"></div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js"></script>
<script src="OrbitControls.js"></script>
<script src="script.js"></script>
</body>
</html>
var scene;
var cube;
var camera;
var renderer;
var clock;
var holder;
var intersects;
var particles = [];
var level = 1;
var totalLevels = 4;
var score = 0;
var totalTargets = 3;
var speed = 0.01;
var complete = false;
var comments = ["Easy", "Tricky", "Careful now", "INSANITY"];
var myLevel = document.getElementById("level");
var myScore = document.getElementById("score");
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
function myScene () {
scene=new THREE.Scene();
var light= new THREE.AmbientLight(0xffffff);
var width = window.innerWidth;
var height = window.innerHeight;
camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 1000);
camera.position.z = 18;
renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
renderer.setSize( width, height );
document.getElementById("webgl-container").appendChild(renderer.domElement);
clock = new THREE.Clock();
var sLight = new THREE.SpotLight( 0xffffff );
sLight.position.set( -100, 100, 100 );
scene.add( sLight );
var aLight = new THREE.AmbientLight( 0xffffff );
scene.add( aLight );
}
function spinner () {
var geometry = new THREE.BoxGeometry(1,1,1);
var material = new THREE.MeshPhongMaterial( {color: "hotpink", ambient: "hotpink" } );
var cube = new THREE.Mesh(geometry, material);
cube.position.x = 10;
var spinner = new THREE.Object3D();
spinner.rotation.x = 6;
spinner.add(cube);
scene.add(spinner);
}
function addHolder () {
holder = new THREE.Object3D();
holder.name = "holder"
for (var i = 0; i < totalTargets; i++) {
var ranCol = new THREE.Color();
ranCol.setRGB( Math.random(), Math.random(), Math.random() );
var geometry = new THREE.BoxGeometry(2,2,2);
var material = new THREE.MeshPhongMaterial( {color: ranCol, ambient: ranCol } );
var cube = new THREE.Mesh(geometry, material);
cube.position.x = i * 5;
cube.name = "cubeName" + i;
var spinner = new THREE.Object3D();
spinner.rotation.x = i*2.5*Math.PI;
spinner.name = "spinnerName" + i;
spinner.add(cube);
holder.add(spinner);
};
scene.add(holder);
}
function addExplosion (point) {
var timeNow = clock.getElapsedTime();
for (var i = 0; i < 4; i++) {
var geometry = new THREE.BoxGeometry(1,1,1);
var material = new THREE.MeshBasicMaterial({color: 0x999999});
var part = new THREE.Mesh(geometry, material);
part.position.x = point.x;
part.position.y = point.y;
part.position.z = point.z;
part.name = "part" + i;
part.birthDay = timeNow;
scene.add(part);
particles.push(part);
};
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render () {
holder.children.forEach(function (elem, index, array) {
elem.rotation.y += (speed * (6-index));
elem.children[0].rotation.x += 0.01;
elem.children[0].rotation.y += 0.01;
});
if (particles.length > 0) {
particles.forEach(function (elem, index, array) {
switch (elem.name) {
case "part0":
elem.position.x += 1;
break;
case "part1":
elem.position.x -= 1;
break;
case "part2":
elem.position.y += 1;
break;
case "part3":
elem.position.y -= 1;
break;
default:
break;
}
if (elem.birthDay - clock.getElapsedTime() < -1 ) {
scene.remove(elem);
particles.splice(index, 1);
}
})
};
renderer.render(scene, camera);
}
function onDocumentMouseDown(event) {
event.preventDefault();
if (complete) {
complete = false;
score = 0;
restartScene();
return;
}
// calculate mouse position in normalized device coordinates
// (-1 to +1) for both components
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
// update the picking ray with the camera and mouse position
raycaster.setFromCamera( mouse, camera );
if (score < totalTargets) {
holder.children.forEach(function (elem, index, array) {
intersects = raycaster.intersectObjects( elem.children );
if (intersects.length > 0 && intersects[0].object.visible) {
intersects[0].object.visible = false;
addExplosion(intersects[0].point);
score += 1;
if (score < totalTargets) {
myScore.innerHTML = "<span class='hit'>HIT!</span> Score: " + score + "/" + totalTargets;
} else {
complete = true;
if (level < totalLevels) {
myScore.innerHTML = "<strong>You got 'em all!</strong> Click the screen for level " + (level+1) + ".";
} else {
myScore.innerHTML = "<strong>You win!</strong> Click the screen to play again.";
}
};
}
});
}
}
function restartScene () {
myScore.innerHTML = "";
if (level < totalLevels) {
speed += 0.005;
totalTargets += 1;
level += 1;
} else {
speed = 0.01;
totalTargets = 3;
level = 1;
}
myLevel.innerText = comments[level-1] + ": Level " + level + " of " + totalLevels;
scene.remove(holder);
addHolder();
}
document.getElementById("webgl-container").addEventListener('mousedown', onDocumentMouseDown, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
render();
}
window.onload = function() {
myLevel.innerText = comments[level-1] + ": Level " + level + " of " + totalLevels;
myScene();
addHolder();
animate();
window.addEventListener( 'resize', onWindowResize, false );
};
body {
margin: 0;
padding: 0;
background-color: #eee;
color: #333;
font-family: helvetica;
}
canvas {
position: absolute;
}
.hud {
position: absolute;
margin-left: 1em;
}
.hit {
font-weight: bold;
color: red;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment