diff --git a/apps/pokewalk/README.md b/apps/pokewalk/README.md new file mode 100644 index 000000000..f2b77d67f --- /dev/null +++ b/apps/pokewalk/README.md @@ -0,0 +1,8 @@ +# PokeWalk + +A very simple watchface featuring a Pokemon trainer on a walk. + +![](screenshot.png) + +Relive your childhood using this simple watchface based on a Gameboy Classic version of Pokemon. +Widgets not supported diff --git a/apps/pokewalk/app-icon.js b/apps/pokewalk/app-icon.js new file mode 100644 index 000000000..d5ee64a73 --- /dev/null +++ b/apps/pokewalk/app-icon.js @@ -0,0 +1 @@ +atob("MDDD/9Bs3P9iCNDyE6YIKc3BmGrZttt/mEgL85vfZZtttiC5tt7Ztts28gBKg9sLW1uytiBtttu50VvCqpttALobW8Xm24LNttu3Am0Cy7Mlviok66SCAWrN71u200kgLZtktrNkG4SQkgK20m0EykkD49tvl1tmSLAAQCoE0ikQkkkJb5tuxXOEEZcDgaoEm8lCEkC+6ttt2gSSQZKgXbagkmBIAAUTbbN17jgAfa1arAHocAfIQlCfbbWy0BAXbKLPegkJL5Xww2SC7bWQUC0epULbeiEJMtviEk8RW7Ya0KrbbbZakAQNkvngkHPeK3bbW3bNttt5IAC1t8keGFvXwW6pLbNttklvZAVtOI8ASJveH+0BbNtttttlvWvO2E9AAB++Qwyq5tttttttva7Z1cHUD1XCA0kWttttttttt7LN0ny5NklAAClVtttttttttvZZACjpts4pt0K1tttttttttvbCAAAa5tkvNPq5tttttttttt7KAAdZttt63matttttJJtttt7VVBRXNtvbLxW5tttJJJNttt7ZN0G77Nuq/5W5tttIwlJttt7ZZ7yv7W2RZtXbNtpQkhJtttvZQMSq20mCrO3apJJEkmJJLN7ZDvXAQkkKSdJJJJJEk/pJJJJJDbj0AkgZkhJJLwpIgFI1JJJJD7KSgAdPAxSEkklJEpIkkkyVCVMm239QEdAEkkmpJJEkkkyDjrMm+6BUcFAQkkklJIkkkkwACrZAfbC7i40CEkkkkkkkkmQXPLbNe21bXUoAEkkkkkkkkmAJukrJttvbbT1AAkkkkkkkkwANEklYkklu7gJAAEkkkkkkmABQcEmkkkky6+DIAAEkkkkkwAIW30Gkm2kkfbW1AACEkkkyADoK21EC2G3kfptvIAAASSQAABAEkqwE2mkkes7bZUAAAAAABIAEkmLgm0kgVtt7bK0AAAAcKCcEkknaEknZZttt25JfgDiriT2o38lbYnba3Ntt7ZZJJJLrg0dK0m33bbbJY3Wt7Vbr/3bXgnrN028C7bZRbREqqhZsiD23efbN0CVbXWoK3Z00wBN5kltbbZbNvfZk58wE25yEgDZtkl55Lj7NtvZts83gi18AALNt3NzLWAK5tvVtkgGAAX/8VJVuw1vZ6gW37b1umk0L6X23oUVWk1uDbwVLgX8=") diff --git a/apps/pokewalk/app.js b/apps/pokewalk/app.js new file mode 100644 index 000000000..fdad9e6e0 --- /dev/null +++ b/apps/pokewalk/app.js @@ -0,0 +1,104 @@ +const sprites = [ + atob("EBWDASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSQACSSSSSP5ASSSSR/JICSSSJJJJASSSJIBJASSSBB+IASSSOB+BwSSSR+B+CSSSSP/wSSSSSQACSSQ=="), + atob("EBWDASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSASSSSSSSIASSSSSRJIASSQCRJJIASICNJJAABIBthAABJARgAAJIACSBJAJJACSSJJBIACSSQJIAASSSSQAASSSSSSQSSSQ=="), + atob("EBWDASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSAACSSSSRthgSSSSNsNgSSSRttsMCSSRtttsCSSNtddsCSRtsNdsCSRLJbJASSSLJJACSSSSALZASSSSAKJASSSRIBIACSSQIKBRQSSSARaACSSSSSACSQ=="), + atob("EBWDASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSACSSSSSBhgCSSSRthtgSSSNthtgSSSNtttsCSBNtttsCRJNv9tsCRJJh9tgCRJJNtgMCSJJAANhgSQAMNthgSSSNhsNgCSSRsBsMCSSSAAAASSSSSASSQ=="), + atob("EBWDAkkAAAAAkkh////+Ekh////+Ekh////+Ekg22222EkgwAAAGEgAxyAAGABwwAAAGOBwwAAAGGBwwAAAGGBw22222GBwSSQACGBw22222GBwSSSSSGB+AAAAA+B//////+ASAAAAASABzzzz+AEgySSSeEkhzz/+eEkg22222Eg=="), + atob("EBWDASSSQACSSSSQLRQCSSALaLbQARbRbRaLaBbRbbaLaBaBbbaBaCBRbbaKASOL7/fRwSQP///wCSR/x+P+CSSPx+PwSSSQP/wCSSSBAAIASSR+J/B+CSR+JJB+CSSJJJJASSSQJJACSSSR+B+CSSSSASASSSSSSSSSSSSSSSSSSQ==") +]; + +const tiles = [ + atob("EBCDAVlllllllssMMssMMkFlkEFlkMsssssssllllllllssssssssllllllllssssssssllllllllssMMssMMkFlkEFlkMsssssssllllllllssssssssllllllllssssssssg=="), + atob("EBCDAVlllllllssMMssMMkFlkEFlkMsssssssllllllllssssssssllllllllssssssssllllrrpLssMMtdLZUFlkLpZLMssstJZLFlllpZLZsssspZJNVlllrLZrsssstZNdQ=="), + atob("EBCDAFkkllkklkkskkkskkkkkkkkkskkkskkkkkklkkklkkkkkkkklkkklkkkkkkkkkkklkkllkklkkskkkskkkkkkkkkskkkskkkkkklkkklkkkkkkkklkkklkkkkkkkkkkkg=="), + atob("EBCDAdtttttttsNsNsNsNhhhhhhhhgkEhgkEhsEghsEghkEggkEggkggEkggEskAlskAlttttttttsNsNsNsNhhhhhhhhgkEhgkEhsEghsEghkEggkEggkggEkggEskAlskAlg==") +]; + +const walk = [ +atob("EBWDASSSSSSSSSSAAAASSSRJJJICSSRJJJJASSJJJJJwCSJJJJJxASJJJJJxASBJJJAJASABJIJICSAAAAAASSQMNsNgSSSMNtsCSSRBttgSSSNmAACSSSGAG2ASSSA2GxsCSSGAAxsCSSQw2AASSSQAwACSSSRsCSSSSSSASSSSSQ=="), + atob("EBWDASSAAAASSSRJJJICSSRJJJJASSJJJJJwCSJJJJJxASJJJJJxASBJJJAJASABJIJICSAAAAAASSQMNsNgSSSMNtsCSSRBttgSSSJIAACSSSMAGwwSSSA2GwwSSSGAGwwSSSQwNgCSSSSAwGCSSSSSG2CSSSSSBsCSSSSSQASSSQ=="), + atob("EBWDASSSSSSSSSSAAAASSSRJJJICSSRJJJJASSJJJJJwCSJJJJJxASJJJJJxASBJJJAJASABJIJICSAAAAAASSQMNsNgSSSMNtsCSSRBttgSSSNmAACSSSGwGGwSSSANg2wSSSGNgGASSSQwAwGCSSSAAG2CSSSSSNgCSSSSSQASSQ=="), + 0 +]; +walk[3] = walk[1]; + +const scale = 2; +const mapWidth = Math.ceil(176 / (16 * scale)); +const mapHeight = 4; +const map = new Uint8Array(mapWidth * mapHeight); +const Y = 176 - mapHeight/2*16*scale - 16*scale/2; +let frame = 0; + +function init() { + g.clear(); + g.setFont('6x8', 4); + g.setFontAlign(0, 0.5); + for (let i = 0; i < mapWidth; ++i) + shiftMap(); +} + +function tick(full){ + frame++; + + var d = new Date(); + var h = d.getHours(), m = d.getMinutes(); + var time = (" "+h).substr(-2) + ":" + m.toString().padStart(2,0); + + g.setColor(g.theme.fg); + g.drawString(time, 176/2, (176 - mapHeight * 16 * scale) / 2, true); + + if (full) { + let py = (176 - mapHeight * 16 * scale); + g.setColor(g.theme.bg); + g.fillRect(0, py - 5 * scale, 176, py); + if (!(frame & 3)) + shiftMap(); + drawMap(); + g.drawImage(walk[frame & 3], 16 * scale, Y, {scale:2}); + } +} + +function shiftMap() { + for (let y = 0; y < mapHeight; ++y) { + const i = y * mapWidth; + for (let x = 0; x < mapWidth - 1; ++x) { + map[i + x] = map[i + x + 1]; + } + const t = Math.random() * tiles.length | 0; + const s = Math.random() < 0.95 ? 0 : 1 + Math.random() * sprites.length | 0; + map[i + mapWidth - 1] = t | (s << 4); + } +} + +function drawMap(){ + let py = (176 - mapHeight * 16 * scale); + for (let y = 0; y < mapHeight; ++y, py += 16 * scale) { + const i = y * mapWidth; + for (let x = 0; x < mapWidth; ++x) { + let M = map[i + x]; + let t = M & 0xF; + g.drawImage(tiles[t], x * 16 * scale, py, {scale:2}); + } + } + py = (176 - mapHeight * 16 * scale) - 5 * scale; + for (let y = 0; y < mapHeight; ++y, py += 16 * scale) { + const i = y * mapWidth; + for (let x = 0; x < mapWidth; ++x) { + let M = map[i + x]; + let s = M >> 4; + if (s) + g.drawImage(sprites[s - 1], x * 16 * scale, py, {scale:2}); + } + } +} + + +init(); +tick(true); + +var interval = setInterval(tick, 700); +Bangle.on("lock", (locked) => { + clearInterval(interval); + tick(); + interval = setInterval(tick.bind(null, !locked), locked ? 60 * 1000 : 700); +}); diff --git a/apps/pokewalk/app.png b/apps/pokewalk/app.png new file mode 100644 index 000000000..4836605bd Binary files /dev/null and b/apps/pokewalk/app.png differ diff --git a/apps/pokewalk/metadata.json b/apps/pokewalk/metadata.json new file mode 100644 index 000000000..3f97e2fe6 --- /dev/null +++ b/apps/pokewalk/metadata.json @@ -0,0 +1,17 @@ +{ + "id": "pokewalk", + "name": "pokewalk clock", + "version": "0.01", + "description": "A very simple watchface featuring a Pokemon trainer on a walk.", + "readme": "README.md", + "icon": "app.png", + "screenshots": [{"url":"screenshot.png"}], + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS2"], + "allow_emulator": true, + "storage": [ + {"name":"pokewalk.app.js","url":"app.js"}, + {"name":"pokewalk.img","url":"app-icon.js","evaluate":true} + ] +} diff --git a/apps/pokewalk/screenshot.png b/apps/pokewalk/screenshot.png new file mode 100644 index 000000000..ebc9d6510 Binary files /dev/null and b/apps/pokewalk/screenshot.png differ