diff --git a/apps.json b/apps.json index 56a6b69d3..dc9d47c2c 100644 --- a/apps.json +++ b/apps.json @@ -1171,5 +1171,18 @@ {"name":"bledetect.app.js","url":"bledetect.js"}, {"name":"bledetect.img","url":"bledetect-icon.js","evaluate":true} ] + }, + { "id": "snake", + "name": "Snake", + "shortName":"Snake", + "icon": "snake.png", + "version":"0.01", + "description": "The classic snake game. Eat apples and don't bite your tail:", + "tags": "game,fun", + "readme": "README.md", + "storage": [ + {"name":"snake.app.js","url":"snake.js"}, + {"name":"snake.img","url":"snake-icon.js","evaluate":true} + ] } ] diff --git a/apps/snake/ChangeLog b/apps/snake/ChangeLog new file mode 100644 index 000000000..2286a7f70 --- /dev/null +++ b/apps/snake/ChangeLog @@ -0,0 +1 @@ +0.01: New App! \ No newline at end of file diff --git a/apps/snake/README.md b/apps/snake/README.md new file mode 100644 index 000000000..7860dbd88 --- /dev/null +++ b/apps/snake/README.md @@ -0,0 +1,13 @@ +# Snake + +![Screenshot](https://i.ibb.co/XzWrvPL/screenshot.png) + +The legentary classic game is now available on Bangle.js! +Eat apples and don't bite your tail. + +## Controls + +- UP: BTN1 +- DOWN: BTN3 +- LEFT: BTN4 +- RIGHT: BTN5 diff --git a/apps/snake/snake-icon.js b/apps/snake/snake-icon.js new file mode 100644 index 000000000..305061003 --- /dev/null +++ b/apps/snake/snake-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AH4A/ADE3m9hsIusrdhGIM3LtU3g0GAgQxlEwIqBmEAgEGF4QwkF4c3F4MxF4dbF8qLDrYHDre74IABF8QwBLoaPDF8wPKF96/jF/4v/F/4vrrc3AIQsnsIAKF94wiFxgv/R//+m4ABrYALBwIpYFwwAQLC4v/F7gXGF91hACovWFqwwUF4VbF7IwUFzSRVF1gwCF9wwZFyoA/AH4A/AH4A/AGg=")) \ No newline at end of file diff --git a/apps/snake/snake.js b/apps/snake/snake.js new file mode 100644 index 000000000..37b461596 --- /dev/null +++ b/apps/snake/snake.js @@ -0,0 +1,144 @@ +const H = g.getWidth(); +const W = g.getHeight(); +let running = true; +let score = 0; +let d; + +// game world +const gridSize = 40; +const tileSize = 6; +let nextX = 0; +let nextY = 0; + +// snake +const defaultTailSize = 3; +let tailSize = defaultTailSize; +const snakeTrail = []; +let snakeX = 10; +let snakeY = 10; + +// apple +let appleX = Math.floor(Math.random() * gridSize); +let appleY = Math.floor(Math.random() * gridSize); + +function gameStart() { + running = true; + score = 0; +} + +function gameStop() { + g.clear(); + g.setColor("#FFFFFF"); + g.setFont("6x8", 2); + g.drawString("GAME OVER!", W / 2, H / 2 - 20); + g.drawString("Tap to Restart", W / 2, H / 2 + 20); + running = false; + tailSize = defaultTailSize; +} + +function draw() { + if (!running) { + return; + } + + // move snake in next pos + snakeX += nextX; + snakeY += nextY; + + // snake over game world? + if (snakeX < 0) { + snakeX = gridSize - 1; + } + + if (snakeX > gridSize - 1) { + snakeX = 0; + } + + if (snakeY < 0) { + snakeY = gridSize - 1; + } + if (snakeY > gridSize - 1) { + snakeY = 0; + } + + //snake bite apple? + if (snakeX === appleX && snakeY === appleY) { + tailSize++; + score++; + + appleX = Math.floor(Math.random() * gridSize); + appleY = Math.floor(Math.random() * gridSize); + } + + //paint background + g.setColor("#000000"); + g.fillRect(0, 0, H, W); + + // paint snake + g.setColor("#008000"); + + for (let i = 0; i < snakeTrail.length; i++) { + g.fillRect(snakeTrail[i].x * tileSize, snakeTrail[i].y * tileSize, snakeTrail[i].x * tileSize + tileSize, snakeTrail[i].y * tileSize + tileSize); + + //snake bites it's tail? + if (snakeTrail[i].x === snakeX && snakeTrail[i].y === snakeY && tailSize > defaultTailSize) { + gameStop(); + } + } + + // paint apple + g.setColor("#FF0000"); + g.fillRect(appleX * tileSize, appleY * tileSize, appleX * tileSize + tileSize, appleY * tileSize + tileSize); + + // paint score + g.setColor("#FFFFFF"); + g.setFont("6x8"); + g.setFontAlign(0, 0); + g.drawString("Score:" + score, W / 2, 10); + + //set snake trail + snakeTrail.push({ x: snakeX, y: snakeY }); + while (snakeTrail.length > tailSize) { + snakeTrail.shift(); + } +} + +// input +setWatch(() => {// Up + if (d !== 'd') { + nextX = 0; + nextY = -1; + d = 'u'; + } +}, BTN1, { repeat: true }); +setWatch(() => {// Down + if (d !== 'u') { + nextX = 0; + nextY = 1; + d = 'd'; + } +}, BTN3, { repeat: true }); +setWatch(() => {// Left + if (d !== 'r') { + nextX = -1; + nextY = 0; + d = 'l'; + } +}, BTN4, { repeat: true }); +setWatch(() => {// Right + if (d !== 'l') { + nextX = 1; + nextY = 0; + d = 'r'; + } +}, BTN5, { repeat: true }); + +Bangle.on('touch', button => { + if (!running) { + gameStart(); + } +}); + +// render X times per second +var x = 5; +setInterval(draw, 1000 / x); \ No newline at end of file diff --git a/apps/snake/snake.png b/apps/snake/snake.png new file mode 100644 index 000000000..04564a8f7 Binary files /dev/null and b/apps/snake/snake.png differ