diff --git a/apps/pongclock/app.js b/apps/pongclock/app.js new file mode 100644 index 000000000..8efe0eca5 --- /dev/null +++ b/apps/pongclock/app.js @@ -0,0 +1,309 @@ +class Ball { + constructor(collision) { + this.collision = collision; + this.w = 4; + this.h = this.w; + this.y = height / 2 - this.h / 2; + this.x = width / 2 - this.w / 2; + this.oldX = this.x; + this.oldY = this.y; + this.velX = 6; + this.velY = 3.5 + Math.random(); + } + + reset() { + this.y = height / 2 - this.h / 2; + this.x = width / 2 - this.w / 2; + this.velX = 6; + this.velY = 3.5 + Math.random(); + } + + checkCollision(that, isLeft) { + let test = false; + if (isLeft) { + test = this.x <= that.w + this.w && this.y > that.y && this.y < that.y + that.h; + } + else { + test = this.x >= that.x + this.w && this.y > that.y && this.y < that.y + that.h; + } + if (test) { + this.velX = -this.velX; + this.valY = (3.5 + Math.random()) * this.valY / Math.abs(this.valY); + + if (isLeft) { + right.follow = this; + left.follow = null; + } else { + left.follow = this; + right.follow = null; + } + } + } + + move() { + if (this.velX > 0) { + this.checkCollision(right, false); + } else { + this.checkCollision(left, true); + } + + this.x += this.velX; + this.y += this.velY; + + if (this.y <= this.h) { + this.y = this.h; + this.velY = -this.velY; + } + + if (this.y >= height - this.h) { + this.y = height - this.h; + this.velY = -this.velY; + } + + if(this.x >= width) { + left.scored(); + restart(); + } else if(this.x < 0) { + right.scored(); + restart(); + } + + } +} + +class Paddle { + constructor(side) { + this.side = side; + this.w = 4;//15; + this.h = 30;//80; + this.y = height / 2 - this.h/2; + this.follow = null; + this.target = height / 2 - this.h/2; + this.score = 99; + this.hasLost = false; + } + + reset() { + this.follow = null; + this.hasLost = false; + this.target = height / 2 - this.h/2; + this.y = height / 2 - this.h/2; + this.move(); + } + + scored() { + let d = new Date(); + let value = 0; + if (this.side == "left") { + value = d.getHours(); + } else { + value = d.getMinutes(); + } + if (this.score < value) { + this.score++; + } + else { + this.score = value; + } + } + + move() { + + if (this.follow && ! this.hasLost) { + var dy = this.follow.y - this.y - this.h / 2; + this.y += dy / 2; + } + else { + this.y += (this.target - this.y) / 10; + } + if (this.y < 0) { + this.y = 0; + } + if (this.y > height - this.h) { + this.y = height - this.h; + } + } +} + +var updateTimeout = null; +function update() { + var d = new Date(); + var lastStep = Date.now(); + left.move(); + right.move(); + if(d.getHours() != left.score) { + right.follow = null; + right.hasLost = true; + } + if(d.getMinutes() != right.score) { + left.follow = null; + left.hasLost = true; + } + + ball.move(); + redraw(); + var nextStep = 40 - (Date.now() - lastStep); + //console.log(nextStep); + updateTimeout = setTimeout(update, nextStep > 0 ? nextStep : 0); + return lastStep; +} + +function redraw() { + let fontHeight = width / 3.6; + let fontTop = top + height / 11; + let topHeight = top + height; + g.reset(); + + if (settings.isInvers) { + g.setColor(g.theme.bg); + g.setBgColor(g.theme.fg); + } + + g.clearRect(0, top + left.oldY, left.w, top + left.oldY + left.h); + g.clearRect(width - right.w, top + right.oldY, width, top + right.oldY + right.h); + g.clearRect(width / 2 - fontHeight * 1.4, fontTop, width / 2 + fontHeight * 1.4, fontTop + fontHeight); + g.clearRect(ball.oldX - ball.w, top + ball.oldY - ball.h, ball.oldX + ball.w, top + ball.oldY + ball.h); + + g.drawLine(width / 2, top, width / 2, topHeight); + g.fillRect(0, top + left.y, left.w, top + left.y + left.h); + left.oldY = left.y; + g.fillRect(width - right.w, top + right.y, width, top + right.y + right.h); + right.oldY = right.y; + g.fillCircle(ball.x, top + ball.y, ball.w); + ball.oldX = ball.x; + ball.oldY = ball.y; + + g.setFontVector(fontHeight); + /* + g.setFontAlign(0, -1); + g.drawString(("0" + left.score).substr(-2)+ " " + ("0" + right.score).substr(-2), width / 2, fontTop); + */ + /**/ + g.setFontAlign(1, -1); + g.drawString(("0" + left.score).substr(-2), 5 * width / 11, fontTop); + g.setFontAlign(-1, -1); + g.drawString(("0" + right.score).substr(-2), 6 * width / 11, fontTop); + /**/ +} + +function restart() { + g.reset(); + if (settings.isInvers) { + g.setColor(g.theme.bg); + g.setBgColor(g.theme.fg); + } + g.clearRect(0, top, width, top + height); + ball.reset(); + left.reset(); + right.reset(); + right.follow = ball; + left.move(); + right.move(); + if (settings.withWidgets) { + Bangle.drawWidgets(); + } +} + +function stop() { + if (updateTimeout) { + clearTimeout(updateTimeout); + } + updateTimeout = null; + if (pauseTimeout) { + clearTimeout(pauseTimeout); + } + pauseTimeout = null; +} + +var pauseTimeout = null; +function pause() { + stop(); + left.scored(); + right.scored(); + redraw(); + pauseTimeout = setTimeout(pause, Date.now() % 60000); +} + +const SETTINGS_FILE = "pongclock.json"; +var settings = Object.assign({ + // default values + withWidgets: true, + isInvers: false, + playLocked: true, +}, require('Storage').readJSON(SETTINGS_FILE, true) || {}); +require('Storage').writeJSON(SETTINGS_FILE, settings); + +var height = g.getHeight(), + width = g.getWidth(); +var top = 0; + +Bangle.setUI("clock"); + +g.reset(); +g.clearRect(0, top, width, height); + +if (settings.withWidgets) { + Bangle.loadWidgets(); + Bangle.drawWidgets(); + //console.log(WIDGETS); + if (global.WIDGETS) { + let bottom = 0; + for (var i in WIDGETS) { + var w = WIDGETS[i]; + if (w.area) { + if (w.area.indexOf("t") >= 0) { + top = 25; + } + if (w.area.indexOf("b") >= 0) { + bottom = 25; + } + } + } + height -= top + bottom; + } +} + +if (settings.isInvers) { + g.setColor(g.theme.bg); + g.setBgColor(g.theme.fg); +} +g.clearRect(0, top, width, top + height); + +var left = new Paddle("left"); +var right = new Paddle("right"); +var ball = new Ball(true); + +left.x = 20; +right.x = width - 20; + +left.scored(); +right.scored(); + +Bangle.on("lock", (on) => { + //console.log(on); + if (!settings.playLocked) { + if (on) { + pause(); + } else { + stop(); + update(); + } + } +}); + +restart(); +if (!settings.playLocked && Bangle.isLocked()) { + pause(); +} else { + update(); +} + +/* +require("Storage").write("pongclock.info",{ + "id":"pongclock", + "name":"Pong Clock", + "type":"clock", + "src":"pongclock.app.js", + "icon":"pongclock.img" +}); +*/