/* anim.js – drop this at top of your script or in a module */ var Anim = (() => { const DEFAULT_MIN = 1 / 60; /* 16 ms – one frame */ function play(source, loop=true){ return { src : source, idx : 0, timer : 0, loop : loop ?? source.loop ?? true }; } function update(a, dt){ a.timer += dt; const frames = a.src.frames; while(true){ const time = Math.max(frames[a.idx].time || 0, Anim.minDelay); if(a.timer < time) break; /* still on current frame */ a.timer -= time; a.idx += 1; if(a.idx >= frames.length){ if(a.loop) a.idx = 0; else { a.idx = frames.length - 1; a.timer = 0; break; } } } } function current(a){ return a.src.frames[a.idx].image; } function updateAll(arr, dt){ for(const a of arr) update(a, dt); } function draw(a, pos, opt, pipe){ draw2d.image(current(a), pos, 0, [0,0], [0,0], opt, pipe); } return {play, update, current, updateAll, draw, minDelay:DEFAULT_MIN}; })(); var render = use('render'); /* ── init window ───────────────────────── */ render.initialize({width:500, height:500, resolution_x:500, resolution_y:500, mode:'letterboxed', refresh:60}); var os = use('os'); var draw2d = use('draw2d'); var gfx = use('graphics'); var transform = use('transform'); var camera = { size: [500,500], transform: new transform, fov:50, near_z: 0, far_z: 1000, surface: undefined, viewport: {x:0,y:0,width:1,height:1}, ortho:true, anchor:[0,0], } /* ── load animations ───────────────────── */ const crab = gfx.texture('tests/crab'); // gif → Animation const warrior = gfx.texture('tests/warrior'); // ase → {Original:Animation} const anims = [ Anim.play(crab), // crab.frames Anim.play(warrior.Run) // warrior.Original.frames ]; /* ── fps probe vars ───────────────────── */ var fpsTimer=0, fpsCount=0 Anim.minDelay = 1 / 100; // 10 ms, feel free to tune later let last = os.now(); function loop(){ const now = os.now(); const dt = now - last; // real frame time last = now; Anim.updateAll(anims, dt); /* draw */ render.clear([22/255,120/255,194/255,255/255]); render.camera(camera); Anim.draw(anims[0], [ 50,200]); Anim.draw(anims[1], [250,200]); render.present(); /* fps probe (unchanged) */ fpsTimer += dt; fpsCount++; if(fpsTimer >= 0.5){ prosperon.window.title = `Anim demo FPS ${(fpsCount/fpsTimer).toFixed(1)}`; fpsTimer = fpsCount = 0; } /* schedule next tick: aim for 60 Hz but won’t matter to anim speed */ $_.delay(loop, Math.max(0, (1/60) - (os.now()-now))); } loop();