mirror of https://github.com/espruino/BangleApps
151 lines
4.6 KiB
JavaScript
151 lines
4.6 KiB
JavaScript
const falcon9 = Graphics.createImage(`
|
|
xxxxx
|
|
xxxxx xxxxx
|
|
x x
|
|
x x
|
|
xxxxx
|
|
xxxxx
|
|
xxxxx
|
|
xxxxx
|
|
xxxxx
|
|
xxxxx
|
|
xxxxx
|
|
xxxxx
|
|
xxxxx
|
|
xxxxx
|
|
xxxxx
|
|
xxxxx
|
|
xxxxx
|
|
xxxxx
|
|
xxxxxxxxx
|
|
xx xxxxx xx
|
|
xx xx`);
|
|
|
|
const droneShip = Graphics.createImage(`
|
|
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
`);
|
|
|
|
const droneX = Math.floor(Math.random()*(g.getWidth()-droneShip.width-40) + 20)
|
|
const cloudOffs = Math.floor(Math.random()*g.getWidth()/2);
|
|
|
|
const oceanHeight = g.getHeight()*0.1;
|
|
|
|
const targetY = g.getHeight()-oceanHeight-falcon9.height/2;
|
|
|
|
var booster = { x : g.getWidth()/4 + Math.random()*g.getWidth()/2,
|
|
y : 20,
|
|
vx : 0,
|
|
vy : 0,
|
|
mass : 100,
|
|
fuel : 100 };
|
|
|
|
var exploded = false;
|
|
var nExplosions = 0;
|
|
var landed = false;
|
|
|
|
const gravity = 4;
|
|
const dt = 0.1;
|
|
const fuelBurnRate = 20*(176/g.getHeight());
|
|
const maxV = 12;
|
|
|
|
function flameImageGen (throttle) {
|
|
var str = " xxx \n xxx \n";
|
|
str += "xxxxx\n".repeat(throttle);
|
|
str += " xxx \n x \n";
|
|
return Graphics.createImage(str);
|
|
}
|
|
|
|
function drawFalcon(x, y, throttle, angle) {
|
|
g.setColor(1, 1, 1).drawImage(falcon9, x, y, {rotate:angle});
|
|
if (throttle>0) {
|
|
var flameImg = flameImageGen(throttle);
|
|
var r = falcon9.height/2 + flameImg.height/2-1;
|
|
var xoffs = -Math.sin(angle)*r;
|
|
var yoffs = Math.cos(angle)*r;
|
|
if (Math.random()>0.7) g.setColor(1, 0.5, 0);
|
|
else g.setColor(1, 1, 0);
|
|
g.drawImage(flameImg, x+xoffs, y+yoffs, {rotate:angle});
|
|
}
|
|
}
|
|
|
|
function drawBG() {
|
|
g.setBgColor(0.2, 0.2, 1).clear();
|
|
g.setColor(0, 0, 1).fillRect(0, g.getHeight()-oceanHeight, g.getWidth()-1, g.getHeight()-1);
|
|
g.setColor(0.5, 0.5, 1).fillCircle(cloudOffs+34, 30, 15).fillCircle(cloudOffs+60, 35, 20).fillCircle(cloudOffs+75, 20, 10);
|
|
g.setColor(1, 1, 0).fillCircle(g.getWidth(), 0, 20);
|
|
g.setColor(1, 1, 1).drawImage(droneShip, droneX, g.getHeight()-oceanHeight-1);
|
|
}
|
|
|
|
function showFuel() {
|
|
g.setColor(0, 0, 0).setFont("4x6:2").setFontAlign(-1, -1, 0).drawString("Fuel: "+Math.abs(booster.fuel).toFixed(0), 4, 4);
|
|
}
|
|
|
|
function renderScreen(input) {
|
|
drawBG();
|
|
showFuel();
|
|
drawFalcon(booster.x, booster.y, Math.floor(input.throttle*12), input.angle);
|
|
}
|
|
|
|
function getInputs() {
|
|
var accel = Bangle.getAccel();
|
|
var a = Math.PI/2 + Math.atan2(accel.y, accel.x);
|
|
var t = (1+accel.z);
|
|
if (t > 1) t = 1;
|
|
if (t < 0) t = 0;
|
|
if (booster.fuel<=0) t = 0;
|
|
return {throttle: t, angle: a};
|
|
}
|
|
|
|
function epilogue(str) {
|
|
g.setFont("Vector", 24).setFontAlign(0, 0, 0).setColor(0, 0, 0).drawString(str, g.getWidth()/2, g.getHeight()/2).flip();
|
|
g.setFont("Vector", 16).drawString("<= again exit =>", g.getWidth()/2, g.getHeight()/2+20);
|
|
clearInterval(stepInterval);
|
|
Bangle.on("swipe", (d) => { if (d>0) load(); else load('f9lander.app.js'); });
|
|
}
|
|
|
|
function gameStep() {
|
|
if (exploded) {
|
|
if (nExplosions++ < 15) {
|
|
var r = Math.random()*25;
|
|
var x = Math.random()*30 - 15;
|
|
var y = Math.random()*30 - 15;
|
|
g.setColor(1, Math.random()*0.5+0.5, 0).fillCircle(booster.x+x, booster.y+y, r);
|
|
if (nExplosions==1) Bangle.buzz(600);
|
|
}
|
|
else epilogue("You crashed!");
|
|
}
|
|
else {
|
|
var input = getInputs();
|
|
if (booster.y >= targetY) {
|
|
// console.log(booster.x + " " + booster.y + " " + booster.vy + " " + droneX + " " + input.angle);
|
|
if (Math.abs(booster.x-droneX-droneShip.width/2)<droneShip.width/2 && Math.abs(input.angle)<Math.PI/8 && booster.vy<maxV) {
|
|
renderScreen({angle:0, throttle:0});
|
|
epilogue("You landed!");
|
|
}
|
|
else exploded = true;
|
|
}
|
|
else {
|
|
booster.x += booster.vx*dt;
|
|
booster.y += booster.vy*dt;
|
|
booster.vy += gravity*dt;
|
|
booster.fuel -= input.throttle*dt*fuelBurnRate;
|
|
booster.vy += -Math.cos(input.angle)*input.throttle*gravity*3*dt;
|
|
booster.vx += Math.sin(input.angle)*input.throttle*gravity*3*dt;
|
|
renderScreen(input);
|
|
}
|
|
}
|
|
}
|
|
|
|
var stepInterval;
|
|
Bangle.setLCDTimeout(0);
|
|
renderScreen({angle:0, throttle:0});
|
|
g.setFont("Vector", 24).setFontAlign(0, 0, 0).setColor(0, 0, 0).drawString("Swipe to start", g.getWidth()/2, g.getHeight()/2);
|
|
Bangle.on("swipe", () => {
|
|
stepInterval = setInterval(gameStep, Math.floor(1000*dt));
|
|
Bangle.removeListener("swipe");
|
|
});
|