diff options
| author | brian cully <bjc@spork.org> | 2025-12-23 21:47:59 -0500 |
|---|---|---|
| committer | brian cully <bjc@spork.org> | 2025-12-23 21:47:59 -0500 |
| commit | fdd715f4e610ae68dcb5310c37cebfbf383b1a4c (patch) | |
| tree | ced540d95376ba015703eff141c1219fa66c8711 /site/main.mjs | |
| parent | d1bc29694219a3d3d34e6dcc696ce249c7540fcd (diff) | |
| download | automathon-fdd715f4e610ae68dcb5310c37cebfbf383b1a4c.tar.gz automathon-fdd715f4e610ae68dcb5310c37cebfbf383b1a4c.zip | |
js: move arena stuff to module
Diffstat (limited to 'site/main.mjs')
| -rw-r--r-- | site/main.mjs | 78 |
1 files changed, 11 insertions, 67 deletions
diff --git a/site/main.mjs b/site/main.mjs index fd9abb6..e2cdc3e 100644 --- a/site/main.mjs +++ b/site/main.mjs @@ -1,83 +1,38 @@ +import Arena from './arena.mjs'; import Inspector from './inspector.mjs'; -// simulation speed -let TICKS_PER_SECOND = 15; -let MS_PER_TICK = 1_000 / TICKS_PER_SECOND; - // one per page -const CANVAS_SELECTOR = '#arena'; const TICK_BUTTON_SELECTOR = '#tick'; const TICK_RATE_SELECTOR = '#tick-rate-select'; const RUN_BUTTON_SELECTOR = '#run'; -const FPS_SELECTOR = '#fps'; - -const ROBO_RADIUS = 25; - -function clamp(radius, x, y, width, height) { - const xx = Math.min(Math.max(radius, x), width-radius); - const yy = Math.min(Math.max(radius, y), height-radius); - return [xx, yy]; -} - -function renderRobo(ctx, x, y) { - ctx.fillStyle = 'rgb(200 0 0)'; - ctx.beginPath(); - //ctx.arc(Math.floor(x), Math.floor(y), 25, 0, 2 * Math.PI); - ctx.arc(x, y, ROBO_RADIUS, 0, 2 * Math.PI); - ctx.fill(); -} - -function renderArena(robos, now=0) { - // interpolation factor for smoother movement independent of tick - // rate, but never tween more than 1 tick. - const canvas = document.querySelector(CANVAS_SELECTOR); - const ctx = canvas.getContext('2d'); - - ctx.clearRect(0, 0, canvas.width, canvas.height); - - robos.forEach(robo => { - const delta = robo.lastTick ? now - robo.lastTick : 0; - const timeScale = Math.min(delta / MS_PER_TICK, 1.0); - let [x, y] = [robo.x, robo.y]; - if (delta > 0) { - const [velx, vely] = [ - robo.speedx, robo.speedy - ].map(x => timeScale * x); - [x, y] = clamp(ROBO_RADIUS, robo.x + velx, robo.y + vely, canvas.width, canvas.height); - } - renderRobo(ctx, x, y); - }); -} async function loaded() { + Arena.register(); Inspector.register(); - const canvas = document.querySelector(CANVAS_SELECTOR); const robos = [{ worker: new Worker('robo.mjs', { type: 'module' }), lastTick: undefined, - x: ROBO_RADIUS + Math.floor(Math.random() * (canvas.width - ROBO_RADIUS)), - y: ROBO_RADIUS + Math.floor(Math.random() * (canvas.height - ROBO_RADIUS)), heading: 0, speed: 0, speedx: 0, speedy: 0, - }]; + }].map(r => document.querySelector(Arena.name).randStart(r)); robos.forEach((robo, i) => { robo.worker.onmessage = e => { const { kind, res, trans } = e.data; switch (kind) { case 'compile': if (res) { - renderArena(robos); + document.querySelector(Arena.name).render(robos); document.querySelectorAll(Inspector.name)[i].render(trans, true); } break; case 'tick': robo.lastTick = document.timeline.currentTime; - [robo.x, robo.y] = clamp(ROBO_RADIUS, robo.x + robo.speedx, robo.y + robo.speedy, canvas.width, canvas.height); - renderArena(robos); + [robo.x, robo.y] = document.querySelector(Arena.name).clamp(Arena.radius, robo.x + robo.speedx, robo.y + robo.speedy); + document.querySelector(Arena.name).render(robos, robo.lastTick); robo.heading = trans.vars.heading; robo.speed = trans.vars.speed; @@ -111,35 +66,24 @@ async function loaded() { document.querySelector(TICK_RATE_SELECTOR).onchange = e => { console.debug('tick rate changed', e, Number(e.target.value)); - TICKS_PER_SECOND = e.target.value; - MS_PER_TICK = 1_000 / TICKS_PER_SECOND; + document.querySelector(Arena.name).tickMS = 1_000 / e.target.value; } - document.querySelector(TICK_RATE_SELECTOR).onchange({target: { value: TICKS_PER_SECOND }}); + document.querySelectorAll(TICK_RATE_SELECTOR).forEach(elt => elt.onchange({ target: elt })); let blinkenRun = false; - let lastTime = 0; function renderFrame(t) { if (!blinkenRun) { return; } self.requestAnimationFrame(renderFrame); - - // we often get called with the same time stamp many times - // in a row due to fingerprint-reduction tech. - const ms = t - lastTime; - if (ms > 0) { - lastTime = t; - renderArena(robos, t); - const fps = document.querySelector(FPS_SELECTOR); - fps.textContent = ms > 0 ? Math.floor(1_000 / ms) : '0'; - } + document.querySelector(Arena.name).render(robos, t); } function timeout() { if (!blinkenRun) { return } - self.setTimeout(timeout, MS_PER_TICK); + self.setTimeout(timeout, document.querySelector(Arena.name).tickMS); robos.forEach(robo => robo.worker.postMessage({ kind: 'tick' })); } @@ -158,7 +102,7 @@ async function loaded() { e.currentTarget.classList.remove('blinken'); e.currentTarget.classList.add('halten'); e.currentTarget.querySelector('title').textContent = 'blinken'; - document.querySelector(FPS_SELECTOR).textContent = 'n/a'; + document.querySelector(Arena.name).invalidateFPS(); } } } |
