Created
March 14, 2014 10:15
-
-
Save nielsdoorn/9545222 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function LeapLander() { | |
var canvas; | |
var c; | |
var width; | |
var height; | |
var roll; | |
var viewPort = { x: 0, y: 0}; | |
var explosions = []; | |
this.BG_WIDTH = 2000; | |
this.BG_HEIGHT = 1400; | |
var sounds = { | |
pullup: { id: 'pullup', file: 'sounds/warnpullup.mp3', sound: undefined, playing: false}, | |
terrain: { id: 'terrain', file: 'sounds/warnterrain.mp3', sound: undefined, playing: false}, | |
thrust: { id: 'thrust', file: 'sounds/thrust.mp3', sound: undefined, playing: false}, | |
explosion: { id: 'explosion', file: 'sounds/explosion.mp3', sound: undefined, playing: false} | |
}; | |
var background = [ | |
{x: 0, y: 0, safe: false }, | |
{x: 20, y: 100, safe: false}, | |
{x: 200, y: 200, safe: false }, | |
{x: 300, y: 1350, safe: false}, | |
{x: 400, y: 1350, safe: true}, | |
{x: 450, y: 1250, safe: false}, | |
{x: 500, y: 1250, safe: true}, | |
{x: 600, y: 1400, safe: false}, | |
{x: 630, y: 1400, safe: true}, | |
{x: 700, y: 1000, safe: false}, | |
{x: 750, y: 1200, safe: false}, | |
{x: 760, y: 1100, safe: false}, | |
{x: 820, y: 1100, safe: true}, | |
{x: 820, y: 1220, safe: false}, | |
{x: 840, y: 1290, safe: false}, | |
{x: 900, y: 1000, safe: false}, | |
{x: 910, y: 900, safe: false}, | |
{x: 960, y: 900, safe: true}, | |
{x: 960, y: 800, safe: false}, | |
{x: 980, y: 800, safe: true}, | |
{x: 1000, y: 1200, safe: false}, | |
{x: 1200, y: 1100, safe: false}, | |
{x: 1250, y: 1230, safe: false}, | |
{x: 1300, y: 960, safe: false}, | |
{x: 1340, y: 960, safe: true}, | |
{x: 1360, y: 850, safe: false}, | |
{x: 1480, y: 800, safe: false}, | |
{x: 1500, y: 880, safe: false}, | |
{x: this.BG_WIDTH, y: this.BG_HEIGHT-200, safe: false} | |
] | |
var game = this; | |
var ship = new Ship(this); | |
function reset() { | |
ship = new Ship(game); | |
} | |
function loadSounds() { | |
sounds.pullup.sound = soundManager.createSound({ | |
id: 'pullup', | |
url: sounds.pullup.file, | |
autoload: true | |
}); | |
sounds.terrain.sound = soundManager.createSound({ | |
id: 'terrain', | |
url: sounds.terrain.file, | |
autoload: true | |
}); | |
sounds.thrust.sound = soundManager.createSound({ | |
id: 'thrust', | |
url: sounds.thrust.file, | |
autoload: true | |
}); | |
sounds.explosion.sound = soundManager.createSound({ | |
id: 'explosion', | |
url: sounds.explosion.file, | |
autoload: true | |
}); | |
} | |
function setSize() { | |
canvas.width = window.innerWidth; | |
canvas.height = window.innerHeight; | |
width = canvas.width; | |
height = canvas.height; | |
viewPort.width = width; | |
viewPort.height = height; | |
} | |
function moveViewPort() { | |
viewPort.y = ship.y - (viewPort.height / 2); | |
viewPort.x = ship.x - (viewPort.width / 2); | |
viewPort.x = (viewPort.x+viewPort.width > game.BG_WIDTH ? game.BG_WIDTH-viewPort.width : viewPort.x); | |
viewPort.x = (viewPort.x < 0 ? 0 : viewPort.x); | |
viewPort.y = (viewPort.y+viewPort.height > game.BG_HEIGHT ? game.BG_HEIGHT-viewPort.height : viewPort.y); | |
viewPort.y = (viewPort.y < 0 ? 0 : viewPort.y); | |
} | |
function determineHandPosition(frame) { | |
for( var i=0; i < frame.hands.length; i++ ){ | |
var hand = frame.hands[i]; | |
if (hand.palmVelocity[1] < -100) { | |
ship.accelarator = false; | |
stopSound(sounds.thrust); | |
} | |
if (hand.palmVelocity[1] > 200 ) { | |
ship.accelarator = true; | |
ship.accelarate(); | |
loopSound(sounds.thrust); | |
} | |
roll = hand.roll(); | |
ship.roll(roll); | |
} | |
} | |
function drawScene(frame) { | |
c.clearRect( 0 , 0 , width , height ); | |
drawBackground(); | |
if (!ship.crashed) { | |
drawShip(); | |
} | |
drawPlane(frame); | |
//drawHands(frame); | |
drawExplosions(); | |
drawData(); | |
} | |
function drawData() { | |
c.save(); | |
c.fillStyle = "white"; | |
var f = "fuel: "+Math.round(ship.fuel); | |
c.fillText(f, width-10, 140); | |
var a = "altitude: "+Math.round(game.BG_HEIGHT - ship.y); | |
c.fillText(a, width-10, 170); | |
var hs = "horizontal speed: "+Math.round(ship.v.x*10)/10; | |
c.fillText(hs, width-10, 200); | |
var vs = "vertical speed: "+(Math.round(ship.v.y*10)/10); | |
c.fillText(vs, width-10, 230); | |
var alfa = "angle: "+(Math.round(ship.alfa*10)/10); | |
c.fillText(alfa, width-10, 260); | |
c.restore(); | |
} | |
function drawExplosions() { | |
c.save(); | |
c.translate(-viewPort.x, -viewPort.y); | |
for (var i = 0; i < explosions.length; i++) { | |
var exp = explosions[i]; | |
c.beginPath(); | |
c.arc(exp.x, exp.y, exp.r, 0, Math.PI * 2, true); | |
c.fillStyle = "red"; | |
c.lineWidth = "4"; | |
c.strokeStyle = "yellow"; | |
c.stroke(); | |
c.fill(); | |
c.closePath(); | |
exp.r*=1.2; | |
exp.lifetime--; | |
}; | |
c.restore(); | |
} | |
function drawShip() { | |
c.save(); | |
c.translate(-viewPort.x, -viewPort.y); | |
c.strokeStyle = "black"; | |
c.fillStyle = "white" | |
c.lineWidth = 2; | |
c.translate(ship.x, ship.y); | |
c.rotate(ship.alfa); | |
c.beginPath(); | |
c.moveTo(5, 5); | |
c.lineTo(0, -5); | |
c.lineTo(-5, 5); | |
c.lineTo(5, 5); | |
c.closePath(); | |
c.stroke(); | |
c.fill(); | |
c.closePath(); | |
if (ship.accelarator && ship.fuel > 0 && !ship.landed) { | |
var thrusterSize = 15 + Math.random() * 10; | |
c.fillStyle = "#f00"; | |
c.beginPath(); | |
c.moveTo(-5, 7); | |
c.lineTo(-5, thrusterSize); | |
c.lineTo(-4, thrusterSize); | |
c.lineTo(-4, 7); | |
c.closePath(); | |
c.fill(); | |
c.beginPath(); | |
c.moveTo(5, 7); | |
c.lineTo(5, thrusterSize); | |
c.lineTo(4, thrusterSize); | |
c.lineTo(4, 7); | |
c.closePath(); | |
c.fill(); | |
} | |
c.restore(); | |
} | |
function drawBackground() { | |
c.save(); | |
c.strokeStyle = "black"; | |
c.fillStyle = "white"; | |
c.translate(-viewPort.x, -viewPort.y); | |
c.beginPath(); | |
c.moveTo(0, game.BG_HEIGHT); | |
for (var i = 0; i < background.length; i++) { | |
coord = background[i]; | |
c.lineTo(coord.x, coord.y); | |
c.stroke(); | |
}; | |
c.lineTo(game.BG_WIDTH, game.BG_HEIGHT); | |
c.lineTo(0, game.BG_HEIGHT); | |
c.stroke(); | |
c.fill(); | |
c.closePath(); | |
c.strokeStyle = 'green'; | |
c.lineWidth = 4; | |
for (var i = 0; i < background.length-1; i++) { | |
oldCoord = background[i]; | |
coord = background[i+1]; | |
if (coord.safe) { | |
c.beginPath(); | |
c.moveTo(oldCoord.x, oldCoord.y); | |
c.lineTo(coord.x, coord.y); | |
c.stroke(); | |
c.closePath(); | |
} | |
}; | |
c.restore(); | |
} | |
function drawPlane() { | |
c.save(); | |
c.translate(width-50, 50) | |
c.rotate((Math.PI * 2) - roll); | |
c.beginPath(); | |
c.moveTo(-40, 0); | |
c.lineTo(40, 0); | |
if (ship.accelarator) { | |
c.strokeStyle = "#f00"; | |
} else { | |
c.strokeStyle = "#fff"; | |
} | |
c.lineWidth = 5; | |
c.stroke(); | |
c.closePath(); | |
c.restore(); | |
} | |
function drawHands(frame) { | |
for( var i=0; i < frame.hands.length; i++ ){ | |
var hand = frame.hands[i]; | |
drawPalm(frame, hand); | |
drawFingers(frame, hand); | |
} | |
} | |
function drawPalm(frame, hand) { | |
// Getting our position | |
var handPos = leapToScene( frame , hand.palmPosition ); | |
// Setting up the style for the fill | |
c.fillStyle = "#7C005A"; | |
// Draw a circle | |
c.beginPath(); | |
c.arc(handPos[0], handPos[1], 10, 0, Math.PI*2); | |
c.closePath(); | |
c.fill(); | |
} | |
function drawFingers(frame, hand) { | |
for( var j = 0; j < hand.fingers.length; j++ ){ | |
var finger = hand.fingers[j]; | |
// Getting our position | |
var fingerPos = leapToScene( frame , finger.tipPosition ); | |
// Setting up the style for the stroke | |
c.strokeStyle = "#759D00"; | |
c.lineWidth = 5; | |
// Draw a circle | |
c.beginPath(); | |
c.arc(fingerPos[0], fingerPos[1], 6, 0, Math.PI*2); | |
c.closePath(); | |
c.stroke(); | |
} | |
} | |
function leapToScene(frame, leapPos){ | |
var iBox = frame.interactionBox; | |
var left = iBox.center[0] - iBox.size[0]/2; | |
var top = iBox.center[1] + iBox.size[1]/2; | |
var x = leapPos[0] - left; | |
var y = leapPos[1] - top; | |
x /= iBox.size[0]; | |
y /= iBox.size[1]; | |
x *= width; | |
y *= height; | |
return [ x , -y ]; | |
} | |
function collisionDetect() { | |
var closestGround = undefined; | |
var shortestDistance = 10000; | |
for (var i = 0; i < background.length-1; i++) { | |
coordA = background[i]; | |
coordB = background[i+1]; | |
var d = pDistance(ship.x, ship.y, coordA.x, coordA.y, coordB.x, coordB.y); | |
if (d < shortestDistance) { | |
closestGround = coordB; | |
shortestDistance = d; | |
} | |
} | |
if (shortestDistance < 150 && (ship.v.x > 1 || ship.v.x < -1 || ship.v.y > 1)) { | |
playSound(sounds.terrain); | |
} | |
if (ship.v.y > 2) { | |
playSound(sounds.pullup); | |
} | |
if (shortestDistance < 8) { | |
if (closestGround.safe && ship.v.y < 1.5 && ship.alfa < 0.2 && ship.alfa > -0.2) { | |
ship.land(); | |
setTimeout(reset, 6000); | |
} else { | |
ship.destroy(); | |
addExplosion(ship.x, ship.y); | |
playSound(sounds.explosion); | |
setTimeout(reset, 2000); | |
} | |
} | |
} | |
function addExplosion(x, y) { | |
explosions.push({'x': x, 'y': y, 'r': 1, 'lifetime': 20}); | |
} | |
function pDistance(x, y, x1, y1, x2, y2) { | |
var A = x - x1; | |
var B = y - y1; | |
var C = x2 - x1; | |
var D = y2 - y1; | |
var dot = A * C + B * D; | |
var len_sq = C * C + D * D; | |
var param = dot / len_sq; | |
var xx, yy; | |
if (param < 0 || (x1 == x2 && y1 == y2)) { | |
xx = x1; | |
yy = y1; | |
} | |
else if (param > 1) { | |
xx = x2; | |
yy = y2; | |
} | |
else { | |
xx = x1 + param * C; | |
yy = y1 + param * D; | |
} | |
var dx = x - xx; | |
var dy = y - yy; | |
return Math.sqrt(dx * dx + dy * dy); | |
} | |
function playSound(s) { | |
if (!s.playing) { | |
s.playing = true; | |
soundManager.play(s.id, { | |
onfinish: function() { | |
s.playing = false; | |
} | |
}) | |
} | |
} | |
function loopSound(s) { | |
if (!s.playing) { | |
s.playing = true; | |
soundManager.play(s.id, { | |
onfinish: function() { | |
loopSound(s); | |
} | |
}) | |
} | |
} | |
function stopSound(s) { | |
if (s.playing) { | |
soundManager.stop(s.id); | |
} | |
s.playing = false; | |
} | |
function handleFrame(frame) { | |
if (!ship.crashed && !ship.landed) { | |
if (frame.valid) { | |
determineHandPosition(frame); | |
} else { | |
ship.accelarator = false; | |
} | |
ship.moveShip(); | |
moveViewPort(); | |
collisionDetect(); | |
} | |
cleanUp(); | |
drawScene(frame); | |
}; | |
function cleanUp() { | |
for (var i = 0; i < explosions.length; i++) { | |
var exp = explosions[i]; | |
if (exp.lifetime < 1) { | |
explosions.remove(i); | |
break; | |
} | |
} | |
} | |
function initLeap() { | |
var controller = new Leap.Controller({ | |
frameEventName: "animationFrame", | |
enableGestures: false | |
}); | |
controller.on( 'connect' , function(){ | |
console.log( 'Successfully connected.' ); | |
}); | |
controller.on( 'deviceConnected' , function() { | |
console.log( 'A Leap device has been connected.' ); | |
}); | |
controller.on( 'ready' , function(){ | |
console.log("ready"); | |
}); | |
controller.on( 'animationFrame' , handleFrame); | |
controller.connect(); | |
} | |
function init() { | |
// create canvas | |
canvas = document.createElement("canvas"); | |
canvas.width = "100%"; | |
canvas.height = "100%"; | |
document.body.appendChild(canvas); | |
setSize(); | |
window.onresize = setSize; | |
c = canvas.getContext('2d'); | |
c.font = "14pt Arial"; | |
c.textAlign = "right"; | |
reset(); | |
initLeap(); | |
soundManager.setup({ | |
url: 'swf', | |
onready: function() { | |
loadSounds(); | |
console.log("SOUNDMANAGER OK"); | |
} | |
}); | |
} | |
init(); | |
} | |
Array.prototype.remove = function(from, to) { | |
var rest = this.slice((to || from) + 1 || this.length); | |
this.length = from < 0 ? this.length + from : from; | |
return this.push.apply(this, rest); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment