"use strict"; document.addEventListener('DOMContentLoaded', init); let Key = { _pressed: {}, isDown: function (keyCode) { return this._pressed[keyCode]; }, onKeydown: function (event) { this._pressed[event.code] = true; }, onKeyup: function (event) { delete this._pressed[event.code]; } }; let ctx, canvas = document.createElement("canvas"); function init() { canvas.width = window.innerWidth canvas.height = window.innerHeight ctx = canvas.getContext('2d'); document.body.insertBefore(canvas, document.body.childNodes[0]); window.addEventListener('keydown', (e) => Key.onKeydown(e)); window.addEventListener('keyup', (e) => Key.onKeyup(e)); function run() { ctx.clearRect(0, 0, canvas.width, canvas.height); refresh(); requestAnimationFrame(run); } // ------------------------------------------------------------------- let gstate = 1; let intro = new Intro(); let score = new Score(); let bar = new Bar(); function joy_fire() { switch (gstate) { case 0: // Waiting to start newGame(); break; case 1: // Playing... break; case 2: // Game Over newGame(); break; } } function newGame() { gstate = 1; score.reset(); bar.reset(); } function refresh() { switch (gstate) { case 0: // Waiting to start intro.update(); break; case 1: // Playing... bar.update(); score.update(); break; case 2: // Game Over break; } } run(); } class Intro { constructor() { this.x = canvas.width; this.y = canvas.height / 2 - 48; } update() { this.centerText('BreakOut', this.y, '48px', 'Consolas', 'Black'); this.centerText('JDG', this.y + 50, '24px', 'Consolas', 'Black'); } centerText(txt, y, s, f, c) { ctx.font = s + ' ' + f; ctx.fillStyle = 'Black'; let x = (canvas.width - ctx.measureText(txt).width) / 2; ctx.fillText(txt, x, y); } } class Bar { constructor() { this.w = 100; this.h = 20; this.speed = 10; // Target Speed this._speed = 0; // Current Speed and direction this.xLimit = (canvas.width - this.w); this.reset(); } reset() { this.x = (canvas.width - this.w) / 2; this.y = (canvas.height - this.h * 2); this._y = canvas.height + 10; } update() { this.move(); this.draw(); } stop() { this._speed = 0; } left() { if (this._speed >= 0) this._speed = -this.speed; this.x += this._speed; if (this.x < 0) this.x = 0; this._speed -= 0.5; } right() { if (this._speed <= 0) this._speed = this.speed; this.x += this._speed; if (this.x > this.xLimit) this.x = this.xLimit; this._speed += 0.5; } move() { if (Key.isDown('ArrowLeft')) this.left(); else if (Key.isDown('ArrowRight')) this.right(); else this.stop(); } draw() { if (this._y != this.y) this._y--; if (this._y < canvas.height) { ctx.fillStyle = 'black'; ctx.fillRect(this.x, this._y, this.w, this.h); } } } class Score { constructor() { this.reset(); ctx.font = "30px Consolas"; let m = ctx.measureText('Score: 00000'); this.x = canvas.width - m.width; this.y = -10; } reset() { this.points = 0; } add(x) { this.points += x; } update() { if (this.y != 30) this.y++; if (this.y > 0) { ctx.font = "30px Consolas"; ctx.fillStyle = 'Black'; ctx.fillText('Score: ' + this.points, this.x, this.y); } } } class ball { constructor(x, y, speed, angle) { this.x = x; this.y = y; this.speed = speed; this.angle = angle; this.color = 'black'; this.size = 20; } update() { this.move(); this.draw(); } draw() { ctx.fillStyle = this.color; ctx.fillRect(this.x, this.y, this.size, this.size); } move() { this.x += this.speed * Math.cos(this.angle); this.y += this.speed * Math.sin(this.angle); if (this.x < 0 || this.x > canvas.width || this.y < 0 || this.y > canvas.height) this.bounce(); } bounce() { this.angle += 180; } }