Merge pull request #2623 from Le-Kat/master

multiple dice roller app
master
Gordon Williams 2023-03-01 08:07:11 +00:00 committed by GitHub
commit 44a19f76b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 254 additions and 1 deletions

32
apps/multidice/ChangeLog Normal file
View File

@ -0,0 +1,32 @@
0.90: got most of the features done, lacking some polish and real-hardware testing
1.00: overhauled the whole app, made some margins larger to be easier to tap on
1.01: fixed bug that caused rolled dice on the right of screen to be writ off-screen
1.02: added vibration when dice is rolled
1.03: vibration caused the accelerometer to never stop
1.04: decreased vibration strength
1.05: toggled the acceleration handler to prevent infinite buzz loop
1.06: increased vibration again
1.07: IDK how to use promises properly
1.08: still trying to fix the lack of vibrations
1.09: hopefully now it's fixed?
1.10: not having web bluetooth to debug is a PAIN
1.11: decreased vibration time, decreased accel requirement
1.12: issue with app calling roll function too many times at startup
1.13: added a delay after the buzzer stops to prevent multi-rolling
1.14: made the delay needlessly long to see if it even does anything
1.15: moved accel & vibration commands to the accelHandler function
1.16: enabled button usage & temporarily disabled acceleration
1.17: made changes to when accelHandler gets overwritten, temporarily disabled button usage
1.18: decided to keep around the button even while testing, disabled all safety round the accelHandler self-triggering
1.19: added longer delay before resetting accelHandler
1.20: removed all traces of accel b/c I've given up
1.21: added a drawWidgets command to see if I have the padding right
1.22: ok the buzzing *might* work now
1.23: forgot to resolve the promise
1.24: fixed dumb errors
1.25: god I hope this works
1.26: trying to add timeout after it's done buzzing... again
1.27: OH GOD IT FINALLY WORKS
1.28: increased vibration strength, added some comments, & some QOL
1.29: changed image
1.30: changed image, again

20
apps/multidice/README.md Normal file
View File

@ -0,0 +1,20 @@
# multiple dice roller
roll anywhere from 1-8 dice at the same time.
## Usage
![startup.png](startup.png)
On the menu screen: tap on the dice to change what variant is selected, & shake/or press BTN to roll the dice
![single_rolled.png](single_rolled.png)
On the dice screen: tap anywhere on the screen to go back to the menu, or shake/or press BTN to roll the dice
## Features
roll anywhere from 1-8 dice (d4, d6, d8, d10, d12, d20, & d percentile). You can select multiple different dice at the same time
![many_selected.png](many_selected.png)
![many_rolled.png](many_rolled.png)
## Controls
App uses touchscreen to cycle through different dice, and accelerometer/BTN to roll them

View File

@ -0,0 +1 @@
atob("MDABAAAAA8AAAAAAB+AAf//+DDAAwAACGBgAwAADMAwAwAADYAYAgAAAwYMAgAABg+GAgAADBiDAgDwGBiBggH4MAmAwgMMYA8AYgIEwAAAMgIFg8AeGgIHBkAyDgMNBGAjDgH5BGAjDgDxh8A+DgAAwYAMGgAAYAYAMgAAMA+AYwAAGBiAwwAADBiBgwAADgmDAf//+w8Gwf///4AM8wAADMAYEzwADGA3En4ABDBvkmYABBjIkmYABI+IkH4ABPAPkjwABHAHEgDwBAHAEAH4BAPgEgGYBAIgEgGYBAIgEgH4BAPgEgDwBAHAEgADxHAHEgAH5PgPkgAGZIgIkgAGZIgIkgAH5PgPkwADzHAHEwAADAAAEcAAPwAAcP//8///w")

185
apps/multidice/app.js Normal file
View File

