ecspresso
Version:
A minimal Entity-Component-System library for typescript and javascript.
5 lines (3 loc) • 6.38 kB
JavaScript
var S=((z)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(z,{get:(J,L)=>(typeof require<"u"?require:J)[L]}):z)(function(z){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+z+'" is not supported')});import{definePlugin as A}from"ecspresso";function G(z){return Object.freeze({frames:Object.freeze([...z.frames]),frameDuration:z.frameDuration??0.1,frameDurations:z.frameDurations?Object.freeze([...z.frameDurations]):null,loop:z.loop??"loop"})}function v(z,J){return Object.freeze({id:z,clips:Object.freeze({default:G(J)}),defaultClip:"default"})}function f(z,J,L){let O={},M=Object.keys(J);for(let Y of M)O[Y]=G(J[Y]);let Q=M[0];if(!Q)throw Error("defineSpriteAnimations: clips object must have at least one key");return Object.freeze({id:z,clips:Object.freeze(O),defaultClip:L?.defaultClip??Q})}function x(z,J){let L=J?.initial??z.defaultClip;return{spriteAnimation:{set:z,current:L,currentFrame:0,elapsed:0,playing:!0,speed:J?.speed??1,direction:1,totalLoops:J?.totalLoops??-1,completedLoops:0,justFinished:!1,onComplete:J?.onComplete}}}function g(z,J,L,O){let M=z.getComponent(J,"spriteAnimation");if(!M)return!1;if(!(L in M.set.clips))return!1;if(L!==M.current||O?.restart===!0)M.current=L,M.currentFrame=0,M.elapsed=0,M.direction=1,M.completedLoops=0,M.justFinished=!1;if(M.playing=!0,O?.speed!==void 0)M.speed=O.speed;return z.markChanged(J,"spriteAnimation"),!0}function F(z,J){let L=z.getComponent(J,"spriteAnimation");if(!L)return!1;return L.playing=!1,!0}function I(z,J){let L=z.getComponent(J,"spriteAnimation");if(!L)return!1;return L.playing=!0,!0}function j(z,J,L){z.playing=!1,z.justFinished=!0,z.onComplete?.({entityId:J,animation:z.current}),L.commands.removeComponent(J,"spriteAnimation")}function N(z,J,L,O){if(z.completedLoops++,J.loop==="once")return j(z,L,O),!1;if(z.totalLoops>0&&z.completedLoops>=z.totalLoops)return j(z,L,O),!1;if(J.loop==="pingPong")return z.direction=z.direction===1?-1:1,z.currentFrame+=z.direction,z.elapsed>0;return z.currentFrame=0,z.elapsed>0}function q(z,J,L,O){let M=z.currentFrame+z.direction;if(M>=J.frames.length||M<0)return N(z,J,L,O);return z.currentFrame=M,!0}function T(z,J,L,O){while(!0){let M=J.frameDurations!==null?J.frameDurations[z.currentFrame]??J.frameDuration:J.frameDuration;if(M<=0){if(!q(z,J,L,O))return;continue}let Q=M-z.elapsed;if(Q>0.000001)return;if(z.elapsed=Q<0?-Q:0,!q(z,J,L,O))return}}function h(z){let{systemGroup:J="spriteAnimation",priority:L=0,phase:O="update"}=z??{};return A("spriteAnimation").withComponentTypes().withLabels().withGroups().install((M)=>{M.addSystem("sprite-animation-update").setPriority(L).inPhase(O).inGroup(J).addQuery("animations",{with:["spriteAnimation"]}).setProcess(({queries:Q,dt:Y,ecs:V})=>{for(let X of Q.animations){let U=X.components.spriteAnimation,Z=U.set.clips[U.current];if(!Z)continue;if(U.justFinished){U.justFinished=!1;continue}if(!U.playing)continue;if(Z.frames.length<=1)continue;let $=U.currentFrame;if(U.elapsed+=Y*U.speed,T(U,Z,X.id,V),U.currentFrame!==$||$===0)b(X.components,U,Z);if(U.currentFrame!==$)V.markChanged(X.id,"spriteAnimation")}})})}function b(z,J,L){let O=z.sprite;if(O&&typeof O==="object"&&"texture"in O)O.texture=L.frames[J.currentFrame]}function y(z,J,L){let O=z.animations[J];if(!O||O.length===0){let M=Object.keys(z.animations).join(", ")||"(none)";throw Error(`clipFromSheet: animation "${J}" not found on sheet (or has no frames). Available: ${M}`)}return G({...L,frames:O})}function u(z,J,L){let O=Object.entries(J.animations),M=O[0];if(!M)throw Error(`animationSetFromSheet: sheet "${z}" has no animations defined`);let Q=O.reduce((Y,[V,X])=>{if(!Array.isArray(X)||X.length===0)throw Error(`animationSetFromSheet: animation "${String(V)}" on sheet "${z}" has no frames (got ${X===null?"null":Array.isArray(X)?"empty array":typeof X})`);let U=L?.perClip?.[V];return Y[V]=G({frames:X,frameDuration:U?.frameDuration??L?.frameDuration,frameDurations:U?.frameDurations,loop:U?.loop??L?.loop}),Y},{});return Object.freeze({id:z,clips:Object.freeze(Q),defaultClip:L?.defaultClip??M[0]})}async function d(z){let{source:J,frameWidth:L,frameHeight:O,columns:M,rows:Q,indices:Y,count:V,spacing:X=0,margin:U=0}=z;if(!J)throw Error("clipFromGrid: source is required");if(!Number.isInteger(M)||M<=0)throw Error(`clipFromGrid: columns must be a positive integer, got ${M}`);if(Q!==void 0&&(!Number.isInteger(Q)||Q<=0))throw Error(`clipFromGrid: rows must be a positive integer, got ${Q}`);if(V!==void 0&&(!Number.isInteger(V)||V<0))throw Error(`clipFromGrid: count must be a non-negative integer, got ${V}`);if(Y!==void 0&&V!==void 0)throw Error("clipFromGrid: pass either 'indices' or 'count', not both");if(Y===void 0&&V===void 0&&Q===void 0)throw Error("clipFromGrid: specify 'rows', 'count', or 'indices' to define the cell set (only 'columns' is ambiguous)");let Z=Q!==void 0?M*Q:void 0,$=Y??Array.from({length:Z!==void 0&&V!==void 0?Math.min(V,Z):V??Z??0},(_,P)=>P);if($.length===0)throw Error("clipFromGrid: resolved to zero cells (empty indices array or count: 0)");let B=Z??1/0,R=$.find((_)=>!Number.isInteger(_)||_<0||_>=B);if(R!==void 0){let _=Z!==void 0?`[0, ${Z})`:"[0, ∞) — pass 'rows' to enable upper-bound checking";throw Error(`clipFromGrid: invalid cell index ${R}; expected integer in ${_}`)}let{Texture:D,Rectangle:E}=await import("pixi.js"),H=$.map((_)=>{let P=_%M,K=Math.floor(_/M),W=U+P*(L+X),k=U+K*(O+X);return new D({source:J,frame:new E(W,k,L,O)})});return G({frames:H,frameDuration:z.frameDuration,frameDurations:z.frameDurations,loop:z.loop})}function l(z){return async()=>{let{Assets:J}=await import("pixi.js"),L=await J.load(z);if(!L||typeof L!=="object"||typeof L.animations!=="object"||L.animations===null||typeof L.textures!=="object"||L.textures===null)throw Error(`spritesheetLoader: resource at "${z}" did not resolve to a Spritesheet (expected non-null 'animations' and 'textures' objects). Check that the URL points to a TexturePacker-style JSON atlas, not a raw image.`);return L}}export{F as stopAnimation,l as spritesheetLoader,I as resumeAnimation,g as playAnimation,f as defineSpriteAnimations,v as defineSpriteAnimation,h as createSpriteAnimationPlugin,x as createSpriteAnimation,y as clipFromSheet,d as clipFromGrid,u as animationSetFromSheet};
//# debugId=288D71B236D04EC264756E2164756E21
//# sourceMappingURL=sprite-animation.js.map