From 5d7db80f3d0981d6a180a65c7c632d1782785a41 Mon Sep 17 00:00:00 2001 From: Daniel Bulant Date: Thu, 8 Apr 2021 15:04:42 +0200 Subject: [PATCH] phaser rewrite --- package-lock.json | 88 ++++++++++ package.json | 1 + src/game/gameScene.js | 211 ++++++++++++++++++++++++ src/game/index.js | 367 +++++------------------------------------- src/game/input.js | 26 ++- src/game/maps.js | 8 +- src/pages/game.svelte | 9 +- 7 files changed, 366 insertions(+), 344 deletions(-) create mode 100644 src/game/gameScene.js diff --git a/package-lock.json b/package-lock.json index e92ad35..07c0097 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "fabric": "^4.3.1", "howler": "^2.2.1", + "phaser": "^3.54.0", "sirv-cli": "^1.0.0" }, "devDependencies": { @@ -1999,6 +2000,11 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3122,6 +3128,15 @@ "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", "optional": true }, + "node_modules/path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", + "dependencies": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -3143,6 +3158,15 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "optional": true }, + "node_modules/phaser": { + "version": "3.54.0", + "resolved": "https://registry.npmjs.org/phaser/-/phaser-3.54.0.tgz", + "integrity": "sha512-/1XVI6J2siS0OGwJez7vLbRjars1zb//EvJdYMVyd3wNTUf5DHrvYUj1f6TsEISr4vjnbrNtS66QIuPbGU8x6A==", + "dependencies": { + "eventemitter3": "^4.0.7", + "path": "^0.12.7" + } + }, "node_modules/picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", @@ -3176,6 +3200,14 @@ "node": ">=6" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -4115,12 +4147,25 @@ "punycode": "^2.1.0" } }, + "node_modules/util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dependencies": { + "inherits": "2.0.3" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "optional": true }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, "node_modules/uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", @@ -6275,6 +6320,11 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "devOptional": true }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -7183,6 +7233,15 @@ "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", "optional": true }, + "path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", + "requires": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -7201,6 +7260,15 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "optional": true }, + "phaser": { + "version": "3.54.0", + "resolved": "https://registry.npmjs.org/phaser/-/phaser-3.54.0.tgz", + "integrity": "sha512-/1XVI6J2siS0OGwJez7vLbRjars1zb//EvJdYMVyd3wNTUf5DHrvYUj1f6TsEISr4vjnbrNtS66QIuPbGU8x6A==", + "requires": { + "eventemitter3": "^4.0.7", + "path": "^0.12.7" + } + }, "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", @@ -7225,6 +7293,11 @@ "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "dev": true }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -7983,6 +8056,21 @@ "punycode": "^2.1.0" } }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index 34659bc..03d78fe 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "dependencies": { "fabric": "^4.3.1", "howler": "^2.2.1", + "phaser": "^3.54.0", "sirv-cli": "^1.0.0" } } diff --git a/src/game/gameScene.js b/src/game/gameScene.js new file mode 100644 index 0000000..7bc6853 --- /dev/null +++ b/src/game/gameScene.js @@ -0,0 +1,211 @@ +import Phaser, { Animations } from "phaser"; +import { keys } from "./input"; + +const textureWidth = 100; + +export class GameScene extends Phaser.Scene { + constructor(map) { + super({ + key: "GameScene", + active: true, + physics: { + default: "arcade" + } + }); + /** @type {{ + background: string, + sprite: string, + offset: { x: number, y: nunber }, + size: { x: number, y: number }, + px: number, + map: (string | null | { + type: string, + direction?: number + })[][] + }} */ + this.map = map; + } + + preload() { + this.load.setBaseURL(); + this.load.image("level1", "/sprite/level1.webp"); + this.load.image("lyre", "/sprite/lyre.webp"); + this.load.image("cloud", "/sprite/clouds.webp"); + this.load.spritesheet("wind", "/sprite/wind.png", { frameWidth: textureWidth }); + this.load.spritesheet("uriel", "/sprite/uriel.png", { frameWidth: textureWidth }); + this.load.spritesheet("michael", "/sprite/michael.png", { frameWidth: textureWidth }); + this.load.spritesheet("spawn", "/sprite/michael.png", { frameWidth: textureWidth }); + } + + create() { + this.input.on("keydown", function() { + if (this.game.sound.context.state === 'suspended') { + this.game.sound.context.resume(); + } + }); + console.log(this.map); + + this.container = this.add.container(); + this.container.width = this.map.size.x * this.map.px + this.map.offset.x * 2; + this.container.height = this.map.size.y * this.map.px + this.map.offset.y * 2; + this.grid = this.add.container(this.map.offset.x, this.map.offset.y); + this.container.width = this.map.size.x * this.map.px; + this.container.height = this.map.size.y * this.map.px; + + this.background = this.add.image(this.container.width / 2, this.container.height / 2, this.map.background); + this.container.add(this.background); + this.container.add(this.grid); + + /** + * @type {{ type: string, direction?: number, sprite: Phaser.GameObjects.Sprite, animated: boolean }[][]} + */ + this.items = new Array(this.map.map.length); + for(var y in this.map.map) { + var row = this.map.map[y]; + + for(var x in row) { + if(!this.items[x]) { + this.items[x] = new Array(row.length); + } + var item = row[x]; + if(!item) { + this.items[x][y] = null; + continue; + } + if(typeof item === "string") { + item = { + type: item + } + } + item.direction = item.direction ?? 0; + y = parseInt(y); + x = parseInt(x); + if(item.type !== "barrier") { + var type = item.type; + if(type === "angel") type = this.map.sprite; + if(this.textures.get(type).frameTotal > 1) { + console.log("Generating animation for", item); + var sprite = this.add.sprite(x * this.map.px, y * this.map.px); + item.animated = true; + if(!this.anims.exists(type)) { + this.anims.create({ + key: type, + frames: this.anims.generateFrameNumbers(type, { + start: 0 + }), + frameRate: 10, + repeat: -1 + }); + } + sprite.play(type); + } else { + var sprite = this.add.sprite(x * this.map.px, y * this.map.px, type); + item.animated = false; + } + sprite.setRotation(item.direction * Math.PI / 2); + this.grid.add(sprite); + item.sprite = sprite; + if(type !== item.type) { + item.texture = type; + } + + if(item.type === "spawn") { + this.player = item; + this.player.x = x; + this.player.y = y; + } + } else { + item.sprite = null; + } + this.items[x][y] = item; + } + } + } + + move(fromX, fromY, toX, toY, onComplete = () => {}) { + var item = this.items[fromX][fromY]; + this.tweens.add({ + targets: item.sprite, + onComplete, + x: toX * this.map.px, + y: toY * this.map.px, + duration: 400 + }); + this.items[fromX][fromY] = null; + this.items[toX][toY] = item; + } + + underPlace = null; + + getMovementFromDirection(direction) { + switch(direction) { + case 1: + return { x: 0, y: -1 }; + case 2: + return { x: 1, y: 0 }; + case 3: + return { x: 0, y: 1 }; + case 4: + return { x: -1, y: 0 }; + default: + return { x: 0, y: 0 }; + } + } + + movePlayer(moveX, moveY) { + if(!this.canMove) return; + var toX = this.player.x + moveX; + var toY = this.player.y + moveY; + console.log("Moving", this.player.x, this.player.y, toX, toY); + if(toX > this.map.size.x - 1 || toX < 0 || toY > this.map.size.y - 1 || toY < 0) return; + var underPlace = this.underPlace; + this.underPlace = null; + if(this.items[toX][toY]) { + if(this.items[toX][toY].type === "wind") { + this.underPlace = this.items[toX][toY]; + } else { + if(this.items[toX][toY].type !== "lyre") return; + if(toX + moveX > this.map.size.x - 1|| toX + moveX < 0 || toY + moveY > this.map.size.y - 1 || toY + moveY < 0) return; + if(this.items[toX + moveX][toY + moveY] && this.items[toX + moveX][toY + moveY].type !== "wind") return; + this.move(toX, toY, toX + moveX, toY + moveY); + } + } + this.canMove = false; + this.move(this.player.x, this.player.y, toX, toY, () => { + this.canMove = true; + this.items[this.player.x][this.player.y] = underPlace; + this.player.x = toX; + this.player.y = toY; + if(this.underPlace) { + var movement = this.getMovementFromDirection(this.underPlace.direction); + this.movePlayer(movement.x, movement.y); + } + }); + } + + canMove = true; + + update() { + // debug mode + if(keys.wasKeyPressed("debug")) { + console.log("Toggled debug mode"); + this.physics.config.debug = !this.physics.config.debug; + if(this.physics.config.debug) this.physics.world.createDebugGraphic(); + this.physics.world.drawDebug = this.physics.config.debug; + if(!this.physics.config.debug) this.physics.world.debugGraphic.destroy(); + } + + this.container.x = this.cameras.main.width / 2 - this.container.width / 2; + this.container.y = this.cameras.main.height / 2 - this.container.height / 2; + + var movement = { x: 0, y: 0}; + if(keys.isKeyPressed("down")) movement.y++; + if(keys.isKeyPressed("up")) movement.y--; + if(keys.isKeyPressed("left")) movement.x--; + if(keys.isKeyPressed("right")) movement.x++; + + if((movement.x !== 0 && movement.y === 0) || (movement.x === 0 && movement.y !== 0)) { + this.movePlayer(movement.x, movement.y); + } + } +} \ No newline at end of file diff --git a/src/game/index.js b/src/game/index.js index 1547d1e..57441c8 100644 --- a/src/game/index.js +++ b/src/game/index.js @@ -1,339 +1,48 @@ -import { fabric } from "fabric"; -import images from "./images"; -import { keys } from "./input"; +import { CANVAS, Game, Scale, WEBGL } from "phaser"; +import { GameScene } from "./gameScene"; import { maps } from "./maps"; -import { Sprite } from "./sprite"; +export function resize() { -/** - * @typedef Sprite - * @property {"sprite"} type - * @property {number} spriteWidth - * @property {number} spriteHeight - * @property {number} spriteIndex - * @property {number} frameTime - * - * @property {(element: HTMLImageElement, options: any) => Sprite} constructor - */ - -/** @type {HTMLCanvasElement} */ -var htmlcanvas; -/** @type {fabric.StaticCanvas} */ -var canvas; -export function setCanvas(htmlCanvas) { - htmlcanvas = htmlCanvas; - canvas = new fabric.StaticCanvas(htmlcanvas); - canvas.backgroundColor = "#01021B"; - load(); } -/** - * @type {Map} - */ -const objects = new Map; -/** - * @type {Map} - */ -const points = new Map; +var htmlcanvas; +/** @type {Game} */ +var game; +export function setCanvas(canvas) { + htmlcanvas = canvas; + var ctx = canvas.getContext("webgl2") || canvas.getContext("webgl"); + game = new Game({ + canvas: canvas, + url: window.location.host, + hideBanner: true, + type: ctx ? WEBGL : CANVAS, + context: ctx || canvas.getContext("2d"), + customEnvironment: false, + width: canvas.parentElement.clientWidth, + height: canvas.parentElement.clientHeight, + scale: { + mode: Scale.RESIZE + }, + physics: { + default: "arcade", + }, + title: "Heaventaker", + version: "beta", + scene: [new GameScene(map)], + backgroundColor: "#01021B" + }); + game.hideBanner = true; +} -function load() { - objects.set("loadingText", new fabric.Text("Loading", { - left: canvas.getWidth() / 2, - top: 0, - fill: "white", - textAlign: "center", - originX: "center", - fontFamily: "monospace" - })) - canvas.add(objects.get("loadingText")); - images.load("level1", "/sprite/level1.webp"); - images.load("lyre", "/sprite/lyre.webp"); - images.load("wind", "/sprite/wind.png"); - images.load("cloud", "/sprite/clouds.webp"); - images.load("uriel", "/sprite/uriel.png"); - images.load("michael", "/sprite/michael.png"); - images.load("spawn", "/sprite/michael.png"); - images.startLoad(); - loading = true; +export function stop() { + game.destroy(false); } var map; -/** @type {{ - background: string, - sprite: string, - offset: { x: number, y: nunber }, - size: { x: number, y: number }, - px: number, - map: string[][] - }} -*/ -var mapdata; -var mapName; -export function setMap(name) { - if(mapName === name) return; - mapdata = maps[name]; - mapName = name; - - map = mapdata.map.map(m => m.map(piece => typeof piece === "string" && { type: piece } || piece)); - - console.table(map); -} - -/** - * @type {{ - * object: fabric.Object, - * property: string, - * value: number, - * onComplete: Function, - * start: Date, - * update: Function - * }[]} - */ -var animations = []; - -/** - * Animates given property - * @param {fabric.Object} object - * @param {string} property - * @param {number} value - * @param {Function} onComplete - */ -function animate(object, property, value, onComplete) { - const length = 400; - animations.push({ - object, - property, - value, - onComplete, - start: new Date, - initial: object[property], - update() { - var diff = (new Date - this.start) / length; - var toUpdate = { - originX: "center", - originY: "center" - }; - if(diff > 1) { - onComplete(); - animations.splice(animations.indexOf(this), 1); - toUpdate[this.property] = this.value - this.object.set(toUpdate); - return; - } - toUpdate[this.property] = (this.value - this.initial) * diff + this.initial; - this.object.set(toUpdate); - } - }) -} - -/** - * Moves given object with animation - * @param {fabric.Object} source - * @param {number} fromX - * @param {number} fromY - * @param {number} toX - * @param {number} toY - * @param {Function} done - */ -function move(source, fromX, fromY, toX, toY, done = () => {}) { - if(fromX !== toX) animate(source, "left", toX * mapdata.px + (mapdata.px / 2) + canvas.getWidth() / 2 - mapdata.size.x * mapdata.px / 2, done); - if(fromY !== toY) animate(source, "top", (toY + 1) * mapdata.px + canvas.getHeight() / 2 - mapdata.size.y * mapdata.px / 2, done); - // map[toY][toX] = map[fromY][fromX]; - // map[fromY][fromX] = undefined; -} - -export function resize() { - canvas.setWidth(htmlcanvas.parentElement.clientWidth); - canvas.setHeight(htmlcanvas.parentElement.clientHeight - 7); -} - -function getPieceAt(x, y) { - return points.get(x + "-" + y)?.piece; -} - -var canMove = true; -function tryMove(toX, toY, wind = false) { - const player = objects.get("player"); - if(toX > mapdata.size.x - 1 || toY > mapdata.size.y - 1 || toX < 0 || toY < 0) return; - var point = points.get(toX + "-" + toY); - if(point) { - if(point.piece.type !== "wind") { - if(!wind && point.piece.type === "lyre") { - points.delete(toX + "-" + toY); - var diff = { x: toX - position.x, y: toY - position.y }; - points.set((toX + diff.x) + "-" + (toY + diff.y), point); - move(point.object, toX, toY, toX + diff.x, toY + diff.y); - } else return; - } - } - if(!canMove) return; - - canMove = false; - move(player, position.x, position.y, toX, toY, () => { - canMove = true; - if(point && point.piece.type === "wind") { - var res = moveInDirection(point.piece.direction); - tryMove(toX + res.x, toY + res.y, true); - } else { - if(getPieceAt(toX + 1, toY)?.type === "angel" || - getPieceAt(toX, toY + 1)?.type === "angel" || - getPieceAt(toX - 1, toY)?.type === "angel" || - getPieceAt(toX, toY - 1)?.type === "angel") { - console.log("found angel"); - } - } - }); - position.x = toX; - position.y = toY; - console.log(position, player.left / mapdata.px, player.top / mapdata.px); -} - -keys.addEventListener("keyDown", key => { - console.log(key); - const { x, y } = position; - switch(key) { - case "right": - tryMove(x + 1, y); - break; - case "left": - tryMove(x - 1, y); - break; - case "up": - tryMove(x, y - 1); - break; - case "down": - tryMove(x, y + 1); - break; - default: - console.error("Unrecognized key", key); - } -}); - -function offsetDirection(direction) { - switch(direction) { - case 1: - return { x: 1, y: 0 }; - case 2: - return { x: 1, y: 1 }; - case 3: - return { x: 0, y: 1 }; - case 4: - default: - return { x: 0, y: 0 }; - } -} - -function moveInDirection(direction) { - switch(direction) { - case 1: - return { x: 0, y: -1 }; - case 2: - return { x: 1, y: 0 }; - case 3: - return { x: 0, y: 1 }; - case 4: - return { x: -1, y: 0 }; - default: - return { x: 0, y: 0 }; - } -} - -var position = { - x: 0, - y: 0 -} - -var resizeDirty = true; -window.onresize = () => { - resizeDirty = true; -} - -var loading = true; -export function render(delta) { - if(images.areAllLoaded() && loading) { - loading = false; - - objects.set("background", new fabric.Image(images.get(mapdata.background), { - left: canvas.getWidth() / 2, - top: canvas.getHeight() / 2, - originX: "center", - originY: "center", - })); - - canvas.add(objects.get("background")); - - for(const y in map) { - const pieces = map[y]; - for(const x in pieces) { - const piece = pieces[x]; - if(!piece || piece.type === "barrier") { - objects.set("object-" + x + "-" + y, null); - continue; - } - let type = piece.type; - if(type === "angel") type = mapName; - /** @type {fabric.Image || Sprite} */ - let object; - if(piece.type === "angel" || piece.type === "spawn" || piece.type === "wind") { - object = new Sprite(images.get(type), { - spriteWidth: 100, - spriteHeight: 100 - }); - object.play(); - if(piece.type === "spawn") { - objects.set("player", object); - position = { x: parseInt(x), y: parseInt(y) }; - console.log(position); - } - } else { - object = new fabric.Image(images.get(type)); - } - object.set({ - originX: "left", - originY: "top", - left: parseInt(x) * mapdata.px + (mapdata.px / 2) + canvas.getWidth() / 2 - (mapdata.offset.x / 2), - top: parseInt(y) * mapdata.px + canvas.getHeight() / 2 - (mapdata.offset.y / 2) - 200, - angle: 90 * (piece.direction || 0) - }); - if(piece.type !== "spawn") { - points.set(x + "-" + y, { object, piece }); - } - canvas.add(object); - } - } - - canvas.remove(objects.get("loadingText")); - } else if(loading) return canvas.renderAll(); - - var background = objects.get("background"); - background.set({ - left: canvas.getWidth() / 2, - top: canvas.getHeight() / 2 - }); - if(resizeDirty) { - for(var [name, point] of points) { - if(!point) { - console.log(name, points); - continue; - } - var [x, y] = name.split("-"); - var offset = offsetDirection(point.piece.direction); - x = parseInt(x) + offset.x; - y = parseInt(y) + offset.y; - point.object.set({ - left: parseInt(x) * mapdata.px + canvas.getWidth() / 2 - mapdata.size.x * mapdata.px / 2, - top: parseInt(y) * mapdata.px + (mapdata.px / 2) + canvas.getHeight() / 2 - mapdata.size.y * mapdata.px / 2, - }); - } - resizeDirty = false; - } - var player = objects.get("player"); - player.set({ - left: position.x * mapdata.px + (mapdata.px / 2) + canvas.getWidth() / 2 - mapdata.size.x * mapdata.px / 2, - top: (position.y + 1) * mapdata.px + canvas.getHeight() / 2 - mapdata.size.y * mapdata.px / 2 - }); - for(var animation of animations) { - animation.update(); - } - canvas.renderAll(); +/** @type {string} */ +var mapname; +export function setMap(newmap) { + mapname = newmap; + map = maps[mapname]; } \ No newline at end of file diff --git a/src/game/input.js b/src/game/input.js index cdd6860..224b918 100644 --- a/src/game/input.js +++ b/src/game/input.js @@ -2,7 +2,8 @@ const keybinds = { "right": "ArrowRight", "left": "ArrowLeft", "up": "ArrowUp", - "down": "ArrowDown" + "down": "ArrowDown", + "debug": "f3" }; class KeyHandler { @@ -21,6 +22,7 @@ class KeyHandler { this.addHandlers(); this.mounted = false; this.mountHandlers(); + this.keysWasPressed = new Map(); /** @type {Map} */ this.listeners = new Map(); } @@ -73,10 +75,16 @@ class KeyHandler { } addHandlers() { this.addDocumentEventListener("keydown", (ev) => { - this.pressKeyBind(ev.key); + if(this.pressKeyBind(ev.key)) { + ev.preventDefault(); + return false; + }; }); this.addDocumentEventListener("keyup", (ev) => { - this.unpressKeyBind(ev.key); + if(this.unpressKeyBind(ev.key)) { + ev.preventDefault(); + return false; + }; }); // this.addDocumentEventListener("mousemove", (ev) => { // var rotation = Math.atan2(ev.pageY - window.innerHeight / 2, ev.pageX - window.innerWidth / 2) * 180 / Math.PI; @@ -137,12 +145,14 @@ class KeyHandler { pressKeyBind(key) { var kb = this.getKeyBind(key); if(!kb) return null; + this.keysWasPressed.set(kb, true); this.emit("keyDown", kb); return this.pressKey(kb); } unpressKeyBind(key) { var kb = this.getKeyBind(key); if(!kb) return null; + this.keysWasPressed.delete(kb); this.emit("keyUp", kb); return this.unpressKey(kb); } @@ -152,7 +162,7 @@ class KeyHandler { return this.setAxis(kb, value); } getKeyBind(key) { - var index = Object.values(keybinds).indexOf(key); + var index = Object.values(keybinds).map(t => t.toLowerCase()).indexOf(key.toLowerCase()); if(index === -1) return null; return Object.keys(keybinds)[index]; } @@ -160,7 +170,13 @@ class KeyHandler { isKeyPressed(key) { return this.keys.has(key) && this.keys.get(key) > this.treshold; } - + + wasKeyPressed(key) { + var was = this.keysWasPressed.has(key); + this.keysWasPressed.delete(key); + return was; + } + getAxis(key) { if(!this.axis.has(key)) return; var val = this.axis.get(key); diff --git a/src/game/maps.js b/src/game/maps.js index a53f946..abe4b8f 100644 --- a/src/game/maps.js +++ b/src/game/maps.js @@ -24,10 +24,10 @@ function wind(direction) { export const maps = { uriel: { background: "level1", - sprite: "/sprite/uriel.gif", + sprite: "uriel", offset: { // map offset for alignment - x: 90, - y: 0 + x: 60, + y: 100 }, size: { // map size (per block) x: 5, @@ -36,7 +36,7 @@ export const maps = { px: 100, // block size map: [ ["barrier", "barrier", "angel" , "barrier", "barrier"], - ["barrier", "barrier", null , null , "barrier"], + ["barrier", "barrier", null , "barrier", "barrier"], [null , null , wind(1) , null , null ], [null , "lyre" , wind(1) , null , null ], ["lyre" , null , "cloud" , null , null ], diff --git a/src/pages/game.svelte b/src/pages/game.svelte index a874ba3..41cbcd8 100644 --- a/src/pages/game.svelte +++ b/src/pages/game.svelte @@ -3,7 +3,7 @@ import { dialog } from "../stores/dialog.js"; import { characters } from "../stores/characters.js"; import { onMount } from "svelte"; - import { setCanvas, render, setMap, resize } from "../game"; + import { setCanvas, setMap, resize, stop } from "../game"; export var current; @@ -36,12 +36,9 @@ setMap(dialog[current].map); setCanvas(canvas); resize(); - function update(delta) { - render(delta); - frame = requestAnimationFrame(update); + return () => { + stop(); } - var frame = requestAnimationFrame(update); - return () => cancelAnimationFrame(frame); }); $: setMap(dialog[current].map);