Skip to content

Instantly share code, notes, and snippets.

@nielsdoorn
Created March 14, 2014 10:15
Show Gist options
  • Save nielsdoorn/9545222 to your computer and use it in GitHub Desktop.
Save nielsdoorn/9545222 to your computer and use it in GitHub Desktop.
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