/* Original renderer/controller; owns the only animation loop. MIT. */ import {createState,start,togglePause,advance} from './host.mjs'; import {createInput} from './input.mjs'; const canvas=document.querySelector('#world'),ctx=canvas.getContext('2d'),status=document.querySelector('#status'),mode=document.querySelector('#mode'),pulseButton=document.querySelector('#pulse'); let state=createState(),frame=0,last=null,pulseRequested=false,announced=''; const input=createInput(document,window,canvas,()=>{if(state.status==='running'){togglePause(state);clear();}}); function clear(){input.clear();pulseRequested=false;last=null;} function circle(x,y,r,color){ctx.fillStyle=color;ctx.beginPath();ctx.arc(x,y,r,0,Math.PI*2);ctx.fill();} function render(){ctx.clearRect(0,0,640,360);for(const t of state.tokens)if(!t.collected)circle(t.x,t.y,9,'#ffda76');for(const h of state.hazards)circle(h.x,h.y,12,'#ff799c');circle(state.player.x,state.player.y,14,'#75ffd6');ctx.fillStyle='#fff';ctx.font='18px system-ui';ctx.fillText(`Tokens ${state.collected}/4 · Health ${state.hp} · Charges ${state.charges} · ${Math.ceil(state.remaining)}s`,16,28);const message=`${state.mode}: ${state.status}. Tokens ${state.collected}/4. Health ${state.hp}. Charges ${state.charges}.`;if(message!==announced){status.textContent=message;announced=message;}} function tick(now){if(last!==null)advance(state,{...input.read(),pulse:pulseRequested},(now-last)/1000);last=now;pulseRequested=false;render();frame=requestAnimationFrame(tick);} document.querySelector('#start').addEventListener('click',()=>{clear();state=start(mode.value);canvas.focus();}); document.querySelector('#pause').addEventListener('click',()=>{togglePause(state);clear();}); mode.addEventListener('change',()=>{clear();state=createState(mode.value);}); pulseButton.addEventListener('click',()=>{if(state.status==='running')pulseRequested=true;}); window.addEventListener('pagehide',()=>{cancelAnimationFrame(frame);input.destroy();clear();}); window.addEventListener('pageshow',event=>{if(event.persisted)window.location.reload();}); render();frame=requestAnimationFrame(tick);