@ -0,0 +1,185 @@
var menu = true; // default to have the selection menu open
const DICE_ARRAY = [0, 4, 6, 8, 10, 12, 20, 100]; // 0 means nothing selected
const SELECTION_ARRAY = [6, 0, 0, 0, 0, 0, 0, 0]; // default to selecting a single d20
// function to draw the selection menu
function drawMenu() {
stringArr = new Array ("", "", "", "", "", "", "", "");
for (i = 0; i < 8; i++) {
if (SELECTION_ARRAY [i] != 0) {
stringArr [i] = "" + DICE_ARRAY [SELECTION_ARRAY [i]];
} else {
stringArr [i] = " . "; // more clearly defines where the user can tap
}
}
g.clear();
g.setFont ("Vector", 40);
// " ".slice(-3) left-pads all numbers with spaces
g.drawString ((" " + stringArr [0]).slice (-3), 5, 10);
g.drawString ((" " + stringArr [1]).slice (-3), 5, 50);
g.drawString ((" " + stringArr [2]).slice (-3), 5, 90);
g.drawString ((" " + stringArr [3]).slice (-3), 5, 130);
g.drawString ((" " + stringArr [4]).slice (-3), 96, 10);
g.drawString ((" " + stringArr [5]).slice (-3), 96, 50);
g.drawString ((" " + stringArr [6]).slice (-3), 96, 90);
g.drawString ((" " + stringArr [7]).slice (-3), 96, 130);
}
// function to change what dice is selected in the menu
function touchHandler (button, xy) {
if (! menu) { // if menu isn't open, open it & return
menu = true;
drawMenu();
return;
}
if (xy.x <= 87) { // left
if (xy.y <= 43) { // first
selection = 0;
} else if (xy.y <= 87) { // second
selection = 1;
} else if (xy.y <= 131) { // third
selection = 2;
} else { // fourth
selection = 3;
}
} else { // right
if (xy.y <= 43) { // first
selection = 4;
} else if (xy.y <= 87) { // second
selection = 5;
} else if (xy.y <= 131) { // third
selection = 6;
} else { // fourth
selection = 7;
}
}
if (SELECTION_ARRAY [selection] == SELECTION_ARRAY.length - 1) { // if last dice is selected, go back to first
SELECTION_ARRAY [selection] = 0;
} else {
SELECTION_ARRAY [selection] += 1;
}
drawMenu();
}
function accelHandler (xyz) {
if (xyz.diff >= 0.3) {
menu = false;
mutex (rollDice).catch (() => {
return; // not necessary, but prevents spamming the logs
});
}
}
// returns a resolved promise if no other mutex call is active, all further ones return a rejected one
let lock = false;
function mutex (functionRef) {
if (lock) {
return Promise.reject (new Error ("mutex is busy"));
}
lock = true;
return new Promise ((resolve, reject) => {
functionRef().then ((result) => {
lock = false;
resolve (result);
}).catch ((error) => {
lock = false;
reject (error);
});
});
}
// function to roll all selected dice, and display them
function rollDice() {
resultsArr = new Uint8Array (8);
for (i = 0; i < 8; i++) {
if (SELECTION_ARRAY [i] != 0) {
resultsArr [i] = random (DICE_ARRAY [SELECTION_ARRAY [i]]);
}
}
g.clear();
g.setFont ("Vector", 40);
for (i = 0; i < 4; i++) {
if (SELECTION_ARRAY [i] != 0) {
g.drawString ((" " + resultsArr [i]).slice (-3), 5, 10 + 40 * i);
}
}
for (i = 4; i < 8; i++) {
if (SELECTION_ARRAY [i] != 0) {
g.drawString ((" " + resultsArr [i]).slice (-3), 96, 10 + 40 * (i - 4));
}
}
return vibrate();
}
// triggers the vibration, then pauses before returning
function vibrate() {
return new Promise ((resolve, reject) => {
return Bangle.buzz (50, 1).then ((value) => {
setTimeout (() => {
resolve (value);
}, 200);
});
});
}
// returns a integer [1, max]
function random (max) {
return Math.round (Math.random() * (max - 1) + 1);
}
drawMenu();
Bangle.on ('touch', touchHandler);
Bangle.on ('accel', accelHandler);
setWatch (function() {
menu = false;
mutex (rollDice);
}, BTN, {repeat: true, edge: "falling", debounce: 10});

BIN
apps/multidice/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,15 @@
{ "id": "multidice",
"name": "multiple dice roller",
"shortName":"multidice",
"version":"1.30",
"description": "roll anywhere from 1-8 dice at the same time",
"icon": "app.png",
"tags": "tool,game",
"supports" : ["BANGLEJS2"],
"readme": "README.md",
"allow_emulator": true,
"storage": [
{"name":"multidice.app.js","url":"app.js"},
{"name":"multidice.img","url":"app-icon.js","evaluate":true}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
apps/multidice/startup.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

2
core

@ -1 +1 @@
Subproject commit 0d02ff3763783d166ff84906af038420736aabfc
Subproject commit 893c2dbbe5a93fbb80d035a695663b4f4cca8875