mirror of https://github.com/espruino/BangleApps
221 lines
5.2 KiB
JavaScript
221 lines
5.2 KiB
JavaScript
const isB2 = process.env.HWVERSION === 2;
|
|
|
|
// Bangle.js 1 runs just too fast in direct mode??? (also no getPixel)
|
|
if (!isB2) Bangle.setLCDMode("120x120");
|
|
|
|
const options = Bangle.getOptions();
|
|
|
|
options.lockTimeout = 0;
|
|
options.lcdPowerTimeout = 0;
|
|
|
|
Bangle.setOptions(options);
|
|
|
|
g.reset();
|
|
g.setBgColor(0, 0, 0);
|
|
g.setColor(255, 255, 255);
|
|
g.clear();
|
|
const h = g.getHeight();
|
|
|
|
function trigToCoord(ret) {
|
|
return ((ret + 1) * h) / 2;
|
|
}
|
|
|
|
function trigToLen(ret) {
|
|
return (ret * h) / 2;
|
|
}
|
|
|
|
let i = 0.2;
|
|
let speedCoef = 0.014;
|
|
|
|
let flowFile = require("Storage").readJSON("flow.json");
|
|
|
|
let highestI = (flowFile && flowFile.hiscore) || 0.1;
|
|
|
|
let colorA = [255, 255, 0];
|
|
let colorB = [0, 255, 255];
|
|
|
|
let x = 0;
|
|
let xt = 0;
|
|
let safeMode = false;
|
|
let lost = false;
|
|
|
|
function offsetRect(g, x, y, w) {
|
|
g.fillRect(x, y, x + w, y + w);
|
|
}
|
|
|
|
function getColor(num) {
|
|
return [
|
|
[1, 0, 0],
|
|
[0, 1, 0],
|
|
[0, 0, 1],
|
|
[1, 1, 0],
|
|
[0, 1, 1],
|
|
[1, 0, 1],
|
|
[0.5, 0.5, 1],
|
|
[1, 0.5, 0],
|
|
[0, 1, 0.5],
|
|
[0.5, 0.5, 0.5],
|
|
][num];
|
|
}
|
|
|
|
function calculateColor(num) {
|
|
colorA = getColor(Math.floor((num % 1) * 10));
|
|
colorB = getColor(Math.floor((num % 10) - (num % 1)));
|
|
}
|
|
|
|
calculateColor(highestI);
|
|
|
|
Bangle.on("touch", () => (safeMode = !safeMode));
|
|
|
|
function resetGame() {
|
|
x = xt = 0;
|
|
safeMode = lost = false;
|
|
i = 0.2;
|
|
speedCoef = 0.014;
|
|
obstaclePeriod = 150;
|
|
obstacleMode = 1;
|
|
g.clear();
|
|
shownScore = false;
|
|
intervalId = setInterval(draw);
|
|
}
|
|
|
|
function checkCollision() {
|
|
lost = g.getPixel(trigToCoord(+x), (h * 2) / 3 - 4) !== 0;
|
|
if (lost) {
|
|
scoringI = i;
|
|
speedCoef = Math.min(speedCoef, 0.02);
|
|
g.setFont(isB2 ? "6x15" : "4x6", 3);
|
|
g.setColor(colorA[0], colorA[1], colorA[2])
|
|
.drawString(
|
|
"Game over",
|
|
trigToCoord(0) - g.stringWidth("Game over") / 2,
|
|
trigToCoord(0)
|
|
)
|
|
.setColor(1, 1, 1);
|
|
}
|
|
}
|
|
|
|
function drawPlayer() {
|
|
if (!safeMode) xt = Math.cos(i * Math.PI * 4) / 7.5;
|
|
else xt = -Math.cos(i * Math.PI * 2) / 20 + 0.35;
|
|
x = x * 0.8 + xt * 0.2;
|
|
if (highestI > 250) calculateColor(i);
|
|
g.setColor(colorA[0], colorA[1], colorA[2]);
|
|
offsetRect(g, trigToCoord(+x), (h * 2) / 3, 3);
|
|
g.setColor(colorB[0], colorB[1], colorB[2]);
|
|
offsetRect(g, trigToCoord(-x), (h * 2) / 3, 3);
|
|
}
|
|
|
|
let obstaclePeriod = 150;
|
|
let obstacleMode = 1;
|
|
|
|
function drawObstracle() {
|
|
g.setColor(1, 1, 1);
|
|
switch (obstacleMode) {
|
|
case 0:
|
|
offsetRect(g, trigToCoord(-0.15), 0, trigToLen(0.3));
|
|
break;
|
|
case 1:
|
|
offsetRect(g, trigToCoord(0.2), 0, trigToLen(0.2));
|
|
offsetRect(g, trigToCoord(-0.4), 0, trigToLen(0.2));
|
|
break;
|
|
case 2:
|
|
break;
|
|
}
|
|
obstaclePeriod--;
|
|
if (obstaclePeriod <= 0) {
|
|
// If we are off cooldown mode, pick a random actual mode
|
|
if (obstacleMode === 2) {
|
|
obstaclePeriod = Math.random() * 50 + 50;
|
|
obstacleMode = Math.round(Math.random());
|
|
} else if (Math.random() > 0.5) {
|
|
// Give it a chance to repeat with no cooldown
|
|
obstaclePeriod = 25 + 2.5 * speedCoef;
|
|
obstacleMode = 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
let shownScore = false;
|
|
let scoringI = 0;
|
|
|
|
function draw() {
|
|
if (!lost) {
|
|
drawPlayer();
|
|
checkCollision();
|
|
speedCoef *= 1.0005;
|
|
drawObstracle();
|
|
} else {
|
|
speedCoef /= 1.05;
|
|
if (speedCoef <= 0.005) {
|
|
clearInterval(intervalId);
|
|
i -= speedCoef;
|
|
g.setFont(isB2 ? "6x15" : "4x6", 1);
|
|
const str = "Hiscore: " + Math.round(highestI * 10);
|
|
g.setColor(
|
|
scoringI > highestI ? 0 : 255,
|
|
0,
|
|
scoringI > highestI ? 255 : 0
|
|
)
|
|
.drawString(
|
|
str,
|
|
trigToCoord(0) - g.stringWidth(str) / 2,
|
|
trigToCoord(0)
|
|
)
|
|
.setColor(255, 255, 255);
|
|
if (scoringI > highestI) {
|
|
highestI = scoringI;
|
|
require("Storage").writeJSON("flow.json", {
|
|
hiscore: highestI,
|
|
});
|
|
calculateColor(highestI);
|
|
}
|
|
setTimeout(resetGame, 3000);
|
|
} else if (speedCoef <= 0.01 && !shownScore) {
|
|
shownScore = true;
|
|
g.setFont(isB2 ? "6x15" : "4x6", 2);
|
|
const str = "Score: " + Math.round(scoringI * 10);
|
|
g.setColor(colorB[0], colorB[1], colorB[2])
|
|
.drawString(
|
|
str,
|
|
trigToCoord(0) - g.stringWidth(str) / 2,
|
|
trigToCoord(0)
|
|
)
|
|
.setColor(1, 1, 1);
|
|
}
|
|
}
|
|
i += speedCoef;
|
|
g.scroll(0, speedCoef * h);
|
|
g.flip();
|
|
}
|
|
|
|
let intervalId;
|
|
|
|
if (BTN.read()) {
|
|
for (let i = 0; i < 10; i++) {
|
|
const color = getColor(i);
|
|
g.setColor(color[0], color[1], color[2]);
|
|
g.fillRect((i / 10) * h, 0, ((i + 1) / 10) * h, h);
|
|
}
|
|
g.setColor(0);
|
|
g.setFont("Vector", 9);
|
|
let str = "Welcome to the debug screen!";
|
|
g.drawString(
|
|
str,
|
|
trigToCoord(0) - g.stringWidth(str) / 2,
|
|
trigToCoord(0) - 9
|
|
);
|
|
str = "Don't hold BTN while opening to play!";
|
|
g.drawString(str, trigToCoord(0) - g.stringWidth(str) / 2, trigToCoord(0));
|
|
g.flip();
|
|
setInterval(() => {
|
|
g.scroll(0, 0.014 * h);
|
|
i += 0.014;
|
|
calculateColor(i);
|
|
g.setColor(colorA[0], colorA[1], colorA[2]);
|
|
g.fillRect(0, 0, trigToCoord(0), 0.014 * h);
|
|
g.setColor(colorB[0], colorB[1], colorB[2]);
|
|
g.fillRect(trigToCoord(0), 0, trigToCoord(1), 0.014 * h);
|
|
}, 1000 / 30);
|
|
} else intervalId = setInterval(draw, 1000 / 30);
|