Work on different screens
This commit is contained in:
parent
76d77b4fac
commit
c596e9ec2f
3
Makefile
3
Makefile
|
@ -4,9 +4,12 @@ www/js/escalator.js: $(shell find src -name "*.js")
|
||||||
mkdir -p www/js
|
mkdir -p www/js
|
||||||
cat \
|
cat \
|
||||||
src/open.js \
|
src/open.js \
|
||||||
|
src/screen.js \
|
||||||
src/scene.js \
|
src/scene.js \
|
||||||
src/box.js \
|
src/box.js \
|
||||||
src/platform.js \
|
src/platform.js \
|
||||||
|
src/menu.js \
|
||||||
|
src/game.js \
|
||||||
src/main.js \
|
src/main.js \
|
||||||
src/close.js \
|
src/close.js \
|
||||||
> www/js/escalator.js
|
> www/js/escalator.js
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
class Game {
|
||||||
|
|
||||||
|
constructor(canvas) {
|
||||||
|
// Create menu
|
||||||
|
let menu = new Menu(canvas);
|
||||||
|
|
||||||
|
// Create game scene
|
||||||
|
let box = new Box();
|
||||||
|
this.scene = new Scene(document.getElementById('canvas'), box);
|
||||||
|
|
||||||
|
this.changeScreen(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
changeScreen(screen) {
|
||||||
|
if (this.mainSCreen !== undefined) {
|
||||||
|
this.mainScreen.removeListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mainScreen = screen;
|
||||||
|
screen.status = Status.Running;
|
||||||
|
screen.addListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
update(time = 0.002) {
|
||||||
|
this.mainScreen.update(time);
|
||||||
|
|
||||||
|
if (this.mainScreen.status === Status.Finished) {
|
||||||
|
if (this.mainScreen.after === AfterMenu.Start) {
|
||||||
|
this.changeScreen(this.scene);
|
||||||
|
} else if (this.mainScreen.after === AfterMenu.Exit) {
|
||||||
|
alert("I don't know how to exit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
this.mainScreen.render();
|
||||||
|
}
|
||||||
|
}
|
22
src/main.js
22
src/main.js
|
@ -1,34 +1,22 @@
|
||||||
let scene;
|
let game;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
loop();
|
loop();
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
|
||||||
// Initialize scene
|
let canvas = document.getElementById('canvas');
|
||||||
let box = new Box();
|
game = new Game(canvas);
|
||||||
scene = new Scene(document.getElementById('canvas'), box);
|
|
||||||
|
|
||||||
// Initialize listeners
|
|
||||||
window.addEventListener('resize', () => {
|
|
||||||
scene.autoResize()
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener('touchstart', (event) => {
|
|
||||||
scene.start();
|
|
||||||
let e = event.changedTouches[0];
|
|
||||||
box.jump(e.clientX / window.innerWidth, e.clientY / window.innerHeight);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function loop() {
|
function loop() {
|
||||||
|
|
||||||
// Manage physics
|
// Manage physics
|
||||||
scene.update();
|
game.update();
|
||||||
|
|
||||||
// Do rendering
|
// Do rendering
|
||||||
scene.render();
|
game.render();
|
||||||
|
|
||||||
requestAnimationFrame(loop);
|
requestAnimationFrame(loop);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
const AfterMenu = {
|
||||||
|
Exit: 0,
|
||||||
|
Start: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
class Menu extends Screen {
|
||||||
|
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 Arial";
|
||||||
|
this.context.stokeStyle = 'rgb(0, 0, 0)';
|
||||||
|
this.context.fillStyle = 'rgb(255, 255, 255)';
|
||||||
|
|
||||||
|
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 Arial";
|
||||||
|
this.context.fillStyle = 'rgb(255, 255, 255)';
|
||||||
|
|
||||||
|
let text = "New Game";
|
||||||
|
let box = this.newGameBox();
|
||||||
|
this.context.fillText(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();
|
||||||
|
|
||||||
|
text = "Exit";
|
||||||
|
box = this.exitBox();
|
||||||
|
this.context.fillText(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();
|
||||||
|
}
|
||||||
|
|
||||||
|
drawBackground() {
|
||||||
|
this.context.fillStyle = 'rgb(255, 0, 0)';
|
||||||
|
this.context.beginPath();
|
||||||
|
this.context.rect(0, 0, this.width(), this.height());
|
||||||
|
this.context.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
newGameBox() {
|
||||||
|
this.context.font = "30px Arial";
|
||||||
|
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 Arial";
|
||||||
|
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 (e.clientX > box.x && e.clientX < box.x + box.width) {
|
||||||
|
if (e.clientY > box.y && e.clientY < box.y + box.height) {
|
||||||
|
this.status = Status.Finished;
|
||||||
|
this.after = AfterMenu.Start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
box = this.enlargeBox(this.exitBox());
|
||||||
|
if (e.clientX > box.x && e.clientX < box.x + box.width) {
|
||||||
|
if (e.clientY > box.y && e.clientY < box.y + box.height) {
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
51
src/scene.js
51
src/scene.js
|
@ -1,18 +1,23 @@
|
||||||
class Scene {
|
class Scene extends Screen {
|
||||||
constructor(canvas, player) {
|
constructor(canvas, player) {
|
||||||
this.canvas = canvas;
|
super(canvas);
|
||||||
this.context = canvas.getContext('2d');
|
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
this.currentHeight = 0;
|
||||||
this.maxHeight = 0;
|
this.maxHeight = 0;
|
||||||
this.initialize();
|
this.initialize();
|
||||||
|
|
||||||
|
this.addEventListener('touchstart', (event) => {
|
||||||
|
this.onTouchStart(event);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
this.autoResize();
|
super.initialize();
|
||||||
this.player.reset();
|
this.player.reset();
|
||||||
this.platforms = [];
|
this.platforms = [];
|
||||||
this.cameraHeight = 0;
|
this.cameraHeight = 0;
|
||||||
this.cameraSpeed = 0;
|
this.cameraSpeed = 0;
|
||||||
|
this.currentHeight = 0;
|
||||||
this.started = false;
|
this.started = false;
|
||||||
|
|
||||||
// Generate random initial platforms
|
// Generate random initial platforms
|
||||||
|
@ -30,32 +35,10 @@ class Scene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
width() {
|
|
||||||
return this.canvas.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
height() {
|
|
||||||
return this.canvas.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
resize(width, height) {
|
|
||||||
this.canvas.width = width;
|
|
||||||
this.canvas.height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
autoResize() {
|
|
||||||
this.canvas.width = window.innerWidth;
|
|
||||||
this.canvas.height = window.innerHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
clear() {
|
|
||||||
this.context.clearRect(0, 0, this.width(), this.height());
|
|
||||||
}
|
|
||||||
|
|
||||||
drawBackground() {
|
drawBackground() {
|
||||||
this.context.fillStyle = 'rgb(255, 0, 0)';
|
this.context.fillStyle = 'rgb(255, 0, 0)';
|
||||||
this.context.beginPath();
|
this.context.beginPath();
|
||||||
this.context.rect(0, 0, this.canvas.width, this.canvas.height);
|
this.context.rect(0, 0, this.width(), this.height());
|
||||||
this.context.fill();
|
this.context.fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +65,7 @@ class Scene {
|
||||||
|
|
||||||
// Update high score
|
// Update high score
|
||||||
this.maxHeight = Math.max(this.player.y, this.maxHeight);
|
this.maxHeight = Math.max(this.player.y, this.maxHeight);
|
||||||
|
this.currentHeight = Math.max(this.player.y, this.currentHeight);
|
||||||
|
|
||||||
let previous = {
|
let previous = {
|
||||||
x: this.player.x,
|
x: this.player.x,
|
||||||
|
@ -177,7 +161,18 @@ class Scene {
|
||||||
drawHud() {
|
drawHud() {
|
||||||
this.context.font = "20px Arial";
|
this.context.font = "20px Arial";
|
||||||
this.context.fillStyle = 'rgb(255, 255, 255)';
|
this.context.fillStyle = 'rgb(255, 255, 255)';
|
||||||
this.context.fillText("High score: " + Math.floor(100 * this.maxHeight), 0, 20);
|
this.context.fillText("Current score: " + Math.floor(100 * this.currentHeight), 0, 20);
|
||||||
|
this.context.fillText("High score: " + Math.floor(100 * this.maxHeight), 0, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
onTouchStart(event) {
|
||||||
|
|
||||||
|
let e = event.changedTouches[0];
|
||||||
|
this.start();
|
||||||
|
if (e !== undefined) {
|
||||||
|
this.player.jump(e.clientX / window.innerWidth, e.clientY / window.innerHeight);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
const Status = {
|
||||||
|
Idle: 0,
|
||||||
|
Running: 1,
|
||||||
|
Finished: 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
class Screen {
|
||||||
|
|
||||||
|
constructor(canvas) {
|
||||||
|
this.status = Status.Idle;
|
||||||
|
this.canvas = canvas;
|
||||||
|
this.context = canvas.getContext('2d');
|
||||||
|
this.listeners = [];
|
||||||
|
this.autoResize();
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener(type, callback) {
|
||||||
|
this.listeners.push({
|
||||||
|
type: type,
|
||||||
|
callback: callback,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addListeners() {
|
||||||
|
for (let listener of this.listeners) {
|
||||||
|
document.addEventListener(listener.type, listener.callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removeListeners() {
|
||||||
|
for (let listener of this.listeners) {
|
||||||
|
document.removeElementListener(listener.type, listener.callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
this.autoResize();
|
||||||
|
}
|
||||||
|
|
||||||
|
autoResize() {
|
||||||
|
this.resize(window.innerWidth, window.innerHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
resize(width, height) {
|
||||||
|
this.canvas.width = width;
|
||||||
|
this.canvas.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.context.clearRect(0, 0, this.width(), this.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
update(time = 0.002) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
width() {
|
||||||
|
return this.canvas.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
height() {
|
||||||
|
return this.canvas.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue