diff --git a/assembly/Game.ts b/assembly/Game.ts index 08433b7..633ab45 100644 --- a/assembly/Game.ts +++ b/assembly/Game.ts @@ -6,6 +6,7 @@ import { Thing, Direction, Flag, Water } from './Thing'; import { Monster, Fly } from './Monster'; const JOURNEY_LENGTH = 150; // length of journey base +const FPS = 8; export enum Controls { Up = 1, @@ -23,6 +24,7 @@ export class Game { private flag: Flag; private score: Score; + private lastUpdate: i64; private level: i32 = 1; private canvas: Canvas; @@ -32,6 +34,7 @@ export class Game { this.scene = new Scene(canvas); this.player = new Player(canvas); this.score = new Score(canvas, canvas.width - 3, canvas.height - 3); + this.lastUpdate = Date.now(); this.things = []; this.obstacles = []; @@ -50,6 +53,9 @@ export class Game { } update(control: Controls): void { + if (!this.readyToUpdate()) { + return; + } if (!this.player.isAlive()) { this.canvas.turnToGray(); return; @@ -176,4 +182,13 @@ export class Game { } return false; } + + private readyToUpdate(): boolean { + const now = Date.now(); + if (now > this.lastUpdate + 1000 / FPS) { + this.lastUpdate = now; + return true; + } + return false; + } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 68d3f0f..cb60361 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,18 +8,18 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "@assemblyscript/loader": "^0.19.4" + "@assemblyscript/loader": "^0.19.7" }, "devDependencies": { - "assemblyscript": "^0.19.4", + "assemblyscript": "^0.19.7", "get-image-data": "^5.0.0", "local-web-server": "^4.2.1" } }, "node_modules/@assemblyscript/loader": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.19.4.tgz", - "integrity": "sha512-sKXgvl3tGg0BkrgQmiNH528GVgj8cYd545ur31Df6DgCI5bI1bCbaEpvPcyd0c+FkOYb455pn/C+egdxo4Eg4g==" + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.19.7.tgz", + "integrity": "sha512-/BdvOMHnfW3uIHFEgDPRbmA+BoQjuYpjKIZgI3p4sG8Jxgy9UuQW7cQUFx7dRlFUk/SBVCoB8N7412NgKyctqg==" }, "node_modules/@babel/runtime": { "version": "7.14.6", @@ -661,12 +661,12 @@ } }, "node_modules/assemblyscript": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.4.tgz", - "integrity": "sha512-3wa4IVNxbwRgUI+T4vhpFB0sJsVYqMY39XCujahp1T/vd16miOAcdVukOYMzQtT1BdmbesyoiXHLHoYnKRzh+A==", + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.7.tgz", + "integrity": "sha512-0Vs27D9yIqxbwAx/zp2CNMCgR/Aa2cQlMZO+ctW30rhQ0/UOS/J9PkFXRxUVNMYj0xwEMT/Cq6l9flXO2ZJFcQ==", "dev": true, "dependencies": { - "binaryen": "101.0.0-nightly.20210604", + "binaryen": "101.0.0-nightly.20210703", "long": "^4.0.0" }, "bin": { @@ -718,9 +718,9 @@ "dev": true }, "node_modules/binaryen": { - "version": "101.0.0-nightly.20210604", - "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-101.0.0-nightly.20210604.tgz", - "integrity": "sha512-aTgX1JDN8m3tTFK8g9hazJcEOdQl7mK4yVfElkKAh7q+TRUCaea4a2SMLr1z2xZL7s9N4lkrvrBblxRuEPvxWQ==", + "version": "101.0.0-nightly.20210703", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-101.0.0-nightly.20210703.tgz", + "integrity": "sha512-7iuRy/aSsd8BlO0ZOG4GqDI8z66UhazD10eeC3i14SOhZJ+MLC3I+BX5ydr3nk9g5j2PDGndxuYvm0gy+VJHYg==", "dev": true, "bin": { "wasm-opt": "bin/wasm-opt" @@ -3673,9 +3673,9 @@ }, "dependencies": { "@assemblyscript/loader": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.19.4.tgz", - "integrity": "sha512-sKXgvl3tGg0BkrgQmiNH528GVgj8cYd545ur31Df6DgCI5bI1bCbaEpvPcyd0c+FkOYb455pn/C+egdxo4Eg4g==" + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.19.7.tgz", + "integrity": "sha512-/BdvOMHnfW3uIHFEgDPRbmA+BoQjuYpjKIZgI3p4sG8Jxgy9UuQW7cQUFx7dRlFUk/SBVCoB8N7412NgKyctqg==" }, "@babel/runtime": { "version": "7.14.6", @@ -4184,12 +4184,12 @@ "dev": true }, "assemblyscript": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.4.tgz", - "integrity": "sha512-3wa4IVNxbwRgUI+T4vhpFB0sJsVYqMY39XCujahp1T/vd16miOAcdVukOYMzQtT1BdmbesyoiXHLHoYnKRzh+A==", + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.7.tgz", + "integrity": "sha512-0Vs27D9yIqxbwAx/zp2CNMCgR/Aa2cQlMZO+ctW30rhQ0/UOS/J9PkFXRxUVNMYj0xwEMT/Cq6l9flXO2ZJFcQ==", "dev": true, "requires": { - "binaryen": "101.0.0-nightly.20210604", + "binaryen": "101.0.0-nightly.20210703", "long": "^4.0.0" } }, @@ -4216,9 +4216,9 @@ "dev": true }, "binaryen": { - "version": "101.0.0-nightly.20210604", - "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-101.0.0-nightly.20210604.tgz", - "integrity": "sha512-aTgX1JDN8m3tTFK8g9hazJcEOdQl7mK4yVfElkKAh7q+TRUCaea4a2SMLr1z2xZL7s9N4lkrvrBblxRuEPvxWQ==", + "version": "101.0.0-nightly.20210703", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-101.0.0-nightly.20210703.tgz", + "integrity": "sha512-7iuRy/aSsd8BlO0ZOG4GqDI8z66UhazD10eeC3i14SOhZJ+MLC3I+BX5ydr3nk9g5j2PDGndxuYvm0gy+VJHYg==", "dev": true }, "bl": { diff --git a/package.json b/package.json index 6dfb754..06b7234 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,10 @@ "author": "Tomas Tulka (ttulka)", "license": "MIT", "dependencies": { - "@assemblyscript/loader": "^0.19.4" + "@assemblyscript/loader": "^0.19.7" }, "devDependencies": { - "assemblyscript": "^0.19.4", + "assemblyscript": "^0.19.7", "get-image-data": "^5.0.0", "local-web-server": "^4.2.1" } diff --git a/src/index.js b/src/index.js index 8b3b658..b727f0f 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -const WIDTH = 100, HEIGHT = 100; +const WIDTH = 100, HEIGHT = 100, SIZE = WIDTH * HEIGHT; const canvas = document.querySelector('canvas'); const ctx = canvas.getContext('2d'); @@ -30,15 +30,22 @@ document.addEventListener('keydown', event => { case "ArrowDown": control = Controls.Down; break; -} + default: + control = Controls.None; + break; + } +}); +document.addEventListener('keyup', event => { + control = Controls.None; }); async function loadWasm() { const wasm = await WebAssembly .instantiateStreaming(fetch('../build/optimized.wasm'), { + Date, env: { abort: (_msg, _file, line, column) => console.error(`Abort at ${line}:${column}`), - seed: () => new Date().getTime() + seed: Date.now }}); return wasm.instance.exports; } @@ -48,26 +55,21 @@ async function start() { wasm.start(); console.log(wasm) - const imageData = ctx.getImageData(0, 0, WIDTH, HEIGHT); - - const updateCall = () => update(wasm, imageData); - setInterval(updateCall, 150); -} - -function update(wasm, imageData) { - //console.log('update', new Date()); - wasm.update(wasm[control]); + const mem = new Uint32Array(wasm.memory.buffer); // 32bit => 8bit color * 4 (RGBA) + + const imageData = ctx.createImageData(WIDTH, HEIGHT); + const argb = new Uint32Array(imageData.data.buffer); - writeImageData(imageData, wasm.memory.buffer); - - control = Controls.None; + const updateCall = () => { + update(wasm, mem, imageData, argb); + window.requestAnimationFrame(updateCall); + } + window.requestAnimationFrame(updateCall); } -function writeImageData(imageData, buffer) { - const bytes = new Uint8ClampedArray(buffer); +function update(wasm, mem, imageData, argb) { + wasm.update(wasm[control]); - for (let i = 0; i < WIDTH * HEIGHT * 4; i++) - imageData.data[i] = bytes[i]; - - ctx.putImageData(imageData, 0, 0); + argb.set(mem.subarray(0, SIZE)); // copy output to image buffer + ctx.putImageData(imageData, 0, 0); // apply image buffer }