Merge pull request #236 from paulcockrell/master

Mario Clock [Enhancement] - Multi characters and Night Mode
master
Gordon Williams 2020-04-06 10:08:59 +01:00 committed by GitHub
commit 7cf9f117d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 120 additions and 39 deletions

View File

@ -911,8 +911,8 @@
{ "id": "marioclock",
"name": "Mario Clock",
"icon": "marioclock.png",
"version":"0.06",
"description": "Animated Mario clock, jumps to change the time!",
"version":"0.07",
"description": "Animated Mario clock, jumps to change the time! Swipe right to change the character, and swipe left to toggle night mode. Press BTN1 to jump.",
"tags": "clock,mario,retro",
"type": "clock",
"allow_emulator":true,

View File

@ -1,6 +1,7 @@
0.01: Create mario app
0.01: Create mario app [Paul Cockrell https://github.com/paulcockrell]
0.02: Fix day of the week and add padding
0.03: use short date format from locale, take timeout from settings
0.04: modify date to display to be more at the original idea but still localized
0.05: use 12/24 hour clock from settings
0.06: Performance refactor, and enhanced graphics!
0.07: Swipe right to change between Mario and Toad characters, swipe left to toggle night mode

View File

@ -1,10 +1,12 @@
/**********************************
BangleJS MARIO CLOCK
+ Based on Espruino Mario Clock V3 https://github.com/paulcockrell/espruino-mario-clock
+ Converting images to 1bit BMP: Image > Mode > Indexed and tick the "Use black and white (1-bit) palette", Then export as BMP.
+ Online Image convertor: https://www.espruino.com/Image+Converter
+ Images must be converted 1Bit White/Black !!! Not Black/White
**********************************/
/**
* BangleJS MARIO CLOCK
*
* + Original Author: Paul Cockrell https://github.com/paulcockrell
* + Created: April 2020
* + Based on Espruino Mario Clock V3 https://github.com/paulcockrell/espruino-mario-clock
* + Online Image convertor: https://www.espruino.com/Image+Converter, Use transparency + compression + 8bit Web + export as Image String
* + Images must be drawn as PNGs with transparent backgrounds
*/
const locale = require("locale");
const storage = require('Storage');
@ -22,14 +24,20 @@ const LIGHTEST = "#effedd";
const LIGHT = "#add795";
const DARK = "#588d77";
const DARKEST = "#122d3e";
const NIGHT = "#001818";
const marioSprite = {
// Character names
const TOAD = "toad";
const MARIO = "mario";
const characterSprite = {
frameIdx: 0,
x: 35,
y: 55,
jumpCounter: 0,
jumpIncrement: Math.PI / 6,
isJumping: false
isJumping: false,
character: MARIO,
};
const coinSprite = {
@ -49,6 +57,27 @@ const ONE_SECOND = 1000;
let timer = 0;
let backgroundArr = [];
let nightMode = false;
function genRanNum(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function switchCharacter() {
const curChar = characterSprite.character;
let newChar;
if (curChar === MARIO) {
newChar = TOAD;
} else {
newChar = MARIO;
}
characterSprite.character = newChar;
}
function toggleNightMode() {
nightMode = !nightMode;
}
function incrementTimer() {
if (timer > 1000) {
@ -61,19 +90,28 @@ function incrementTimer() {
function drawBackground() {
// Clear screen
g.setColor(LIGHTEST);
if (nightMode) {
g.setColor(NIGHT);
} else {
g.setColor(LIGHTEST);
}
g.fillRect(0, 10, W, H);
// Date bar
g.setColor(DARKEST);
g.fillRect(0, 0, W, 9);
// draw sky
g.setColor(LIGHT);
// set cloud colors
if (nightMode) {
g.setColor(DARKEST);
} else {
g.setColor(LIGHT);
}
// draw clouds
g.fillRect(0, 10, g.getWidth(), 15);
g.fillRect(0, 17, g.getWidth(), 17);
g.fillRect(0, 19, g.getWidth(), 19);
g.fillRect(0, 21, g.getWidth(), 21);
// Date bar
g.setColor(DARKEST);
g.fillRect(0, 0, W, 9);
}
function drawFloor() {
@ -105,9 +143,14 @@ function drawTreesFrame(x, y) {
g.drawLine(x + 6 /* Match stalk to palm tree */, y + 6 /* Match stalk to palm tree */, x + 6, H - 6);
}
function drawTrees() {
let newSprite = {x: 90, y: Math.floor(Math.random() * (40 /* max */ - 5 /* min */ + 1) + 15 /* min */)};
function generateTreeSprite() {
return {
x: 90,
y: Math.floor(Math.random() * (60 /* max */ - 30 /* min */ + 1) + 30 /* min */)
};
}
function drawTrees() {
// remove first sprite if offscreen
let firstBackgroundSprite = backgroundArr[0];
if (firstBackgroundSprite) {
@ -117,6 +160,7 @@ function drawTrees() {
// set background sprite if array empty
let lastBackgroundSprite = backgroundArr[backgroundArr.length - 1];
if (!lastBackgroundSprite) {
const newSprite = generateTreeSprite();
lastBackgroundSprite = newSprite;
backgroundArr.push(lastBackgroundSprite);
}
@ -125,6 +169,7 @@ function drawTrees() {
if (backgroundArr.length < 2 && lastBackgroundSprite.x < (16 * 7)) {
const randIdx = Math.floor(Math.random() * 25);
if (randIdx < 2) {
const newSprite = generateTreeSprite();
backgroundArr.push(newSprite);
}
}
@ -155,50 +200,70 @@ function drawCoin() {
}
function drawMarioFrame(idx, x, y) {
const mFr1 = require("heatshrink").decompress(atob("h8UxH+AAkHAAYKFBolcAAIPIBgYPDBpgfGFIY7EA4YcEBIPWAAYdDC4gLDAII5ECoYOFDogODFgoJCBwYZCAQYOFBAhAFFwZKGHQpMDw52FSg2HAAIoDAgIOMB5AAFGQTtKeBLuNcQwOJFwgJFA=")); // Mario Frame 1
const mFr2 = require("heatshrink").decompress(atob("h8UxH+AAkHAAYKFBolcAAIPIBgYPDBpgfGFIY7EA4YcEBIPWAAYdDC4gLDAII5ECoYOFDogODFgoJCBwYZCAQYOFBAhAFFwZKGHQpMDw+HCQYEBSowOBBQIdCCgTOIFgiVHFwYCBUhA9FBwz8HAo73GACQA=")); // Mario frame 2
switch(idx) {
case 0:
const mFr1 = require("heatshrink").decompress(atob("h8UxH+AAkHAAYKFBolcAAIPIBgYPDBpgfGFIY7EA4YcEBIPWAAYdDC4gLDAII5ECoYOFDogODFgoJCBwYZCAQYOFBAhAFFwZKGHQpMDw52FSg2HAAIoDAgIOMB5AAFGQTtKeBLuNcQwOJFwgJFA=")); // Mario Frame 1
g.drawImage(mFr1, x, y);
break;
case 1:
const mFr2 = require("heatshrink").decompress(atob("h8UxH+AAkHAAYKFBolcAAIPIBgYPDBpgfGFIY7EA4YcEBIPWAAYdDC4gLDAII5ECoYOFDogODFgoJCBwYZCAQYOFBAhAFFwZKGHQpMDw+HCQYEBSowOBBQIdCCgTOIFgiVHFwYCBUhA9FBwz8HAo73GACQA=")); // Mario frame 2
g.drawImage(mFr2, x, y);
break;
default:
}
}
function drawMario(date) {
function drawToadFrame(idx, x, y) {
switch(idx) {
case 0:
const tFr1 = require("heatshrink").decompress(atob("iEUxH+ACkHAAoNJrnWAAQRGg/WrgACB4QEBCAYOBB44QFB4QICAg4QBBAQbDEgwPCHpAGCGAQ9KAYQPKCYg/EJAoADAwaKFw4BEP4YQCBIIABB468EB4QADYIoQGDwQOGBYYrCCAwbFFwgQEM4gAEeA4OIH4ghFAAYLD")); // Toad Frame 1
g.drawImage(tFr1, x, y);
break;
case 1:
const tFr2 = require("heatshrink").decompress(atob("iEUxH+ACkHAAoNJrnWAAQRGg/WrgACB4QEBCAYOBB44QFB4QICAg4QBBAQbDEgwPCHpAGCGAQ9KAYQPKCYg/EJAoADAwaKFw4BEP4YQCBIIABB468EB4QADYIoQGDwQOGBYQrDb4wcGFxYLDMoYgHRYgwKABAMBA")); // Mario frame 2
g.drawImage(tFr2, x, y);
break;
default:
}
}
function drawCharacter(date, character) {
// calculate jumping
const seconds = date.getSeconds(),
milliseconds = date.getMilliseconds();
if (seconds == 59 && milliseconds > 800 && !marioSprite.isJumping) {
marioSprite.isJumping = true;
if (seconds == 59 && milliseconds > 800 && !characterSprite.isJumping) {
characterSprite.isJumping = true;
}
if (marioSprite.isJumping) {
marioSprite.y = (Math.sin(marioSprite.jumpCounter) * -12) + 50 /* Mario Y base value */;
marioSprite.jumpCounter += marioSprite.jumpIncrement;
if (characterSprite.isJumping) {
characterSprite.y = (Math.sin(characterSprite.jumpCounter) * -12) + 50 /* Character Y base value */;
characterSprite.jumpCounter += characterSprite.jumpIncrement;
if (parseInt(marioSprite.jumpCounter) === 2 && !coinSprite.isAnimating) {
if (parseInt(characterSprite.jumpCounter) === 2 && !coinSprite.isAnimating) {
coinSprite.isAnimating = true;
}
if (marioSprite.jumpCounter.toFixed(1) >= 4) {
marioSprite.jumpCounter = 0;
marioSprite.isJumping = false;
if (characterSprite.jumpCounter.toFixed(1) >= 4) {
characterSprite.jumpCounter = 0;
characterSprite.isJumping = false;
}
}
// calculate animation timing
if (timer % 50 === 0) {
// shift to next frame
marioSprite.frameIdx ^= 1;
characterSprite.frameIdx ^= 1;
}
drawMarioFrame(marioSprite.frameIdx, marioSprite.x, marioSprite.y);
switch(characterSprite.character) {
case("toad"):
drawToadFrame(characterSprite.frameIdx, characterSprite.x, characterSprite.y);
break;
case("mario"):
default:
drawMarioFrame(characterSprite.frameIdx, characterSprite.x, characterSprite.y);
}
}
function drawBrickFrame(x, y) {
@ -244,7 +309,7 @@ function redraw() {
drawTrees();
drawTime(date);
drawDate(date);
drawMario(date);
drawCharacter(date);
drawCoin();
// Render new frame
@ -294,7 +359,7 @@ function init() {
// Get Mario to jump!
setWatch(() => {
if (intervalRef && !marioSprite.isJumping) marioSprite.isJumping = true;
if (intervalRef && !characterSprite.isJumping) characterSprite.isJumping = true;
resetDisplayTimeout();
}, BTN1, {repeat:true});
@ -311,13 +376,28 @@ function init() {
}
});
Bangle.on('faceUp',function(up){
Bangle.on('faceUp', (up) => {
if (up && !Bangle.isLCDOn()) {
clearTimers();
Bangle.setLCDPower(true);
}
});
Bangle.on('swipe', (sDir) => {
resetDisplayTimeout();
switch(sDir) {
// Swipe right (1) - change character (on a loop)
case(1):
switchCharacter();
break;
// Swipe left (-1) - change day/night mode (on a loop)
case(-1):
default:
toggleNightMode();
}
});
startTimers();
}