diff --git a/Makefile b/Makefile index b88eff2..5e89098 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ www/js/escalator.js: $(shell find src -name "*.js") src/open.js \ src/utils.js \ src/screen.js \ + src/gui.js \ src/scene.js \ src/box.js \ src/platform.js \ diff --git a/src/game.js b/src/game.js index 520e4a9..7977e7f 100644 --- a/src/game.js +++ b/src/game.js @@ -29,6 +29,7 @@ class Game { if (this.mainScreen.status === Status.Finished) { if (this.mainScreen.after === AfterMenu.Start) { + this.scene.initialize(); this.changeScreen(this.scene); } else if (this.mainScreen.after === AfterMenu.Exit) { if (navigator.app !== undefined && typeof navigator.app.exitApp === 'function') { diff --git a/src/gui.js b/src/gui.js new file mode 100644 index 0000000..bab2e3d --- /dev/null +++ b/src/gui.js @@ -0,0 +1,99 @@ +const Type = { + Stroke: 1, + Fill: 2, + StrokeFill: 3, +}; + +class GuiButton { + + // x and y are the center of the button + constructor(context, text, x, y, type, callback) { + this.font = context.font; + this.fillStyle = context.fillStyle; + this.strokeStyle = context.strokeStyle; + this.text = text; + this.x = x; + this.y = y; + this.callback = callback; + this.type = type; + } +} + +class Gui extends Screen { + constructor(canvas) { + super(canvas); + this.buttons = []; + + this.addEventListener('touchstart', (event) => { + this.onTouchStart(event); + }); + } + + textToString(text) { + if (typeof text === 'string' || text instanceof String) { + return text; + } else if (typeof text === 'function') { + return text(); + } + } + + + addButton(button) { + this.buttons.push(button); + } + + onTouchStart(event) { + + for (let button of this.buttons) { + + // Compute the box of the button + let text = this.textToString(button.text); + let width = this.context.measureText(text).width; + let height = parseInt(button.font.split('p')[0], 10); + let x = button.x * this.width() - width / 2; + let fontHeight = parseInt(button.font.split('p')[0], 10); + let y = button.y * this.height() - fontHeight; + let box = enlargeBox({ + x: x, + y: y, + width: width, + height: height + }); + + let e = event.changedTouches[0]; + if (typeof button.callback === 'function' && isInBox(position(e), box)) { + button.callback(); + } + } + + } + + renderButton(button) { + this.context.font = button.font; + this.context.fillStyle = button.fillStyle; + this.context.strokeStyle = button.strokeStyle; + + let text = this.textToString(button.text); + let width = this.context.measureText(text).width; + let x = button.x * this.width() - width / 2; + let y = button.y * this.height(); + + if (button.type === Type.Fill || button.type === Type.StrokeFill) { + this.context.fillText(text, x, y); + } + + if (button.type === Type.Stroke || button.type === Type.StrokeFill) { + this.context.strokeText(text, x, y); + } + + } + + render() { + this.clear(); + this.drawBackground(); + for (let button of this.buttons) { + this.renderButton(button); + } + } + +} diff --git a/src/menu.js b/src/menu.js index c88ffc2..d76d03d 100644 --- a/src/menu.js +++ b/src/menu.js @@ -3,58 +3,33 @@ const AfterMenu = { Start: 1, }; -class Menu extends Screen { +function resetHighScoreText() { + return "Reset high score (" + heightToScore(window.localStorage.getItem("maxHeight")) + ")"; +} + +class Menu extends Gui { constructor(canvas) { super(canvas); - this.addEventListener('touchstart', (event) => { - this.onTouchStart(event); - }); - } - - render() { - this.clear(); - this.drawBackground(); - this.drawTitle(); - this.drawMenu(); - } - - drawTitle() { - this.context.font = "50px Dimbo"; - this.context.stokeStyle = 'rgb(0, 0, 0)'; + this.context.font = "90px Dimbo"; this.context.fillStyle = 'rgb(255, 255, 255)'; + this.context.strokeStyle = 'rgb(0, 0, 0)'; + this.addButton(new GuiButton(this.context, "Escalator", 0.5, 0.25, Type.StrokeFill)); - let text = "Escalator"; - let size = this.context.measureText(text).width; - let offset = (this.width() - size) / 2; - - this.context.fillText(text, offset, 0.1 * this.width() + 50); - this.context.strokeText(text, offset, 0.1 * this.width() + 50); - } - - drawMenu() { this.context.font = "30px Dimbo"; - this.context.fillStyle = 'rgb(255, 255, 255)'; + this.addButton(new GuiButton(this.context, "New Game", 0.5, 0.55, Type.StrokeFill, () => { + this.status = Status.Finished; + this.after = AfterMenu.Start; + })); - let text = "New Game"; - let box = this.newGameBox(); - this.context.fillText(text, box.x, box.y + 30); - this.context.strokeText(text, box.x, box.y + 30); + this.addButton(new GuiButton(this.context, resetHighScoreText, 0.5, 0.7, Type.StrokeFill, () => { + window.localStorage.setItem("maxHeight", 0) + })); - // this.context.beginPath(); - // box = this.enlargeBox(box); - // this.context.rect(box.x, box.y, box.width, box.height); - // this.context.stroke(); - - text = "Exit"; - box = this.exitBox(); - this.context.fillText(text, box.x, box.y + 30); - this.context.strokeText(text, box.x, box.y + 30); - - // this.context.beginPath(); - // box = this.enlargeBox(box); - // this.context.rect(box.x, box.y, box.width, box.height); - // this.context.stroke(); + this.addButton(new GuiButton(this.context, "Exit", 0.5, 0.85, Type.StrokeFill, () => { + this.status = Status.Finished; + this.after = AfterMenu.Exit; + })); } drawBackground() { @@ -63,58 +38,4 @@ class Menu extends Screen { this.context.rect(0, 0, this.width(), this.height()); this.context.fill(); } - - newGameBox() { - this.context.font = "30px Dimbo"; - let text = "New Game"; - let size = this.context.measureText(text); - let offset = (this.width() - size.width) / 2; - - return { - x: offset, - y: 0.5 * this.height(), - width: size.width, - height: 30, - }; - } - - exitBox() { - this.context.font = "30px Dimbo"; - let text = "Exit"; - let size = this.context.measureText(text); - let offset = (this.width() - size.width) / 2; - - return { - x: offset, - y: 0.7 * this.height(), - width: size.width, - height: 30, - }; - - } - - onTouchStart(event) { - let e = event.changedTouches[0]; - - let box = this.enlargeBox(this.newGameBox()); - if (isInBox(position(e), box)) { - this.status = Status.Finished; - this.after = AfterMenu.Start; - } - - box = this.enlargeBox(this.exitBox()); - if (isInBox(position(e), box)) { - this.status = Status.Finished; - this.after = AfterMenu.Exit; - } -} - - enlargeBox(box) { - return { - x: box.x - box.width * 0.1, - y: box.y - box.height * 0.1, - width: box.width * 1.2, - height: box.height * 1.4, - } - } } diff --git a/src/scene.js b/src/scene.js index 33479a1..aa8a123 100644 --- a/src/scene.js +++ b/src/scene.js @@ -26,6 +26,7 @@ class Scene extends Screen { initialize() { super.initialize(); + this.player.reset(); this.platforms = []; this.cameraHeight = 0; @@ -93,7 +94,6 @@ class Scene extends Screen { // Increase position of the camera this.cameraHeight += this.cameraSpeed * time * this.height(); - // Update high score this.currentHeight = Math.max(this.player.y, this.currentHeight); @@ -193,7 +193,7 @@ class Scene extends Screen { this.context.font = "15px Dimbo"; this.context.fillStyle = "rgb(255, 255, 255)"; - this.context.fillText("High score: " + this.score(this.currentMaxHeight), 0, height - 5); + this.context.fillText("High score: " + heightToScore(this.currentMaxHeight), 0, height - 5); } drawObject(object) { @@ -295,11 +295,11 @@ class Scene extends Screen { let size = 40; this.context.font = size + "px Dimbo"; - let currentScoreText = "Your score: " + this.score(this.currentHeight); + let currentScoreText = "Your score: " + heightToScore(this.currentHeight); this.centerFillText(currentScoreText, this.height() / 2); this.centerStrokeText(currentScoreText, this.height() / 2); - let highScoreText = "Highest score: " + this.score(this.maxHeight); + let highScoreText = "Highest score: " + heightToScore(this.maxHeight); this.centerFillText(highScoreText, this.height() / 2 + 2 * size); this.centerStrokeText(highScoreText, this.height() / 2 + 2 * size); @@ -351,10 +351,6 @@ class Scene extends Screen { } - score(height) { - return Math.floor(100 * height); - } - } Scene.background = new Image(); diff --git a/src/screen.js b/src/screen.js index 0c825f6..393edd6 100644 --- a/src/screen.js +++ b/src/screen.js @@ -45,7 +45,7 @@ class Screen { removeListeners() { for (let listener of this.listeners) { - document.removeElementListener(listener.type, listener.callback); + console.log(document.removeElementListener(listener.type, listener.callback)); } } @@ -83,4 +83,8 @@ class Screen { return this.canvas.height; } + drawBackground() { + + } + } diff --git a/src/utils.js b/src/utils.js index 6a6538b..07da99c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -11,3 +11,15 @@ function position(event) { }; } +function enlargeBox(box) { + return { + x: box.x - box.width * 0.1, + y: box.y - box.height * 0.1, + width: box.width * 1.2, + height: box.height * 1.4, + } +} + +function heightToScore(height) { + return Math.floor(100 * height); +}