summaryrefslogtreecommitdiffstats
path: root/site/main.mjs
diff options
context:
space:
mode:
authorbrian cully <bjc@spork.org>2025-12-23 21:47:59 -0500
committerbrian cully <bjc@spork.org>2025-12-23 21:47:59 -0500
commitfdd715f4e610ae68dcb5310c37cebfbf383b1a4c (patch)
treeced540d95376ba015703eff141c1219fa66c8711 /site/main.mjs
parentd1bc29694219a3d3d34e6dcc696ce249c7540fcd (diff)
downloadautomathon-fdd715f4e610ae68dcb5310c37cebfbf383b1a4c.tar.gz
automathon-fdd715f4e610ae68dcb5310c37cebfbf383b1a4c.zip
js: move arena stuff to module
Diffstat (limited to 'site/main.mjs')
-rw-r--r--site/main.mjs78
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();
}
}
}