@pixelation/engine
Version:
A simple pixel art game engine.
6 lines (5 loc) • 33.9 kB
JavaScript
"use strict";var Q=Object.defineProperty;var X=(h,t,e)=>t in h?Q(h,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):h[t]=e;var u=(h,t,e)=>X(h,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const x=require("@pixelation/aseprite"),E=()=>{},P=h=>{const t=new ArrayBuffer(h.byteLength);return new Uint8Array(t).set(new Uint8Array(h)),t},Y=Object.freeze(Object.defineProperty({__proto__:null,cloneArrayBuffer:P,noop:E},Symbol.toStringTag,{value:"Module"}));class R{constructor(t,e,s={track:"main",strategy:"once"}){u(this,"ready",!1);u(this,"queued",!1);u(this,"playing",!1);u(this,"duration",0);u(this,"position",0);u(this,"started",0);u(this,"source");this.audio=t,this.raw=e,this.options=s,s.track||(s.track="main"),s.strategy||(s.strategy="once"),t.assets.push(this),this.source=new AudioBufferSourceNode(t.context,{loop:s.strategy==="loop"||s.strategy==="loop-restart"}),this.source.connect(t[s.track]),this.source.onended=()=>{this.stop()},t.context.decodeAudioData(P(e),n=>{this.source.buffer=n,this.ready=!0,this.duration=n.duration,this.position=0,this.queued&&this.play()})}destroy(){const t=this.audio.assets.indexOf(this);t!==-1&&(this.audio.assets=this.audio.assets.splice(t,1)),this.source.disconnect(),this.source.buffer=null}update(){const t=this.audio.context.currentTime-this.started;this.position=t%this.duration,this.playing&&t>=this.duration&&!this.source.loop&&this.stop()}clone(){return new R(this.audio,this.raw,this.options)}play(){if(!this.ready){this.queued=!0;return}if(this.playing)if(this.options.strategy==="once-restart"||this.options.strategy==="loop-restart")this.source.stop();else return;this.started=this.audio.context.currentTime+.01,this.source.start(this.started)}stop(){if(!this.ready){this.queued=!1;return}this.source.stop(),this.started=0,this.position=0}}class j{constructor(){u(this,"context",new AudioContext);u(this,"main",this.context.createGain());u(this,"sfx",this.context.createGain());u(this,"speech",this.context.createGain());u(this,"music",this.context.createGain());u(this,"assets",[]);this.main.connect(this.context.destination),this.main.gain.value=1,this.sfx.connect(this.main),this.main.gain.value=1,this.speech.connect(this.main),this.main.gain.value=1,this.music.connect(this.main),this.main.gain.value=1}asset(t,e={track:"main",strategy:"once"}){return e.track||(e.track="main"),e.strategy||(e.strategy="once"),new R(this,t,e)}volume(t,e){this[t].gain.value=e}once(t){const e=t.clone();e.play();const s=e.update.bind(e);e.update=()=>{s(),e.playing||e.destroy()}}play(t){const e=t.clone();return e.play(),e}update(){for(const t of this.assets)t.update()}}const K=Object.freeze(Object.defineProperty({__proto__:null,Audio:j,AudioAsset:R},Symbol.toStringTag,{value:"Module"})),g=(h,t,e,s)=>{let n=0;return n|=h<<24,n|=t<<16,n|=e<<8,n|=s,n},v=h=>[h>>24&255,h>>16&255,h>>8&255,h&255],N=/^#(?:(?<full>[a-fA-F0-9]{6})|(?:(?<short>[a-fA-F0-9]{3})))$/,q=h=>{const t=N.exec(h);if(!t||!t.groups)throw new Error(`Invalid hex color: ${h}`);if(t.groups.short)return g(parseInt(t.groups.short[0]+t.groups.short[0],16),parseInt(t.groups.short[1]+t.groups.short[1],16),parseInt(t.groups.short[2]+t.groups.short[2],16),255);if(t.groups.full)return g(parseInt(t.groups.full[0]+t.groups.full[1],16),parseInt(t.groups.full[2]+t.groups.full[3],16),parseInt(t.groups.full[4]+t.groups.full[5],16),255);throw new Error(`Invalid hex color: ${h}`)},J=(h,t,e)=>g(h,t,e,255),_=(h,t)=>{if(t instanceof Uint8Array)return t.length===4?g(t[0],t[1],t[2],255):g(t[0],t[0],t[0],255);{const e=h.palette[String(t)];return e?g(e.red,e.green,e.blue,255):(console.warn(`Invalid color index: ${t}`),U)}},C=(h,t,e)=>(e<0&&(e+=1),e>1&&(e-=1),e<1/6?h+(t-h)*6*e:e<1/2?t:e<2/3?h+(t-h)*(2/3-e)*6:h),W=(h,t,e)=>{let s=0,n=0,d=0;if(t===0)s=e,n=e,d=e;else{const a=e<.5?e*(1+t):e+t-e*t,i=2*e-a;s=C(i,a,h+1/3),n=C(i,a,h),d=C(i,a,h-1/3)}return g(Math.round(s*255),Math.round(n*255),Math.round(d*255),255)},Z=(h,t,e,s,n=255)=>{let d=h*(1-s)+s,a=t*(1-s)+s,i=e*(1-s)+s;return g(Math.round((1-d)*255+.5),Math.round((1-a)*255+.5),Math.round((1-i)*255+.5),n)},k=(h,t)=>{const[e,s,n,d]=v(t),[a,i,r,l]=v(h),o=d/255,c=l/255,f=o+c*(1-o);if(f===0)return g(0,0,0,0);const p=(e*o+a*c*(1-o))/f,m=(s*o+i*c*(1-o))/f,y=(n*o+r*c*(1-o))/f;return g(Math.round(p),Math.round(m),Math.round(y),Math.round(f*255))},U=q("#c84cc6"),V=Object.freeze(Object.defineProperty({__proto__:null,PLACEHOLDER:U,blend:k,fromAsepritePixel:_,fromCmyk:Z,fromHex:q,fromHsl:W,fromRgb:J,pack:g,unpack:v},Symbol.toStringTag,{value:"Module"}));var z=(h=>(h.Position="p",h.Velocity="v",h.Step="s",h))(z||{});const tt=(h=0,t=.5,e=.1,s=.1)=>{let n=0;const d=i=>{const r=(i-h)*e;n+=r,n*=t,h+=n,n<s&&n>-s&&r<s&&r>-s&&(h=i,n=0)};function a(i,r){if(arguments.length===0)return h;switch(i){case"p":return r!==void 0&&(h=r),h;case"v":return r!==void 0&&n+r<=s&&n+r>=-s&&(n=r),n}return arguments.length===1&&(i==="s"?d(h):typeof i=="number"&&d(i)),h}return a},et=(h,t,e)=>(1-e)*h+e*t,it=(h,t,e,s)=>{if(h===t)return h;const n=t+(h-t)*Math.exp(-e*s);return Math.abs(n-h)<.001?t:n},st=(h,t,e)=>g(...B(v(h),v(t),e)),B=(h,t,e)=>[Math.round(h[0]+(t[0]-h[0])*e),Math.round(h[1]+(t[1]-h[1])*e),Math.round(h[2]+(t[2]-h[2])*e),Math.round(h[3]+(t[3]-h[3])*e)],at=h=>h*h,nt=h=>h*(2-h),ht=h=>h<.5?2*h*h:-1+(4-2*h)*h,rt=h=>h*h*h,dt=h=>--h*h*h+1,lt=h=>(h/=.5)<1?.5*h*h*h:.5*((h-=2)*h*h+2),ot=h=>h*h*h*h,ft=h=>1- --h*h*h*h,ct=h=>(h/=.5)<1?.5*h*h*h*h:-.5*((h-=2)*h*h*h-2),pt=h=>h*h*h*h*h,ut=h=>1+--h*h*h*h*h,gt=h=>(h/=.5)<1?.5*h*h*h*h*h:.5*((h-=2)*h*h*h*h+2),mt=h=>1-Math.cos(h*Math.PI/2),wt=h=>Math.sin(h*Math.PI/2),yt=h=>.5*(1-Math.cos(Math.PI*h)),Mt=h=>h===0?0:Math.pow(2,10*(h-1)),bt=h=>h===1?1:1-Math.pow(2,-10*h),xt=h=>h===0||h===1?h:(h/=.5)<1?.5*Math.pow(2,10*(h-1)):.5*(2-Math.pow(2,-10*--h)),vt=h=>1-Math.sqrt(1-h*h),It=h=>Math.sqrt(1- --h*h),St=h=>(h/=.5)<1?-.5*(Math.sqrt(1-h*h)-1):.5*(Math.sqrt(1-(h-=2)*h)+1),At=Object.freeze(Object.defineProperty({__proto__:null,SmoothUpdateKind:z,easeIn:at,easeInCirc:vt,easeInCubic:rt,easeInExpo:Mt,easeInOut:ht,easeInOutCirc:St,easeInOutCubic:lt,easeInOutExpo:xt,easeInOutQuart:ct,easeInOutQuint:gt,easeInOutSine:yt,easeInQuart:ot,easeInQuint:pt,easeInSine:mt,easeOut:nt,easeOutCirc:It,easeOutCubic:dt,easeOutExpo:bt,easeOutQuart:ft,easeOutQuint:ut,easeOutSine:wt,lerp:et,lerpColor:st,lerpColorUnpacked:B,lerpSmooth:it,smooth:tt},Symbol.toStringTag,{value:"Module"})),b=class b{constructor(t){u(this,"data");if(t.length===0)throw new Error("Matrix3 requires 9 elements, but got none.");if(Array.isArray(t[0])?this.data=t.flat():this.data=t,this.data.length!==9)throw new Error(`Matrix3 requires 9 elements, but got ${this.data.length}.`)}static fromTranslation(t,e){return new b([[1,0,t],[0,1,e],[0,0,1]])}static fromScale(t,e){return new b([[t,0,0],[0,e,0],[0,0,1]])}static fromRotation(t){const e=Math.cos(t),s=Math.sin(t);return new b([[e,-s,0],[s,e,0],[0,0,1]])}static fromSkew(t,e){return new b([[1,Math.tan(t),0],[Math.tan(e),1,0],[0,0,1]])}toString(){const[t,e,s,n,d,a,i,r,l]=this.data,o=Math.max(t.toString().length,n.toString().length,i.toString().length),c=Math.max(e.toString().length,d.toString().length,r.toString().length),f=Math.max(s.toString().length,a.toString().length,l.toString().length),p=`${t.toString().padEnd(o)} ${e.toString().padEnd(c)} ${s.toString().padEnd(f)}`,m=`${n.toString().padEnd(o)} ${d.toString().padEnd(c)} ${a.toString().padEnd(f)}`,y=`${i.toString().padEnd(o)} ${r.toString().padEnd(c)} ${l.toString().padEnd(f)}`,M=p.length;return`┌ ${" ".repeat(M)} ┐
│ ${p} │
│ ${m} │
│ ${y} │
└ ${" ".repeat(M)} ┘`}isIdentity(){if(this===b.identity)return!0;const[t,e,s,n,d,a,i,r,l]=this.data;return t===1&&e===0&&s===0&&n===0&&d===1&&a===0&&i===0&&r===0&&l===1}mul(t){const e=this.data,s=t.data,n=[e[0]*s[0]+e[1]*s[3]+e[2]*s[6],e[0]*s[1]+e[1]*s[4]+e[2]*s[7],e[0]*s[2]+e[1]*s[5]+e[2]*s[8],e[3]*s[0]+e[4]*s[3]+e[5]*s[6],e[3]*s[1]+e[4]*s[4]+e[5]*s[7],e[3]*s[2]+e[4]*s[5]+e[5]*s[8],e[6]*s[0]+e[7]*s[3]+e[8]*s[6],e[6]*s[1]+e[7]*s[4]+e[8]*s[7],e[6]*s[2]+e[7]*s[5]+e[8]*s[8]];return new b(n)}translate(t,e){return new b([[1,0,t],[0,1,e],[0,0,1]]).mul(this)}scale(t,e){return new b([[t,0,0],[0,e,0],[0,0,1]]).mul(this)}rotate(t){const e=Math.cos(t),s=Math.sin(t);return new b([[e,-s,0],[s,e,0],[0,0,1]]).mul(this)}skew(t,e){return new b([[1,Math.tan(t),0],[Math.tan(e),1,0],[0,0,1]]).mul(this)}inv(){const[t,e,s,n,d,a,i,r,l]=this.data,o=t*(d*l-a*r)-e*(n*l-a*i)+s*(n*r-d*i);if(o===0)throw new Error("Matrix3 is not invertible.");const c=1/o;return new b([(d*l-a*r)*c,(s*r-e*l)*c,(e*a-s*d)*c,(a*i-n*l)*c,(t*l-s*i)*c,(s*n-t*a)*c,(n*r-d*i)*c,(e*i-t*r)*c,(t*d-e*n)*c])}apply(t,e){const[s,n,d,a,i,r,l,o,c]=this.data;return{x:s*t+n*e+d,y:a*t+i*e+r}}applyToRect(t,e,s,n){const d=this.apply(t,e),a=this.apply(t+s,e),i=this.apply(t+s,e+n),r=this.apply(t,e+n),l=Math.min(d.x,a.x,i.x,r.x),o=Math.max(d.x,a.x,i.x,r.x),c=Math.min(d.y,a.y,i.y,r.y),f=Math.max(d.y,a.y,i.y,r.y);return{x:l,y:c,width:o-l,height:f-c}}};u(b,"identity",new b([[1,0,0],[0,1,0],[0,0,1]]));let w=b;class S{constructor(t,e){this.x=t,this.y=e}add(t){return new S(this.x+t.x,this.y+t.y)}sub(t){return new S(this.x-t.x,this.y-t.y)}mul(t){return new S(this.x*t,this.y*t)}div(t){return new S(this.x/t,this.y/t)}mag(){return Math.sqrt(this.x*this.x+this.y*this.y)}norm(){const t=this.mag();return new S(this.x/t,this.y/t)}}const T=(h,t,e,s,n,d,a,i)=>{const r=(h*(i-s)-t*(a-e)+a*s-i*e)/((n-e)*(i-s)-(d-s)*(a-e)),l=(t-s-r*(d-s))/(i-s);return!(r<0||l<0||r+l>1)},kt=Object.freeze(Object.defineProperty({__proto__:null,Matrix3:w,Vector2:S,isPointInTri:T},Symbol.toStringTag,{value:"Module"}));class Tt{constructor(t,e,s=new ImageData(t,e)){u(this,"virtual",!1);u(this,"canvas");u(this,"context");this.width=t,this.height=e,this.image=s,this.canvas=document.createElement("canvas"),this.canvas.setAttribute("tabindex","0"),this.canvas.style.imageRendering="pixelated",this.canvas.width=t,this.canvas.height=e,this.context=this.canvas.getContext("2d"),this.context.imageSmoothingEnabled=!1}commit(){this.context.putImageData(this.image,0,0)}clear(){for(let t=0;t<this.image.data.length;t+=4)this.image.data[t+0]=0,this.image.data[t+1]=0,this.image.data[t+2]=0,this.image.data[t+3]=255}pixel(t,e,s){if(t<0||t>=this.width||e<0||e>=this.height)return;const[n,d,a,i]=v(s);t|=0,e|=0;const r=(e*this.width+t)*4;if(i===255)this.image.data[r+0]=n,this.image.data[r+1]=d,this.image.data[r+2]=a,this.image.data[r+3]=i;else if(i>0){const l=v(k(g(this.image.data[r+0],this.image.data[r+1],this.image.data[r+2],this.image.data[r+3]),s));this.image.data[r+0]=l[0],this.image.data[r+1]=l[1],this.image.data[r+2]=l[2],this.image.data[r+3]=l[3]}}pixelUnpacked(t,e,s,n,d,a){if(t<0||t>=this.width||e<0||e>=this.height)return;t|=0,e|=0;const i=(e*this.width+t)*4;if(a===255)this.image.data[i+0]=s,this.image.data[i+1]=n,this.image.data[i+2]=d,this.image.data[i+3]=a;else if(a>0){const r=v(k(g(this.image.data[i+0],this.image.data[i+1],this.image.data[i+2],this.image.data[i+3]),g(s,n,d,a)));this.image.data[i+0]=r[0],this.image.data[i+1]=r[1],this.image.data[i+2]=r[2],this.image.data[i+3]=r[3]}}blit(t,e=0,s=0,n=w.identity){if(n.isIdentity()){for(let d=0;d<t.height;d++)if(!(d+s<0||d+s>=this.height))for(let a=0;a<t.width;a++){if(a+e<0||a+e>=this.width)continue;const i=(d*t.width+a)*4;this.pixelUnpacked(a+e,d+s,t.data[i+0],t.data[i+1],t.data[i+2],t.data[i+3])}}else{const d=n.applyToRect(e,s,t.width,t.height),a=n.inv();for(let i=Math.floor(d.y);i<Math.ceil(d.y+d.height);i++)for(let r=Math.floor(d.x);r<Math.ceil(d.x+d.width);r++){const l=a.apply(r,i);if(l.x-=e,l.y-=s,l.x<0||l.x>=t.width||l.y<0||l.y>=t.height)continue;const o=(Math.floor(l.y)*t.width+Math.floor(l.x))*4;this.pixel(r,i,g(t.data[o+0],t.data[o+1],t.data[o+2],t.data[o+3]))}}}blitMask(t,e,s=0,n=0,d=w.identity){if(d.isIdentity()){for(let a=0;a<t.height;a++)if(!(a+n<0||a+n>=this.height))for(let i=0;i<t.width;i++){if(i+s<0||i+s>=this.width)continue;const r=(a*e.width+i)*4;if(r+3>=e.data.length)continue;const l=(a*t.width+i)*4;e.data[r]===255&&e.data[r+1]===255&&e.data[r+2]===255&&e.data[r+3]===255&&this.pixelUnpacked(i+s,a+n,t.data[l+0],t.data[l+1],t.data[l+2],t.data[l+3])}}else{const a=d.applyToRect(s,n,t.width,t.height),i=d.inv();for(let r=Math.floor(a.y);r<Math.ceil(a.y+a.height);r++)for(let l=Math.floor(a.x);l<Math.ceil(a.x+a.width);l++){const o=i.apply(l,r);if(o.x-=s,o.y-=n,o.x<0||o.x>=t.width||o.y<0||o.y>=t.height)continue;const c=(Math.floor(o.y)*e.width+Math.floor(o.x))*4;if(c+3>=e.data.length)continue;const f=(Math.floor(o.y)*t.width+Math.floor(o.x))*4;e.data[c]===255&&e.data[c+1]===255&&e.data[c+2]===255&&e.data[c+3]===255&&this.pixel(l,r,g(t.data[f+0],t.data[f+1],t.data[f+2],t.data[f+3]))}}}line(t,e,s,n,d){if(t|=0,e|=0,s|=0,n|=0,t-s===0){for(let f=e;f<=n;f++)this.pixel(t,f,d);return}if(e-n===0){for(let f=t;f<=s;f++)this.pixel(f,e,d);return}t>s&&([t,s]=[s,t],[e,n]=[n,e]);const a=(n-e)/(s-t);if(a===1)if(e>n){for(let f=t,p=e;f<=s;f++,p--)this.pixel(f,p,d);return}else{for(let f=t,p=e;f<=s;f++,p++)this.pixel(f,p,d);return}if(a===-1)if(e>n){for(let f=t,p=e;f<=s;f++,p--)this.pixel(f,p,d);return}else{for(let f=t,p=e;f<=s;f++,p++)this.pixel(f,p,d);return}const i=Math.abs(s-t),r=Math.abs(n-e),l=Math.sign(s-t),o=Math.sign(n-e);let c=i-r;for(;;){if(this.pixel(t,e,d),t===s&&e===n)return;const f=2*c;f>-r&&(c-=r,t+=l),f<i&&(c+=i,e+=o)}}fillRect(t,e,s,n,d,a=w.identity){if(a.isIdentity())for(let i=t;i<t+s;i++)for(let r=e;r<e+n;r++)this.pixel(i,r,d);else{const i=a.applyToRect(t,e,s,n),r=a.inv();for(let l=i.x;l<i.x+i.width;l++)for(let o=i.y;o<i.y+i.height;o++){const c=r.apply(l,o);c.x>=t&&c.x<t+s&&c.y>=e&&c.y<e+n&&this.pixel(l,o,d)}}}traceRect(t,e,s,n,d,a=w.identity){if(a.isIdentity())this.line(t,e,t+s,e,d),this.line(t+s,e,t+s,e+n,d),this.line(t,e+n,t+s,e+n,d),this.line(t,e,t,e+n,d);else{const i=a.apply(t,e),r=a.apply(t+s,e),l=a.apply(t,e+n),o=a.apply(t+s,e+n);this.line(i.x,i.y,r.x,r.y,d),this.line(r.x,r.y,o.x,o.y,d),this.line(o.x,o.y,l.x,l.y,d),this.line(l.x,l.y,i.x,i.y,d)}}fillCirc(t,e,s,n,d=w.identity){if(d.isIdentity()){let a=s,i=0,r=1-s;for(;a>=i;)this.line(-a+t,-i+e,-a+t,i+e,n),this.line(-i+t,-a+e,-i+t,a+e,n),this.line(i+t,-a+e,i+t,a+e,n),this.line(a+t,-i+e,a+t,i+e,n),i++,r<0?r+=2*i+1:(a--,r+=2*(i-a+1))}else{const a=s*2+1,i=d.applyToRect(t-a/2,e-a/2,a,a),r=d.inv();for(let l=Math.floor(i.x);l<Math.ceil(i.x+i.width);l++)for(let o=Math.floor(i.y);o<Math.ceil(i.y+i.height);o++){const c=r.apply(l,o);Math.sqrt((c.x-t)**2+(c.y-e)**2)<=a/2&&this.pixel(l,o,n)}}}traceCirc(t,e,s,n,d=w.identity){if(d.isIdentity()){let a=s,i=0,r=1-s;for(;a>=i;)this.pixel(a+t,i+e,n),this.pixel(i+t,a+e,n),this.pixel(-a+t,i+e,n),this.pixel(-i+t,a+e,n),this.pixel(-a+t,-i+e,n),this.pixel(-i+t,-a+e,n),this.pixel(a+t,-i+e,n),this.pixel(i+t,-a+e,n),i++,r<0?r+=2*i+1:(a--,r+=2*(i-a+1))}else{const a=s*2+1,i=d.applyToRect(t-a/2,e-a/2,a,a),r=d.inv();for(let l=Math.floor(i.x);l<Math.ceil(i.x+i.width);l++)for(let o=Math.floor(i.y);o<Math.ceil(i.y+i.height);o++){const c=r.apply(l,o),f=Math.sqrt((c.x-t)**2+(c.y-e)**2);Math.abs(f-s)<.58&&this.pixel(l,o,n)}}}fillTri(t,e,s,n,d,a,i,r=w.identity){const l=Math.min(t,s,d),o=Math.max(t,s,d),c=Math.min(e,n,a),f=Math.max(e,n,a);if(r.isIdentity())for(let p=Math.floor(l);p<Math.ceil(o);p++)for(let m=Math.floor(c);m<Math.ceil(f);m++)T(p,m,t,e,s,n,d,a)&&this.pixel(p,m,i);else{const p=r.applyToRect(l,c,o-l,f-c),m=r.inv();for(let y=Math.floor(p.x);y<Math.ceil(p.x+p.width);y++)for(let M=Math.floor(p.y);M<Math.ceil(p.y+p.height);M++){const I=m.apply(y,M);T(I.x,I.y,t,e,s,n,d,a)&&this.pixel(y,M,i)}}}traceTri(t,e,s,n,d,a,i,r=w.identity){if(r.isIdentity())this.line(t,e,s,n,i),this.line(s,n,d,a,i),this.line(d,a,t,e,i);else{const l=r.apply(t,e),o=r.apply(s,n),c=r.apply(d,a);this.line(l.x,l.y,o.x,o.y,i),this.line(o.x,o.y,c.x,c.y,i),this.line(c.x,c.y,l.x,l.y,i)}}}class Ot{constructor(t,e,s=new ImageData(t,e)){u(this,"virtual",!0);u(this,"canvas");u(this,"context");this.width=t,this.height=e,this.image=s,this.canvas=new OffscreenCanvas(t,e),this.context=this.canvas.getContext("2d")}commit(){this.context.putImageData(this.image,0,0)}clear(){for(let t=0;t<this.image.data.length;t+=4)this.image.data[t+0]=0,this.image.data[t+1]=0,this.image.data[t+2]=0,this.image.data[t+3]=255}pixel(t,e,s){if(t<0||t>=this.width||e<0||e>=this.height)return;const[n,d,a,i]=v(s);t|=0,e|=0;const r=(e*this.width+t)*4;if(i===255)this.image.data[r+0]=n,this.image.data[r+1]=d,this.image.data[r+2]=a,this.image.data[r+3]=i;else if(i>0){const l=v(k(g(this.image.data[r+0],this.image.data[r+1],this.image.data[r+2],this.image.data[r+3]),s));this.image.data[r+0]=l[0],this.image.data[r+1]=l[1],this.image.data[r+2]=l[2],this.image.data[r+3]=l[3]}}pixelUnpacked(t,e,s,n,d,a){if(t<0||t>=this.width||e<0||e>=this.height)return;t|=0,e|=0;const i=(e*this.width+t)*4;if(a===255)this.image.data[i+0]=s,this.image.data[i+1]=n,this.image.data[i+2]=d,this.image.data[i+3]=a;else if(a>0){const r=v(k(g(this.image.data[i+0],this.image.data[i+1],this.image.data[i+2],this.image.data[i+3]),g(s,n,d,a)));this.image.data[i+0]=r[0],this.image.data[i+1]=r[1],this.image.data[i+2]=r[2],this.image.data[i+3]=r[3]}}blit(t,e=0,s=0,n=w.identity){if(n.isIdentity()){for(let d=0;d<t.height;d++)if(!(d+s<0||d+s>=this.height))for(let a=0;a<t.width;a++){if(a+e<0||a+e>=this.width)continue;const i=(d*t.width+a)*4;this.pixelUnpacked(a+e,d+s,t.data[i+0],t.data[i+1],t.data[i+2],t.data[i+3])}}else{const d=n.applyToRect(e,s,t.width,t.height),a=n.inv();for(let i=Math.floor(d.y);i<Math.ceil(d.y+d.height);i++)for(let r=Math.floor(d.x);r<Math.ceil(d.x+d.width);r++){const l=a.apply(r,i);if(l.x-=e,l.y-=s,l.x<0||l.x>=t.width||l.y<0||l.y>=t.height)continue;const o=(Math.floor(l.y)*t.width+Math.floor(l.x))*4;this.pixel(r,i,g(t.data[o+0],t.data[o+1],t.data[o+2],t.data[o+3]))}}}blitMask(t,e,s=0,n=0,d=w.identity){if(d.isIdentity()){for(let a=0;a<t.height;a++)if(!(a+n<0||a+n>=this.height))for(let i=0;i<t.width;i++){if(i+s<0||i+s>=this.width)continue;const r=(a*e.width+i)*4;if(r+3>=e.data.length)continue;const l=(a*t.width+i)*4;e.data[r]===255&&e.data[r+1]===255&&e.data[r+2]===255&&e.data[r+3]===255&&this.pixelUnpacked(i+s,a+n,t.data[l+0],t.data[l+1],t.data[l+2],t.data[l+3])}}else{const a=d.applyToRect(s,n,t.width,t.height),i=d.inv();for(let r=Math.floor(a.y);r<Math.ceil(a.y+a.height);r++)for(let l=Math.floor(a.x);l<Math.ceil(a.x+a.width);l++){const o=i.apply(l,r);if(o.x-=s,o.y-=n,o.x<0||o.x>=t.width||o.y<0||o.y>=t.height)continue;const c=(Math.floor(o.y)*e.width+Math.floor(o.x))*4;if(c+3>=e.data.length)continue;const f=(Math.floor(o.y)*t.width+Math.floor(o.x))*4;e.data[c]===255&&e.data[c+1]===255&&e.data[c+2]===255&&e.data[c+3]===255&&this.pixel(l,r,g(t.data[f+0],t.data[f+1],t.data[f+2],t.data[f+3]))}}}line(t,e,s,n,d){if(t-s===0){for(let f=e;f<=n;f++)this.pixel(t,f,d);return}if(e-n===0){for(let f=t;f<=s;f++)this.pixel(f,e,d);return}t>s&&([t,s]=[s,t],[e,n]=[n,e]);const a=(n-e)/(s-t);if(a===1)if(e>n){for(let f=t,p=e;f<=s;f++,p--)this.pixel(f,p,d);return}else{for(let f=t,p=e;f<=s;f++,p++)this.pixel(f,p,d);return}if(a===-1)if(e>n){for(let f=t,p=e;f<=s;f++,p--)this.pixel(f,p,d);return}else{for(let f=t,p=e;f<=s;f++,p++)this.pixel(f,p,d);return}const i=Math.abs(s-t),r=Math.abs(n-e),l=Math.sign(s-t),o=Math.sign(n-e);let c=i-r;for(;;){if(this.pixel(t,e,d),t===s&&e===n)return;const f=2*c;f>-r&&(c-=r,t+=l),f<i&&(c+=i,e+=o)}}fillRect(t,e,s,n,d,a=w.identity){if(a.isIdentity())for(let i=t;i<t+s;i++)for(let r=e;r<e+n;r++)this.pixel(i,r,d);else{const i=a.applyToRect(t,e,s,n),r=a.inv();for(let l=i.x;l<i.x+i.width;l++)for(let o=i.y;o<i.y+i.height;o++){const c=r.apply(l,o);c.x>=t&&c.x<t+s&&c.y>=e&&c.y<e+n&&this.pixel(l,o,d)}}}traceRect(t,e,s,n,d,a=w.identity){if(a.isIdentity())this.line(t,e,t+s,e,d),this.line(t+s,e,t+s,e+n,d),this.line(t,e+n,t+s,e+n,d),this.line(t,e,t,e+n,d);else{const i=a.apply(t,e),r=a.apply(t+s,e),l=a.apply(t,e+n),o=a.apply(t+s,e+n);this.line(i.x,i.y,r.x,r.y,d),this.line(r.x,r.y,o.x,o.y,d),this.line(o.x,o.y,l.x,l.y,d),this.line(l.x,l.y,i.x,i.y,d)}}fillCirc(t,e,s,n,d=w.identity){if(d.isIdentity()){let a=s,i=0,r=1-s;for(;a>=i;)this.line(-a+t,-i+e,-a+t,i+e,n),this.line(-i+t,-a+e,-i+t,a+e,n),this.line(i+t,-a+e,i+t,a+e,n),this.line(a+t,-i+e,a+t,i+e,n),i++,r<0?r+=2*i+1:(a--,r+=2*(i-a+1))}else{const a=s*2+1,i=d.applyToRect(t-a/2,e-a/2,a,a),r=d.inv();for(let l=Math.floor(i.x);l<Math.ceil(i.x+i.width);l++)for(let o=Math.floor(i.y);o<Math.ceil(i.y+i.height);o++){const c=r.apply(l,o);Math.sqrt((c.x-t)**2+(c.y-e)**2)<=a/2&&this.pixel(l,o,n)}}}traceCirc(t,e,s,n,d=w.identity){if(d.isIdentity()){let a=s,i=0,r=1-s;for(;a>=i;)this.pixel(a+t,i+e,n),this.pixel(i+t,a+e,n),this.pixel(-a+t,i+e,n),this.pixel(-i+t,a+e,n),this.pixel(-a+t,-i+e,n),this.pixel(-i+t,-a+e,n),this.pixel(a+t,-i+e,n),this.pixel(i+t,-a+e,n),i++,r<0?r+=2*i+1:(a--,r+=2*(i-a+1))}else{const a=s*2+1,i=d.applyToRect(t-a/2,e-a/2,a,a),r=d.inv();for(let l=Math.floor(i.x);l<Math.ceil(i.x+i.width);l++)for(let o=Math.floor(i.y);o<Math.ceil(i.y+i.height);o++){const c=r.apply(l,o),f=Math.sqrt((c.x-t)**2+(c.y-e)**2);Math.abs(f-s)<.58&&this.pixel(l,o,n)}}}fillTri(t,e,s,n,d,a,i,r=w.identity){const l=Math.min(t,s,d),o=Math.max(t,s,d),c=Math.min(e,n,a),f=Math.max(e,n,a);if(r.isIdentity())for(let p=Math.floor(l);p<Math.ceil(o);p++)for(let m=Math.floor(c);m<Math.ceil(f);m++)T(p,m,t,e,s,n,d,a)&&this.pixel(p,m,i);else{const p=r.applyToRect(l,c,o-l,f-c),m=r.inv();for(let y=Math.floor(p.x);y<Math.ceil(p.x+p.width);y++)for(let M=Math.floor(p.y);M<Math.ceil(p.y+p.height);M++){const I=m.apply(y,M);T(I.x,I.y,t,e,s,n,d,a)&&this.pixel(y,M,i)}}}traceTri(t,e,s,n,d,a,i,r=w.identity){if(r.isIdentity())this.line(t,e,s,n,i),this.line(s,n,d,a,i),this.line(d,a,t,e,i);else{const l=r.apply(t,e),o=r.apply(s,n),c=r.apply(d,a);this.line(l.x,l.y,o.x,o.y,i),this.line(o.x,o.y,c.x,c.y,i),this.line(c.x,c.y,l.x,l.y,i)}}}class O{constructor(t,e=0,s={x:0,y:0,width:t.width,height:t.height}){u(this,"image");this.asset=t,this.frame=e,this.subregion=s,this.update()}static fromArrayBuffer(t){const e=new x.Aseprite(t);return new O(e)}get width(){return this.subregion.width}get height(){return this.subregion.height}update(){this.image=new ImageData(this.subregion.width,this.subregion.height);const t=this.asset.frames[this.frame];if(!t){console.error(`Frame ${this.frame} does not exist.`);return}const e=this.asset.palette[0];for(let s=0;s<this.subregion.width;s++)for(let n=0;n<this.subregion.height;n++)for(let d=t.layers.length-1;d>=0;d--){const a=t.layers[d];let i=!1;for(let r=a.cels.length-1;r>=0;r--){const l=a.cels[r],o=s+this.subregion.x-l.x,c=n+this.subregion.y-l.y;if(c<0||c>=l.height||o<0||o>=l.width)continue;const f=l.pixels[c*l.width+o],p=n*this.subregion.width+s,[m,y,M,I]=v(_(this.asset,f));I===0||this.asset.header.depth!==x.AsepriteColorDepth.Index&&e&&e.red===m&&e.green===y&&e.blue===M||this.asset.header.depth!==x.AsepriteColorDepth.Index&&!e&&m===0&&y===0&&M===0||this.asset.header.depth===x.AsepriteColorDepth.Index&&f===0||(this.image.data[p*4+0]=m,this.image.data[p*4+1]=y,this.image.data[p*4+2]=M,this.image.data[p*4+3]=I,i=!0)}if(i)break}}render(t,e,s,n=w.identity){if(n.isIdentity())for(let d=0;d<this.subregion.width;d++)for(let a=0;a<this.subregion.height;a++){const i=(a*this.subregion.width+d)*4;this.image.data[i+3]!==0&&t.pixelUnpacked(d+e,a+s,this.image.data[i+0],this.image.data[i+1],this.image.data[i+2],this.image.data[i+3])}else{const d=n.applyToRect(e,s,this.subregion.width,this.subregion.height),a=n.inv();for(let i=d.x;i<d.x+d.width;i++)for(let r=d.y;r<d.y+d.height;r++){const l=a.apply(i,r);if(l.x>=e&&l.x<e+this.subregion.width&&l.y>=s&&l.y<s+this.subregion.height){const o=(Math.floor(l.y-s)*this.subregion.width+Math.floor(l.x-e))*4;if(this.image.data[o+3]===0)continue;t.pixelUnpacked(i,r,this.image.data[o+0],this.image.data[o+1],this.image.data[o+2],this.image.data[o+3])}}}}}class $ extends O{constructor(e,s=0,n={x:0,y:0,width:e.width,height:e.height}){super(e,s,n);u(this,"image");u(this,"duration",0);u(this,"start");u(this,"end");u(this,"animation");u(this,"direction",x.AsepriteTagAnimationDirection.Forward);u(this,"repeat",0);u(this,"iterations",0);u(this,"playing",!1);this.asset=e,this.frame=s,this.subregion=n,this.start=0,this.end=e.frames.length-1,this.update()}static fromArrayBuffer(e){const s=new x.Aseprite(e);return new $(s)}get width(){return this.subregion.width}get height(){return this.subregion.height}pause(){this.playing=!1}play(){this.playing=!0}setAnimation(e){if(this.iterations=0,this.duration=0,this.animation=e,e){const s=this.asset.tags.find(n=>n.name===e);s?(s.direction===x.AsepriteTagAnimationDirection.Reverse||s.direction===x.AsepriteTagAnimationDirection.PingPongReverse?this.frame=s.to:this.frame=s.from,this.start=s.from,this.end=s.to,this.direction=s.direction,this.repeat=s.repeat):console.error(`Animation ${e} does not exist.`)}else this.start=0,this.end=this.asset.frames.length-1}update(e=0){for(this.duration+=e;this.duration>=this.asset.frames[this.frame].duration;)if(this.duration-=this.asset.frames[this.frame].duration,!!this.playing){if(this.repeat!==0&&this.iterations>=this.repeat){this.playing=!1;continue}switch(this.direction){case x.AsepriteTagAnimationDirection.Forward:this.frame++,this.frame>this.end&&(this.iterations++,this.frame=this.start);break;case x.AsepriteTagAnimationDirection.Reverse:this.frame--,this.frame<this.start&&(this.iterations++,this.frame=this.end);break;case x.AsepriteTagAnimationDirection.PingPong:this.iterations%2===0?(this.frame++,this.frame>this.end&&(this.iterations++,this.frame=this.end)):(this.frame--,this.frame<this.start&&(this.iterations++,this.frame=this.start));break;case x.AsepriteTagAnimationDirection.PingPongReverse:this.iterations%2!==0?(this.frame++,this.frame>this.end&&(this.iterations++,this.frame=this.end)):(this.frame--,this.frame<this.start&&(this.iterations++,this.frame=this.start));break}}super.update()}}class L{constructor(t){u(this,"rows");u(this,"cols");u(this,"sprites",[]);this.asset=t;const e=this.asset.width-this.asset.header.grid.x,s=this.asset.height-this.asset.header.grid.y;this.rows=Math.floor(s/this.asset.header.grid.height),this.cols=Math.floor(e/this.asset.header.grid.width),this.init()}static fromArrayBuffer(t){const e=new x.Aseprite(t);return new L(e)}init(){for(let t=0;t<this.rows;t++)for(let e=0;e<this.cols;e++){const s={x:e*this.asset.header.grid.width,y:t*this.asset.header.grid.height,width:this.asset.header.grid.width,height:this.asset.header.grid.height};this.sprites.push(new O(this.asset,0,s))}}update(){for(const t of this.sprites)t.update()}}class D{constructor(t){u(this,"rows");u(this,"cols");u(this,"sprites",[]);this.asset=t;const e=this.asset.width-this.asset.header.grid.x,s=this.asset.height-this.asset.header.grid.y;this.rows=Math.floor(s/this.asset.header.grid.height),this.cols=Math.floor(e/this.asset.header.grid.width),this.init()}static fromArrayBuffer(t){const e=new x.Aseprite(t);return new D(e)}init(){for(let t=0;t<this.rows;t++)for(let e=0;e<this.cols;e++){const s={x:e*this.asset.header.grid.width,y:t*this.asset.header.grid.height,width:this.asset.header.grid.width,height:this.asset.header.grid.height};this.sprites.push(new $(this.asset,0,s))}}update(t=0){for(const e of this.sprites)e.update(t)}}const Et=(h,t,e=0,s=0)=>{for(let n=0;n<h.height;n++)if(!(n+s<0||n+s>=t.height))for(let d=0;d<h.width;d++){if(d+e<0||d+e>=t.width)continue;const a=(n*h.width+d)*4,i=((n+s)*t.width+(d+e))*4;t.data[i+0]=h.data[a+0],t.data[i+1]=h.data[a+1],t.data[i+2]=h.data[a+2],t.data[i+3]=h.data[a+3]}},Rt=(h,t,e,s=0,n=0)=>{for(let d=0;d<h.height;d++)if(!(d+n<0||d+n>=t.height))for(let a=0;a<h.width;a++){if(a+s<0||a+s>=t.width)continue;const i=((d+n)*e.width+(a+s))*4;if(i+3>=e.data.length)continue;const r=(d*h.width+a)*4,l=((d+n)*t.width+(a+s))*4;e.data[i]===255&&e.data[i+1]===255&&e.data[i+2]===255&&e.data[i+3]===255&&(t.data[l+0]=h.data[r+0],t.data[l+1]=h.data[r+1],t.data[l+2]=h.data[r+2],t.data[l+3]=h.data[r+3])}},$t=Object.freeze(Object.defineProperty({__proto__:null,AnimatedSprite:$,AnimatedSpriteSheet:D,Screen:Tt,Sprite:O,SpriteSheet:L,VirtualScreen:Ot,blit:Et,blitMask:Rt},Symbol.toStringTag,{value:"Module"}));class F{constructor(t,e){u(this,"x",0);u(this,"y",0);u(this,"visible",!1);u(this,"primary",!1);u(this,"secondary",!1);u(this,"middle",!1);this.root=t,this.surface=e,t.addEventListener("mouseenter",()=>{this.visible=!0}),t.addEventListener("mouseleave",()=>{this.visible=!1}),t.addEventListener("mousemove",s=>{const n=t.getBoundingClientRect(),d=s.clientX-n.left,a=s.clientY-n.top;this.x=Math.floor(d/n.width*this.surface.width),this.y=Math.floor(a/n.height*this.surface.height)}),t.addEventListener("mousedown",s=>{switch(s.button){case 0:this.primary=!0;break;case 1:this.middle=!0;break;case 2:this.secondary=!0;break}}),t.addEventListener("mouseup",s=>{switch(s.button){case 0:this.primary=!1;break;case 1:this.middle=!1;break;case 2:this.secondary=!1;break}}),t.addEventListener("contextmenu",s=>{s.preventDefault()})}update(){}}class G{constructor(t){u(this,"keys",{"`":{held:!1,pressed:!1},1:{held:!1,pressed:!1},2:{held:!1,pressed:!1},3:{held:!1,pressed:!1},4:{held:!1,pressed:!1},5:{held:!1,pressed:!1},6:{held:!1,pressed:!1},7:{held:!1,pressed:!1},8:{held:!1,pressed:!1},9:{held:!1,pressed:!1},0:{held:!1,pressed:!1},"-":{held:!1,pressed:!1},"=":{held:!1,pressed:!1},Backspace:{held:!1,pressed:!1},Tab:{held:!1,pressed:!1},q:{held:!1,pressed:!1},w:{held:!1,pressed:!1},e:{held:!1,pressed:!1},r:{held:!1,pressed:!1},t:{held:!1,pressed:!1},y:{held:!1,pressed:!1},u:{held:!1,pressed:!1},i:{held:!1,pressed:!1},o:{held:!1,pressed:!1},p:{held:!1,pressed:!1},"[":{held:!1,pressed:!1},"]":{held:!1,pressed:!1},"\\":{held:!1,pressed:!1},CapsLock:{held:!1,pressed:!1},a:{held:!1,pressed:!1},s:{held:!1,pressed:!1},d:{held:!1,pressed:!1},f:{held:!1,pressed:!1},g:{held:!1,pressed:!1},h:{held:!1,pressed:!1},j:{held:!1,pressed:!1},k:{held:!1,pressed:!1},l:{held:!1,pressed:!1},";":{held:!1,pressed:!1},"'":{held:!1,pressed:!1},Enter:{held:!1,pressed:!1},ShiftLeft:{held:!1,pressed:!1},z:{held:!1,pressed:!1},x:{held:!1,pressed:!1},c:{held:!1,pressed:!1},v:{held:!1,pressed:!1},b:{held:!1,pressed:!1},n:{held:!1,pressed:!1},m:{held:!1,pressed:!1},",":{held:!1,pressed:!1},".":{held:!1,pressed:!1},"/":{held:!1,pressed:!1},ShiftRight:{held:!1,pressed:!1},ControlLeft:{held:!1,pressed:!1},MetaLeft:{held:!1,pressed:!1},AltLeft:{held:!1,pressed:!1},Space:{held:!1,pressed:!1},AltRight:{held:!1,pressed:!1},MetaRight:{held:!1,pressed:!1},ContextMenu:{held:!1,pressed:!1},ControlRight:{held:!1,pressed:!1},ArrowLeft:{held:!1,pressed:!1},ArrowUp:{held:!1,pressed:!1},ArrowRight:{held:!1,pressed:!1},ArrowDown:{held:!1,pressed:!1}});this.root=t,t.addEventListener("keydown",e=>{switch(e.preventDefault(),e.key){case"Shift":case"Control":case"Meta":case"Alt":e.location===KeyboardEvent.DOM_KEY_LOCATION_RIGHT?this.keys[`${e.key}Right`].held=!0:this.keys[`${e.key}Left`].held=!0;break;case" ":this.keys.Space.held=!0;break;default:this.keys.hasOwnProperty(e.key)&&(this.keys[e.key].held=!0);break}}),t.addEventListener("keyup",e=>{switch(e.preventDefault(),e.key){case"Shift":case"Control":case"Meta":case"Alt":e.location===KeyboardEvent.DOM_KEY_LOCATION_RIGHT?(this.keys[`${e.key}Right`].held=!1,this.keys[`${e.key}Right`].pressed=!0):(this.keys[`${e.key}Left`].held=!1,this.keys[`${e.key}Left`].pressed=!0);break;case" ":this.keys.Space.held=!1,this.keys.Space.pressed=!0;break;default:this.keys.hasOwnProperty(e.key)&&(this.keys[e.key].held=!1,this.keys[e.key].pressed=!0);break}})}update(){for(const t in this.keys)this.keys[t].pressed=!1}held(t){return this.keys[t].held}pressed(t){return this.keys[t].pressed}}class A{constructor(t){u(this,"connected",!1);u(this,"device",null);u(this,"buttons",[]);this.root=t}update(){var t;for(let e=0;e<this.buttons.length;e++){const s=(t=this.device)==null?void 0:t.buttons[e],n=this.buttons[e];s&&(n.pressed&&(n.pressed=!1),n.held&&!s.pressed&&(n.pressed=!0),n.held=s.pressed)}}connect(t){this.connected=!0,this.device=t.gamepad,this.buttons=this.device.buttons.map(()=>({held:!1,pressed:!1}))}disconnect(){this.connected=!1}held(t){var e;return((e=this.device)==null?void 0:e.buttons[t].pressed)??!1}pressed(t){var e;return((e=this.buttons[t])==null?void 0:e.pressed)??!1}analog(t){var e;return((e=this.device)==null?void 0:e.buttons[t].value)??0}axis(t){var e;return((e=this.device)==null?void 0:e.axes[t])??0}}class H{constructor(t){u(this,"root");u(this,"mouse");u(this,"keyboard");u(this,"gamepads");this.surface=t,t.virtual?this.root=document.createElement("div"):this.root=t.canvas,this.mouse=new F(this.root,this.surface),this.keyboard=new G(this.root),this.gamepads=[new A(this.root),new A(this.root),new A(this.root),new A(this.root)],window.addEventListener("gamepadconnected",e=>{if(e.gamepad.index>=4)return;this.gamepads[e.gamepad.index].connect(e)}),window.addEventListener("gamepaddisconnected",e=>{if(e.gamepad.index>=4)return;this.gamepads[e.gamepad.index].disconnect()})}update(){this.mouse.update(),this.keyboard.update();for(const t of this.gamepads)t.update()}}const Ct=Object.freeze(Object.defineProperty({__proto__:null,GamepadInput:A,Inputs:H,KeyboardInput:G,MouseInput:F},Symbol.toStringTag,{value:"Module"})),Lt=({surface:h,setup:t=E,update:e=E,render:s=E})=>{let n=0,d=0,a=0,i=0;const r=new H(h),l=new j;let o=document.visibilityState==="visible";window.addEventListener("visibilitychange",()=>{o=document.visibilityState==="visible",o||(d=0,a=0,i=0)});const c=f=>{if(!o){requestAnimationFrame(c);return}const p=f-n;n=f,i+=p,i>=1e3&&(d=a,a=0,i=0),l.update(),e(h,r,l,p,n),r.update(),s(h,r,p,n,d),h.commit(),a++,requestAnimationFrame(c)};t(h,r,l),requestAnimationFrame(c)},Dt=Object.freeze(Object.defineProperty({__proto__:null,run:Lt},Symbol.toStringTag,{value:"Module"}));exports.audio=K;exports.colors=V;exports.easing=At;exports.geometry=kt;exports.graphics=$t;exports.input=Ct;exports.lifecycle=Dt;exports.util=Y;