From a67b636d323963240a929109e1c6cac238f71187 Mon Sep 17 00:00:00 2001 From: Willems Davy Date: Sat, 23 Sep 2023 11:30:25 +0200 Subject: [PATCH] Bigger playfield tiles, Removed displaying of widgets (always runs fullscreen), fixex selector tiles display (wrong array type used), updated screenshots to reflect changes --- apps/waternet/ChangeLog | 1 + apps/waternet/app.js | 221 +++++++++++++++++----------------- apps/waternet/metadata.json | 2 +- apps/waternet/screenshot2.png | Bin 2786 -> 2980 bytes apps/waternet/screenshot3.png | Bin 2731 -> 2797 bytes apps/waternet/screenshot4.png | Bin 2921 -> 3504 bytes apps/waternet/screenshot5.png | Bin 3087 -> 2794 bytes 7 files changed, 111 insertions(+), 113 deletions(-) diff --git a/apps/waternet/ChangeLog b/apps/waternet/ChangeLog index 627831462..7c9a36687 100644 --- a/apps/waternet/ChangeLog +++ b/apps/waternet/ChangeLog @@ -1 +1,2 @@ 0.01: Initial version of Waternet port for Bangle JS 2 +0.02: Bigger play field tiles (more readable on watch), Always run without widgets visible \ No newline at end of file diff --git a/apps/waternet/app.js b/apps/waternet/app.js index a2b3d8955..3bd67b48a 100644 --- a/apps/waternet/app.js +++ b/apps/waternet/app.js @@ -76,8 +76,7 @@ const MMCOUNT = 4; const OPSOUND = 0; const OPINPUTRECTS = 1; const OPTHEMING = 2; -const OPWIDGETS = 3; -const OPCOUNT = 4; +const OPCOUNT = 3; const TSMAINMENU = 0; const TSGAMEMODE = 1; @@ -154,6 +153,13 @@ let btnb = false; // -------------------------------------------------------------------------------------------------- // images // -------------------------------------------------------------------------------------------------- +const BLOCKTILESSIXTEEN = { + width:16, + height: 16, + bpp:1, + buffer: require("heatshrink").decompress(atob("hkwAIv8n4BBCY4LDC44TH/4ACD6Y/IAIUAAIwLDH6HwAIIfTP6ZrLCaYLLP6ZrEH55/KD5aBIaIIBBBoIBFBYa/Oh//AIIfTAL4/I+ABBFLh/KNYa/PP5YfLJaZrDH6B/KD5YLDAIf/ABwXHE44fXH5ABOH6AfWP66/PD65/XH6AfWQJDRBAJq/OD64BfM6ABXL5y/PD653fE64XLn/8AIP/ABwTDE44fbH5ABOH6AfWP7ajHD7Z/bH5gfWH48/KIIBNX5wfXH5ABSH5gfWP7a/LD65/bH5gfaADfwAA0PAAwPPEYf/AAQfX+H8AIsPhgBFB6BfWKYZbDmHwAIs/h4BFB57fE/4BCD7X//gBBP7APWGYZ/cOYQfDAH4A//4ACEDkDALo/EELZ7eP7ZbfH5Afa4EAALojggYBdH4ghbPbx/bLb77EAD3wAIUMAAUwAAX84ABBgc8AIMMgYBBmARBhkAn4BBmEAAIQLCD4cw4ABBD55ffh/wAIM//gBBngAKB4YXDD4a+acAIACn49BAIioDA4c8gABBCZAfSA44fHB4cDAIRvDngBCEY4BEH5RXHH54XDOZZDHP6azDh7xBAJBfMG4w/XTZYfM/gBFngACBZYADH5ATHIoYnHL57JIZZIfE4ABCD4YAKDogXCH54HLL6ZLEAIRnHAAcP/gBBT4gRDAoLHIh/wAIIfDWYj7GI4gBKD4cD4ABZL44BDgAtBAIhLHh/AAIJfEOYYBCL45jECYwfEAKTfLmEDAIM8h4BBn4AD/4BBnnPAIQPCAIY/EZ4YBDcYbfGAA6fEQ4TXPT5c/DoIfIOogPCQ44/EFIITBLYYAKB4bzEH5xDEH4YLGH5ABDFIKLEgAVBM5A/EJYQBDgfAAKLfEXJi/JAIYfbb488h4BO54BBn//AIIKDD4jTKOYbrLD57LDT56LIAIQTDh7lBCZIAGCYYBDBZ4PEKYUwngBBmfMAIIHLC4YgEMoIBBmABB/8MAIMAgYBFBYgTCDYYnDT4Y3EhgBBA4YBDH463DAQSMBCAS0DBYYBHBA//n4BCh4BBbA4LDCYYfHGZYfDJYY/LIAIBB+ABCH44LDCYYbDT4n8AIMwAIQHDBYjfKf4gbCn88AIIbDmYBCD5YA==")) +}; + const BLOCKTILES = { width: 10, height: 10, @@ -190,6 +196,15 @@ const SELECTORTILES = { buffer: require("heatshrink").decompress(atob("ACeAgEogEC0AaUhQdGHCozYFSYWCAggApGd9AgEUgEBqAaUgodGHCozYFSYWCAggApGbYA==")) }; +const SELECTORTILESSIXTEEN = { + width: 16, + height: 16, + bpp: 2, + transparent: 0, + palette : new Uint16Array([63519, 0, 65535, 0]), + buffer : require("heatshrink").decompress(atob("AGegAQMKAY+oB4QDDAF43HJZaO2lQDGG/67wAZ4A/XeQDPAH4AkqACBgoDHqgPCAYYAvG45LLR20VAYw3/XeADPAH67yAZ4AwA==")) +}; + const TITLE = { width: 160, height: 50, @@ -441,14 +456,19 @@ function move_sprite(sprite, x, y) { spritePos[sprite][1] = y; } -function drawCursors(clear) { +function drawCursors(clear, useSixteenSize) { if (showCursor == 0) return; for (let i = 0; i < cursorNumTiles; i++) if (spritePos[i][1] < SCREENHEIGHT) - g.drawImage(SELECTORTILES, SCREENOFFSETX + spritePos[i][0], screenOffsetY + spritePos[i][1], { - frame: ((clear ? 8 : 0) + (i % 8)) - }); + if(!useSixteenSize) + g.drawImage(SELECTORTILES, SCREENOFFSETX + spritePos[i][0], screenOffsetY + spritePos[i][1], { + frame: ((clear ? 8 : 0) + (i % 8)) + }); + else + g.drawImage(SELECTORTILESSIXTEEN, 8 + spritePos[i][0], 12 + spritePos[i][1], { + frame: ((clear ? 8 : 0) + (i % 8)) + }); } function hideCursors() { @@ -466,19 +486,21 @@ function showCursors() { showCursor = 1; } -function setCursorPos(cursorNr, xPos, yPos) { +function setCursorPos(cursorNr, xPos, yPos, useSixteenSize) { if (cursorNr > 1) return; - - move_sprite((cursorNr << 3) + 0, ((xPos) * TILESIZE), ((yPos - 1) * TILESIZE)); - move_sprite((cursorNr << 3) + 1, ((xPos + 1) * TILESIZE), ((yPos) * TILESIZE)); - move_sprite((cursorNr << 3) + 2, ((xPos) * TILESIZE), ((yPos + 1) * TILESIZE)); - move_sprite((cursorNr << 3) + 3, ((xPos - 1) * TILESIZE), ((yPos) * TILESIZE)); + let size = TILESIZE; + if (useSixteenSize) + size = 16; + move_sprite((cursorNr << 3) + 0, ((xPos) * size), ((yPos - 1) * size)); + move_sprite((cursorNr << 3) + 1, ((xPos + 1) * size), ((yPos) * size)); + move_sprite((cursorNr << 3) + 2, ((xPos) * size), ((yPos + 1) * size)); + move_sprite((cursorNr << 3) + 3, ((xPos - 1) * size), ((yPos) * size)); //corners - move_sprite((cursorNr << 3) + 4, ((xPos + 1) * TILESIZE), ((yPos - 1) * TILESIZE)); - move_sprite((cursorNr << 3) + 5, ((xPos + 1) * TILESIZE), ((yPos + 1) * TILESIZE)); - move_sprite((cursorNr << 3) + 6, ((xPos - 1) * TILESIZE), ((yPos - 1) * TILESIZE)); - move_sprite((cursorNr << 3) + 7, ((xPos - 1) * TILESIZE), ((yPos + 1) * TILESIZE)); + move_sprite((cursorNr << 3) + 4, ((xPos + 1) * size), ((yPos - 1) * size)); + move_sprite((cursorNr << 3) + 5, ((xPos + 1) * size), ((yPos + 1) * size)); + move_sprite((cursorNr << 3) + 6, ((xPos - 1) * size), ((yPos - 1) * size)); + move_sprite((cursorNr << 3) + 7, ((xPos - 1) * size), ((yPos + 1) * size)); } function initCursors() { @@ -488,11 +510,23 @@ function initCursors() { // -------------------------------------------------------------------------------------------------- // helper funcs // -------------------------------------------------------------------------------------------------- -function set_bkg_tile_xy(x, y, tile) { +function set_bkg_tile_xy(x, y, tile, noScreenOffset) { "RAM"; - g.drawImage(currentTiles, SCREENOFFSETX + x * TILESIZE, screenOffsetY + y * TILESIZE, { - frame: tile - }); + if(!noScreenOffset) + g.drawImage(currentTiles, SCREENOFFSETX + x * TILESIZE, screenOffsetY + y * TILESIZE, { + frame: tile + }); + else + g.drawImage(currentTiles, x * TILESIZE, y * TILESIZE, { + frame: tile + }); +} + +function set_bkg_tile_xy_sixteen(x, y, tile) { + "RAM"; + g.drawImage(BLOCKTILESSIXTEEN, 8 + x * 16, 12+ y * 16, { + frame: tile + }); } function set_bkg_data(tiles) { @@ -1440,51 +1474,50 @@ function drawLevelSelect(partial) { if (partial > 2) { g.clearRect(Bangle.appRect); //LEVEL: - printMessage(MAXBOARDWIDTH, 0, "LEVEL:"); + printMessage(0, 15, "LEVEL:", true); } if (partial == 2) { //clear parts of loading text - g.setColor(g.getBgColor()); - g.fillRect(SCREENOFFSETX + (boardX + boardWidth) * TILESIZE, screenOffsetY + 3 * TILESIZE, SCREENOFFSETX - 1 + (boardX + MAXBOARDWIDTH + 5) * TILESIZE, screenOffsetY - 1 + 6 * TILESIZE); + printMessage(((16 - 10) >> 1), (MAXBOARDHEIGHT >> 1) - 1, " "); + printMessage(((16 - 10) >> 1), (MAXBOARDHEIGHT >> 1) - 0, " "); + printMessage(((16 - 10) >> 1), (MAXBOARDHEIGHT >> 1) + 1, " "); } //[LEVEL NR] 2 chars if (partial == 2) - set_bkg_tile_xy(MAXBOARDWIDTH + 4, 1, EMPTY); + set_bkg_tile_xy(7, 15, EMPTY, true); - printNumber(MAXBOARDWIDTH + 4, 1, selectedLevel, 2); + printMessage(6, 15, selectedLevel.toString(), true); if (partial > 2) { //B:BACK - printMessage(MAXBOARDWIDTH, 6, "BTN:"); - printMessage(MAXBOARDWIDTH, 7, "BACK"); + printMessage(9, 16, "BTN:BACK", true); } if (partial > 1) { //A:PLAY - printMessage(MAXBOARDWIDTH, 4, "TOUCH:"); - printMessage(MAXBOARDWIDTH, 5, "PLAY"); + printMessage(0, 16, "TCH:PLAY", true); } //Locked & Unlocked keywoard let tmpUnlocked = levelUnlocked(gameMode, difficulty, selectedLevel - 1); if (!tmpUnlocked) - printMessage(MAXBOARDWIDTH, 2, "LOCKED"); + printMessage(9, 15, "LOCKED", true); else - printMessage(MAXBOARDWIDTH, 2, "OPEN "); + printMessage(9, 15, "OPEN ", true); if (partial > 2) { //Draw arrows for vertical / horizontal movement if (gameMode != GMROTATE) { for (let x = 0; x != boardWidth; x++) { - set_bkg_tile_xy(boardX + x, boardY - 1, ARROWDOWN); - set_bkg_tile_xy(boardX + x, boardY + boardHeight, ARROWUP); + set_bkg_tile_xy_sixteen(boardX + x, boardY - 1, ARROWDOWN); + set_bkg_tile_xy_sixteen(boardX + x, boardY + boardHeight, ARROWUP); } for (let y = 0; y != boardHeight; y++) { - set_bkg_tile_xy(boardX - 1, boardY + y, ARROWRIGHT); - set_bkg_tile_xy(boardX + boardWidth, boardY + y, ARROWLEFT); + set_bkg_tile_xy_sixteen(boardX - 1, boardY + y, ARROWRIGHT); + set_bkg_tile_xy_sixteen(boardX + boardWidth, boardY + y, ARROWLEFT); } } } @@ -1494,11 +1527,11 @@ function drawLevelSelect(partial) { //Draw arrows for vertical / horizontal movement if (gameMode != GMROTATE) { for (let x = 0; x != boardWidth; x++) { - set_bkg_tile_xy(boardX + x, boardY + boardHeight, ARROWUP); + set_bkg_tile_xy_sixteen(boardX + x, boardY + boardHeight, ARROWUP); } for (let y = 0; y != boardHeight; y++) { - set_bkg_tile_xy(boardX + boardWidth, boardY + y, ARROWLEFT); + set_bkg_tile_xy_sixteen(boardX + boardWidth, boardY + y, ARROWLEFT); } } } @@ -1506,7 +1539,7 @@ function drawLevelSelect(partial) { let i16 = 0; for (let yy = 0; yy < boardHeight; yy++) { for (let xx = 0; xx < boardWidth; xx++) { - set_bkg_tile_xy(boardX + xx, boardY + yy, level[i16 + xx]); + set_bkg_tile_xy_sixteen(boardX + xx, boardY + yy, level[i16 + xx]); } i16 += boardWidth; } @@ -1628,7 +1661,7 @@ function formatInteger(valinteger) { } //print a number on levelselect or game screen -function printNumber(ax, ay, aNumber, maxDigits) { +function printNumber(ax, ay, aNumber, maxDigits, noScreenOffset) { "RAM"; const buffSize = 10; @@ -1639,12 +1672,12 @@ function printNumber(ax, ay, aNumber, maxDigits) { for (let c = 0; c < maxFor; c++) { if (ret.string.charAt(buffSize - ret.digits + c) == '') return; - set_bkg_tile_xy(ax + (maxDigits - ret.digits) + c, ay, ret.string.charCodeAt(buffSize - ret.digits + c) + 32); + set_bkg_tile_xy(ax + (maxDigits - ret.digits) + c, ay, ret.string.charCodeAt(buffSize - ret.digits + c) + 32, noScreenOffset); } } //print a message on the title screen on ax,ay, the tileset from titlescreen contains an alphabet -function printMessage(ax, ay, amsg) { +function printMessage(ax, ay, amsg, noScreenOffset) { "RAM"; let aCode = 'A'.charCodeAt(0); let zCode = 'Z'.charCodeAt(0); @@ -1722,7 +1755,7 @@ function printMessage(ax, ay, amsg) { } break; } - set_bkg_tile_xy(ax + p, ay, tile); + set_bkg_tile_xy(ax + p, ay, tile, noScreenOffset); } } @@ -1754,8 +1787,6 @@ function validateSaveState() { } if (options[OPSOUND] > 1) return 0; - if (options[OPWIDGETS] > 1) - return 0; if (options[OPINPUTRECTS] > 1) return 0; if (options[OPTHEMING] > 1) @@ -1785,7 +1816,6 @@ function initSaveState() { for (let i = 0; i < DIFFCOUNT; i++) levelLocks[(j * DIFFCOUNT) + i] = 1; //1st level unlocked options[OPSOUND] = 1; - options[OPWIDGETS] = 1; options[OPINPUTRECTS] = 0; options[OPTHEMING] = 1; } @@ -1819,15 +1849,6 @@ function isThemingOnSaveState() { return options[OPTHEMING] == 1; } -function setWidgetsOnSaveState(value) { - options[OPWIDGETS] = value; - saveSaveState(); -} - -function isWidgetsOnSaveState() { - return options[OPWIDGETS] == 1; -} - function setInputRectsOnSaveState(value) { options[OPINPUTRECTS] = value; saveSaveState(); @@ -1934,13 +1955,6 @@ function drawMenuItems(clear) { } else { printMessage(3, 6, "THEMING OFF"); } - if (isWidgetsOnSaveState()) { - printMessage(3, 7, "WIDGETS ON"); - } else { - printMessage(3, 7, "WIDGETS OFF"); - } - printMessage(1, 9, "RESTART NEEDED"); - printMessage(2, 10, "FOR WIDGETS"); break; } } @@ -2107,12 +2121,6 @@ function titleScreen() { needRedraw = 1; redrawPartial = 2; break; - case OPWIDGETS: - setWidgetsOnSaveState(!isWidgetsOnSaveState()); - needRedraw = 1; - //needs 3 because text crosses input rect lines - redrawPartial = 3; - break; case OPINPUTRECTS: setInputRectsOnSaveState(!isInputRectsOnSaveState()); needRedraw = 1; @@ -2233,54 +2241,45 @@ function drawGame(partial) { //LEVEL: if (partial > 2) { - printMessage(MAXBOARDWIDTH, 0, "LEVEL:"); + printMessage(0, 15, "LEVEL:", true); //[LEVEL NR] 2 chars - printNumber(MAXBOARDWIDTH + 4, 1, selectedLevel, 2); + printMessage(6, 15, selectedLevel.toString(), true); } //MOVES: if (partial > 2) - printMessage(MAXBOARDWIDTH, 2, "MOVES:"); + printMessage(9, 15, "MVS:", true); if (partial > 1) - printNumber(MAXBOARDWIDTH + 1, 3, moves, 5); + printMessage(13, 15, moves.toString(), true); //A:XXXXXX (XXXXXX="ROTATE" or XXXXXX="SLIDE " or XXXXXX="ROSLID") if (partial > 2) { switch (gameMode) { case GMROTATE: - printMessage(MAXBOARDWIDTH, 4, "TOUCH:"); - printMessage(MAXBOARDWIDTH, 5, "ROTATE"); + printMessage(0, 16, "TCH:ROTA BTN:BACK", true); break; case GMSLIDE: - printMessage(MAXBOARDWIDTH, 4, "TOUCH:"); - printMessage(MAXBOARDWIDTH, 5, "SLIDE"); + printMessage(0, 16, "TCH:SLID BTN:BACK", true); break; case GMROTATESLIDE: - printMessage(MAXBOARDWIDTH, 4, "TOUCH:"); - printMessage(MAXBOARDWIDTH, 5, "ROSLID"); + printMessage(0, 16, "TCH:ROSL BTN:BACK", true); break; } } - if (partial > 2) { - //B:BACK - printMessage(MAXBOARDWIDTH, 6, "BTN:"); - printMessage(MAXBOARDWIDTH, 7, "BACK"); - } - if (partial > 2) { //Draw arrows for vertical / horizontal movement if (gameMode != GMROTATE) { for (let x = 0; x != boardWidth; x++) { - set_bkg_tile_xy(boardX + x, boardY - 1, ARROWDOWN); - set_bkg_tile_xy(boardX + x, boardY + boardHeight, ARROWUP); + set_bkg_tile_xy_sixteen(boardX + x, boardY - 1, ARROWDOWN); + set_bkg_tile_xy_sixteen(boardX + x, boardY + boardHeight, ARROWUP); } for (let y = 0; y != boardHeight; y++) { - set_bkg_tile_xy(boardX - 1, boardY + y, ARROWRIGHT); - set_bkg_tile_xy(boardX + boardWidth, boardY + y, ARROWLEFT); + set_bkg_tile_xy_sixteen(boardX - 1, boardY + y, ARROWRIGHT); + set_bkg_tile_xy_sixteen(boardX + boardWidth, boardY + y, ARROWLEFT); } } } @@ -2292,7 +2291,7 @@ function drawGame(partial) { if (partial > 1) { for (yy = 0; yy < boardHeight; yy++) { for (xx = 0; xx < boardWidth; xx++) { - set_bkg_tile_xy(boardX + xx, boardY + yy, level[i16 + xx]); + set_bkg_tile_xy_sixteen(boardX + xx, boardY + yy, level[i16 + xx]); } i16 += boardWidth; } @@ -2307,7 +2306,7 @@ function initGame() { setBlockTilesAsBackground(); //set sprite for selector / cursor initCursors(); - setCursorPos(0, boardX + selectionX, boardY + selectionY); + setCursorPos(0, boardX + selectionX, boardY + selectionY, true); showCursors(); redrawLevelDoneBit = 0; needRedraw = 1; @@ -2331,7 +2330,7 @@ function doPause() { function doUnPause() { paused = 0; setSoundOn(wasSoundOn); - setCursorPos(0, boardX + selectionX, boardY + selectionY); + setCursorPos(0, boardX + selectionX, boardY + selectionY, true); showCursors(); } @@ -2347,19 +2346,19 @@ function game() { //if not touching border on bottom if (selectionY + 1 < boardHeight + posAdd) { //clear cursor - drawCursors(true); + drawCursors(true, true); selectionY += 1; needRedraw = 1; redrawPartial = 0; } else { //set to border on top //clear cursor - drawCursors(true); + drawCursors(true, true); selectionY = -posAdd; needRedraw = 1; redrawPartial = 0; } - setCursorPos(0, boardX + selectionX, boardY + selectionY); + setCursorPos(0, boardX + selectionX, boardY + selectionY, true); } } else { if (dragup) { @@ -2368,19 +2367,19 @@ function game() { playGameMoveSound(); if (selectionY - 1 >= -posAdd) { //clear cursor - drawCursors(true); + drawCursors(true, true); selectionY -= 1; needRedraw = 1; redrawPartial = 0; } else { //set to border on bottom //clear cursor - drawCursors(true); + drawCursors(true, true); selectionY = boardHeight - 1 + posAdd; needRedraw = 1; redrawPartial = 0; } - setCursorPos(0, boardX + selectionX, boardY + selectionY); + setCursorPos(0, boardX + selectionX, boardY + selectionY, true); } } else { if (dragright) { @@ -2389,19 +2388,19 @@ function game() { //if not touching border on right if (selectionX + 1 < boardWidth + posAdd) { //clear cursor - drawCursors(true); + drawCursors(true, true); selectionX += 1; needRedraw = 1; redrawPartial = 0; } else { //set to border on left //clear cursor - drawCursors(true); + drawCursors(true, true); selectionX = -posAdd; needRedraw = 1; redrawPartial = 0; } - setCursorPos(0, boardX + selectionX, boardY + selectionY); + setCursorPos(0, boardX + selectionX, boardY + selectionY, true); } } else { if (dragleft) { @@ -2410,18 +2409,18 @@ function game() { //if not touching border on left if (selectionX - 1 >= -posAdd) { //clear cursor - drawCursors(true); + drawCursors(true, true); selectionX -= 1; needRedraw = 1; redrawPartial = 0; } else { //set to border on right //clear cursor - drawCursors(true); + drawCursors(true, true); selectionX = boardWidth - 1 + posAdd; needRedraw = 1; redrawPartial = 0; } - setCursorPos(0, boardX + selectionX, boardY + selectionY); + setCursorPos(0, boardX + selectionX, boardY + selectionY, true); } } } @@ -2510,7 +2509,7 @@ function game() { randomSeedGame = Date.now(); initLevel(randomSeedGame); //show cursor again (it's actually to early but i'm not fixing that) - setCursorPos(0, boardX + selectionX, boardY + selectionY); + setCursorPos(0, boardX + selectionX, boardY + selectionY, true); showCursors(); needRedraw = 1; redrawPartial = 3; @@ -2521,7 +2520,7 @@ function game() { unlockLevel(gameMode, difficulty, selectedLevel - 1); initLevel(randomSeedGame); //show cursor again (it's actually to early but i'm not fixing that) - setCursorPos(0, boardX + selectionX, boardY + selectionY); + setCursorPos(0, boardX + selectionX, boardY + selectionY, true); showCursors(); needRedraw = 1; redrawPartial = 3; @@ -2564,7 +2563,7 @@ function game() { if (needRedraw) { drawGame(redrawPartial); - drawCursors(); + drawCursors(false, true); needRedraw = 0; requiresFlip = 1; } @@ -2578,6 +2577,8 @@ function setThemingOn(value) { if (value && (g.theme.bg != g.theme.fg)) { SELECTORTILES.palette[1] = g.theme.bg; SELECTORTILES.palette[2] = g.theme.fg; + SELECTORTILESSIXTEEN.palette[1] = g.theme.bg; + SELECTORTILESSIXTEEN.palette[2] = g.theme.fg; TITLE.palette[3] = g.theme.bg; TITLE.palette[2] = g.theme.bg; TITLE.palette[1] = g.theme.fg; @@ -2590,6 +2591,8 @@ function setThemingOn(value) { } else { SELECTORTILES.palette[1] = 0x0000; SELECTORTILES.palette[2] = 0xFFFF; + SELECTORTILESSIXTEEN.palette[1] = 0x0000; + SELECTORTILESSIXTEEN.palette[2] = 0xFFFF; TITLE.palette[3] = 0x0000; TITLE.palette[2] = 0x0000; TITLE.palette[1] = 0xFFFF; @@ -2616,12 +2619,6 @@ function setup() { initSaveState(); //initSound(); setSoundOn(isSoundOnSaveState()); - if (isWidgetsOnSaveState()) { - //need to call this first otherwise - Bangle.loadWidgets(); - //only once they update themselves - Bangle.drawWidgets(); - } setThemingOn(isThemingOnSaveState()); //has to be called after applying theming setBlockTilesAsBackground(); @@ -2795,7 +2792,7 @@ function btnPressed() { //initialize spritepos arrays for (let i = 0; i < cursorNumTiles; i++) - spritePos.push(new Int8Array(2)); + spritePos.push(new Int16Array(2)); //clear one time entire screen g.clear(); diff --git a/apps/waternet/metadata.json b/apps/waternet/metadata.json index b372f6882..59170617a 100644 --- a/apps/waternet/metadata.json +++ b/apps/waternet/metadata.json @@ -1,7 +1,7 @@ { "id": "waternet", "name": "Waternet", "shortName":"Waternet", - "version":"0.01", + "version":"0.02", "description": "Puzzle game where water needs to flow through pipes by sliding or rotating them", "icon": "app.png", "screenshots": [{"url":"screenshot2.png"},{"url":"screenshot1.png"},{"url":"screenshot3.png"},{"url":"screenshot4.png"},{"url":"screenshot5.png"},{"url":"screenshot6.png"}], diff --git a/apps/waternet/screenshot2.png b/apps/waternet/screenshot2.png index 503e30a1c626836fc50544d4b494cd2b9662f14e..cdfbc6052e10c399a5b412889af221de98a1e4ab 100644 GIT binary patch literal 2980 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 bH6m4%4NmKHaQ69rM}gBP-JNP31JeErxF`j; diff --git a/apps/waternet/screenshot4.png b/apps/waternet/screenshot4.png index 4725c7a709a84ec2cddad6ee2dd3622f153b7556..7c978fa9fb54987e4a4f0fc890f3af4d8f740b76 100644 GIT binary patch delta 3490 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 F`Cp=ft6Km7 literal 2921 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 JakW@t!oSg4N?ZT{ diff --git a/apps/waternet/screenshot5.png b/apps/waternet/screenshot5.png index b78ee209451c72d34469c70e463b27021777b7d5..fded509ca9d6a0db100c326d03117aac389857a7 100644 GIT binary patch literal 2794 zcmbVOX;70{7JXmBq5%b45ky(k0a-+`5s0!2bVOuN0?L-|VKV{(BG7=zhwTP5(4(@+ zCPW0ns(_)1m?$DPiwJ~QWuU^$X_uO+|va2&@ z8%h-g0NCbm+Rk0#>%N{XG7?)$d+#T4&}DbbDNyrv-wXh#hYof&*f>94!5lu%Ox|vU zPySeFuQ_-9Xyoxv>)J!YbAR(z59_2UibP*l7RNP2#nx`pB1A-Q*N!zO2*_OTLxG5y z&pXUPtMvtG&=kF~MIHX}K?4H#oV+Tfz%+C{4}l{Eme*tnDmv8wWIJoT$VRS@w@*#* zwk~gC(C5Wur(>c*Qkl~pAnMq%lWROw1|_7)!qEC7_+*j`QWb_&V59m^mi^wAgDutc zTVbnZ3&p89f&!mdAl_>~+!z(b`*9PB)Yt#UK`6qz7J{n{U z7=>nRhQyGGPYy0jjUU*ixm_FVuUa59_e3U;@@GaJWyT{)|NRMuV zM;LR9v!=sE26pbfW1vY$7dia?D9=R}-Hax4`k#rLe=>!_&DkQ%s`AXMTR&@eE14z@ z);$4@f`JLD#^$e+QJYBaAj-LxNu0#v6dQ~1qdUr5Tprg?s`>&}V$BmI_hBE%-xd1g z1UMuC?IGcAH-y$TlmvO9mTKHT_d8qcOXIZKgEjT6AX;UVBJTwSeUNONj*9_;(gw5M z1BRo?#fTk{O52_c=xEtmuyNJWW)=4ZcVfm$#M)Hd_@8AalPH-}`}kp2_t}-(7aPaTpn9R*R4S<^-HI5@?}5C0 z_OR@rIx0(r9tG&F9N~AXBb%`+v8%FNn_Fn(W1vc}lnohz%W}otnJ$&%eo3Uwb)zbs zr(e0IXz$B5v?3*LhlKoy~41Q>$)8}B}(l5cn7U*bdA+2tJ40I8&-ia2li z&`w0$S2^E-xbvho<5DRNA9mZq(;Je=;Bi!r$_^T5tG%uX#rUN?Up2X1K!gMGB zXx*WJ%fJ~W&vba9ohP|RkOU^|#1qUNU~u{Af+NoNiRj!Wd)aR!SmD{v3i8awGS19k z1aZPEkXDVrBontju#5{3QaT=K2dp)fpeYh!;ck87ZS*}a`R1N0D*77l^9eb=2GC7j(i`MuE_ z-mOT=oin-;k#vPLo)~Z_rR=%{~2aIl=UnAeQ0?4HcXCF;MlCq)8_m`t! zjD>uY0yLYNM~rm|{d~tbK|q00UmG8MWcJ7d9O` zRZgJB0CUGAN4lHzuR#J`k-_gl?F=2Kz~&P*h#naNOA2s}RAjlGyH6EZO9~y|<$81- zgLCEUs={Pl=0cq>JSO_8(2EP>1B+j>LY6OS(UIka@V89270AFFvN_>!48Q1}{&9cO zZMlOedFmlTtbi_=AVv!UYw z4XF%{RNxdA!d|i&J+#4zto<}16A?W={GBEhOBqosxa~3JS$hmKH}O=K>5r;8qY3D5 zNPJlWc&=MVL}aw_A6TtbZ=YwO@D?Pn+eif}=bWlK`6@uc1~=)sy0gEzdp^hDx?G2^ z&FZeA7PXJk9%;c>1Yq>UhZ59iLh6H?Q)?3aiL7~kBXVkZn(QOdRKCu9p*7t)tX3t} zs;k}%3K!Qfzd?8p_|p1K6=F zgA1w1oY4o&(tgYmkVlp(0dC*S!8mX;>HpZh|Kr&vsEYJ^|6sNsTW#P^FrvDQ zCWI^s1%V;>NT=vUJZ*_B!2&PeT)!8p!g2jD?7QGr6UtQ}%4yB+FtPpE&O?F>k0v>; zTf&jX@4I|H1wFkwpiBS0g|i|QXFDc*?yPa0a?R^^S7x%ciVR)_fAWD76lg@oWyQRa zSu9+i*=)=@o7siWIXe=rhy9I}6VJn1#Xi#)FrX@gGTQ>5N9U!?m0V=>o>`{qz1`Ik z{D-GPRYr_ksSG!jipo!Ml8Z53wpglm4*E+SeIKSCAxiG{kmAcX(^}5K4X=w4 ziF~s1xO~9?La`v%udSLWY`EcS=gJQ{Gu^Re?+fbo^GczgIc_}uv57O52dr7G)v85* z=c6{V-VP=U<6ruS-W4CnK`m{4sdue0{2)uqn1187_5m+D2~)GqG%px8HeM8cp?~L+O(qhf3e@XyQIPTy|ap#Yy=q9+Us1V1DIt2 l*U-(o0QU$x;-r0&7_gbOYtg5*<0PL~;9&1;S96MR?Vm6>K}Y}q literal 3087 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 b?S|04ATnzz+kJCk`@;vE32u&McyjW;#!$H|