diff --git a/apps.json b/apps.json index 3bdc55f07..15f6a0cda 100644 --- a/apps.json +++ b/apps.json @@ -1020,5 +1020,19 @@ {"name":"balltastic.app.js","url":"app.js"}, {"name":"balltastic.img","url":"app-icon.js","evaluate":true} ] + }, + { + "id": "rpgdice", + "name": "RPG dice", + "icon": "rpgdice.png", + "version": "0.01", + "description": "Simple RPG dice rolling app.", + "tags": "game,fun", + "type": "app", + "allow_emulator": true, + "storage": [ + {"name":"rpgdice.app.js","url": "app.js"}, + {"name":"rpgdice.img","url": "app-icon.js","evaluate":true} + ] } ] diff --git a/apps/rpgdice/ChangeLog b/apps/rpgdice/ChangeLog new file mode 100755 index 000000000..7b83706bf --- /dev/null +++ b/apps/rpgdice/ChangeLog @@ -0,0 +1 @@ +0.01: First release diff --git a/apps/rpgdice/app-icon.js b/apps/rpgdice/app-icon.js new file mode 100755 index 000000000..d6fd1fda5 --- /dev/null +++ b/apps/rpgdice/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwgMJgMQgMZzOREaERiERzIACiIVOAIIUCz///ORgIXNIQIAC/4ABJJYsBCogYEAYMQiAWGLAoAJJI8JLAYoCAAgJBJIIwGBohxBJI4YBJIwOFC4w5EC4hdOzIgCyLFDC45hHAAZJDgJAKMQwyBSYSOBxIXGPRTdChOfxChHbpRhBC4P5GAgAOgEZFAKjIBAz1EC5YYJxAvBJ4IXQzGIxEQB4RbPCoOIwEAOKAsCC4QvCFiAXDdwwsMC5eebogVGAALWBC42f/AWLC4zwCUgIEBCxK+DE4bsFC5+f/IrBC4RzHXwkZzATEDgP/RZAXFz5ECf4oXMCYKICC6hABMAQXOgAXBLgLrHRxZfCC6sBCo4XLLwIXBbAgXRMIQAGRxgwChIXVgEQIYimOGAZ6CSgOJC6CrCC4TZBC6IwCC4QWQPQYXKOggAFPQOfC5AWKPQgXGCpR6FOwoWOPQQXDIZYwHC4QVRAAQXBBxgA=")) \ No newline at end of file diff --git a/apps/rpgdice/app.js b/apps/rpgdice/app.js new file mode 100755 index 000000000..2007d6ab0 --- /dev/null +++ b/apps/rpgdice/app.js @@ -0,0 +1,86 @@ +const dice = [4, 6, 8, 10, 12, 20, 100]; +const nFlips = 20; +const delay = 500; + +let dieIndex = 1; +let face = 0; +let rolling = false; + +let bgColor; +let fgColor; + +function getDie() { + return dice[dieIndex]; +} + +function setColors(lastBounce) { + if (lastBounce) { + bgColor = 0xFFFF; + fgColor = 0x0000; + } else { + bgColor = 0x0000 + fgColor = 0xFFFF; + } +} + +function flipFace() { + while(true) { + let newFace = Math.floor(Math.random() * getDie()) + 1; + if (newFace !== face) { + face = newFace; + break; + } + } +} + +function draw() { + g.setColor(bgColor); + g.fillRect(0, 0, g.getWidth(), g.getHeight()); + g.setColor(fgColor); + g.setFontAlign(0, 0); + g.setFontVector(40); + g.drawString('d' + getDie(), 180, 30); + g.setFontVector(100); + g.drawString(face, 120, 120); +} + +function roll(bounces) { + flipFace(); + setColors(bounces === 0); + draw(); + if (bounces > 0) { + setTimeout(() => roll(bounces - 1), delay / bounces); + } else { + rolling = false; + } +} + +function startRolling() { + if (rolling) return; + rolling = true; + roll(nFlips); +} + +function changeDie() { + if (rolling) return; + dieIndex = (dieIndex + 1) % dice.length; + draw(); +} + +Bangle.on('lcdPower',function(on) { + if (on) { + startRolling(); + } +}); + +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +startRolling(); + +// Top button rolls the die, bottom button changes it +setWatch(startRolling, BTN1, {repeat:true}); +setWatch(changeDie, BTN3, {repeat:true}); + +// Show launcher when middle button pressed +setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"}); diff --git a/apps/rpgdice/rpgdice.png b/apps/rpgdice/rpgdice.png new file mode 100755 index 000000000..d14b9c836 Binary files /dev/null and b/apps/rpgdice/rpgdice.png differ