forked from FOSS/BangleApps
flow: Create app
parent
a385c09922
commit
ec9bcf994a
15
apps.json
15
apps.json
|
@ -4675,5 +4675,20 @@
|
|||
"data": [
|
||||
{"name":"pooqroman.json"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "flow",
|
||||
"name": "FLOW",
|
||||
"shortName": "FLOW",
|
||||
"version": "0.01",
|
||||
"description": "A game where you have to help a flow avoid white obstacles thing by tapping! This is a demake of an app which I forgot the name of. Press BTN(1) to restart. See if you can get to 2500 score!",
|
||||
"icon": "app.png",
|
||||
"tags": "game",
|
||||
"supports" : ["BANGLEJS", "BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name": "flow.app.js", "url": "app.js" },
|
||||
{"name": "flow.img", "url": "app-icon.js","evaluate": true }
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
# FLOW
|
||||
|
||||
This is a game where you have to help a flow avoid white obstacles thing by tapping!
|
||||
This is a demake of an app which I forgot the name of.
|
||||
Press BTN(1) to restart.
|
||||
See if you can get to 2500 score!
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||

|
||||

|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEw4X/AwX48EHgEC1WgCQkVqoDBBfuqBQcBqoLagEqGAguBqALaGAOoAoQuEBbEAKgIMBBQNUBbgMCyoKHBbBVBBYIKGBbEBtNVrQLfOgNaT4gLagp0CPQOABbcBFwNAgEKBgILbitVqAFClWq0ALZFwTDFGAQLZFwYwDBfg"))
|
|
@ -0,0 +1,220 @@
|
|||
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++) {
|
||||
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);
|
Binary file not shown.
After Width: | Height: | Size: 323 B |
Binary file not shown.
After Width: | Height: | Size: 992 B |
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
Loading…
Reference in New Issue