@combos-fun/engine 0.0.38 → 0.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engine.cjs.js +231 -3
- package/dist/engine.cjs.js.map +1 -1
- package/dist/engine.cjs.prod.js +1 -1
- package/dist/engine.d.ts +78 -4
- package/dist/engine.esm.js +230 -4
- package/dist/engine.esm.js.map +1 -1
- package/package.json +7 -3
- package/references/bootstrap-examples.md +59 -32
- package/references/public-api.md +2 -2
package/dist/engine.cjs.prod.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("eventemitter3"),t=require("lodash-es"),s=require("tslib"),r=require("@combos-fun/inspector-decorator"),o=require("resource-loader");function n(e){return e&&e.__esModule?e:{default:e}}var a,i=n(e);class c extends i.default{get game(){return this.gameObject?.scene?.game}constructor(e){super(),this.started=!1;const t=this.constructor;this.name=t.componentName,this.__componentDefaultParams=e}}exports.OBSERVER_TYPE=void 0,(a=exports.OBSERVER_TYPE||(exports.OBSERVER_TYPE={})).ADD="ADD",a.REMOVE="REMOVE",a.CHANGE="CHANGE";const p={},h={},m={},d={};function l(e,t){p[e.gameObject.id]||(p[e.gameObject.id]={});const s=p[e.gameObject.id],r=e.name+"_"+t.join(",");if(s[r])return s[r];const o=t.length-1;let n=e;for(let e=0;e<o;e++){if(void 0===n[t[e]]||null===n[t[e]])return{property:void 0,key:void 0};n=n[t[e]]}return s[r]={property:n,key:t[o]},s[r]}function u({systemName:e,componentName:t,component:s,prop:r,type:o}){h[e]?.componentObserver?.add({component:s,prop:r,type:o,componentName:t})}function y({obj:e,key:s,prop:r,component:o,componentName:n}){if(void 0!==e)if(s in e){if(Object.defineProperty(e,`_${s}`,{enumerable:!1,writable:!0,value:e[s]}),r.deep&&t.isObject(e[s]))for(const t of Object.keys(e[s]))y({obj:e[s],key:t,prop:r,component:o,componentName:n});Object.defineProperty(e,s,{enumerable:!0,set(a){e[`_${s}`]!==a&&(e[`_${s}`]=a,function({prop:e,component:s,componentName:r}){for(const o in m){const n=(m[o]||{})[r];n&&(n.findIndex(s=>t.isEqual(s,e))>-1&&u({systemName:o,componentName:r,component:s,prop:e,type:exports.OBSERVER_TYPE.CHANGE}))}}({prop:r,component:o,componentName:n}))},get:()=>e[`_${s}`]})}else console.error(`prop ${s} not in component: ${n}, Can not observer`)}function f(e,t=e.name){for(const s in m){(m[s]||{})[t]&&h[s]?.componentObserver?.add({component:e,type:exports.OBSERVER_TYPE.REMOVE,componentName:t})}!function(e){e.gameObject&&delete p[e.gameObject.id]}(e)}class g extends c{constructor(){super(...arguments),this.name="Transform",this._parent=null,this.inScene=!1,this.children=[],this.position={x:0,y:0},this.size={width:0,height:0},this.origin={x:0,y:0},this.anchor={x:0,y:0},this.scale={x:1,y:1},this.skew={x:0,y:0},this.rotation=0}static{this.componentName="Transform"}init(e={}){const t=["position","size","origin","anchor","scale","skew"];for(const s of t)Object.assign(this[s],e[s]);this.rotation=e.rotation??this.rotation}set parent(e){e?e.addChild(this):this.parent&&this.parent.removeChild(this)}get parent(){return this._parent}addChild(e){if(e.parent===this){const t=this.children.findIndex(t=>t===e);this.children.splice(t,1)}else e.parent&&e.parent.removeChild(e);e._parent=this,this.children.push(e)}removeChild(e){const t=this.children.findIndex(t=>t===e);t>-1&&(this.children.splice(t,1),e._parent=null)}clearChildren(){this.children.length=0}}s.__decorate([r.Field({type:"vector2",step:1,group:"Transform",label:"Position",description:"Position on the design canvas (x right, y down)."})],g.prototype,"position",void 0),s.__decorate([r.Field({type:"size",step:1,min:0,group:"Transform",label:"Size",description:"Width and height of the object in design pixels."})],g.prototype,"size",void 0),s.__decorate([r.Field({type:"vector2",step:.1,group:"Transform",label:"Origin",description:"Local origin used for layout math."})],g.prototype,"origin",void 0),s.__decorate([r.Field({type:"vector2",step:.1,group:"Transform",label:"Anchor",description:"Anchor point (0–1) used when positioning and scaling."})],g.prototype,"anchor",void 0),s.__decorate([r.Field({type:"vector2",step:.1,group:"Transform",label:"Scale",description:"Scale multipliers on X and Y (1 = original size)."})],g.prototype,"scale",void 0),s.__decorate([r.Field({type:"vector2",step:.1,group:"Transform",label:"Skew",description:"Skew amounts on X and Y."})],g.prototype,"skew",void 0),s.__decorate([r.Field({type:"number",step:.1,group:"Transform",label:"Rotation",description:"Rotation in radians.",editor:"number-stepper"})],g.prototype,"rotation",void 0);let E=0;class _{constructor(e,t){this._componentCache={},this.components=[],this.destroyed=!1,this._name=e,this.id=++E,this.addComponent(g,t)}get transform(){return this.getComponent(g)}get parent(){return this.transform&&this.transform.parent&&this.transform.parent.gameObject}get name(){return this._name}set scene(e){if(this._scene===e)return;const t=this._scene;if(this._scene=e,this.transform&&this.transform.children)for(const t of this.transform.children)t.gameObject.scene=e;e?e.addGameObject(this):t&&t.removeGameObject(this)}get scene(){return this._scene}addChild(e){if(e&&e.transform&&e!==this){if(!(e instanceof _))throw new Error("addChild only receive GameObject");if(!this.transform)throw new Error(`gameObject '${this.name}' has been destroy`);e.transform.parent=this.transform,e.scene=this.scene}}removeChild(e){return e instanceof _&&e.parent&&e.parent===this?(e.transform.parent=null,e.scene=null,e):e}addComponent(e,t){if(this.destroyed)return;const s=function(e){return e instanceof c?e.name:e instanceof Function?e.componentName:void 0}(e);if(this._componentCache[s])return;let r;if(e instanceof Function)r=new e(t);else{if(!(e instanceof c))throw new Error("addComponent recieve Component and Component Constructor");r=e}if(r.gameObject)throw new Error(`component has been added on gameObject ${r.gameObject.name}`);return r.gameObject=this,r.init&&r.init(r.__componentDefaultParams),function(e,t=e.name){for(const s in m)(m[s]||{})[t]&&h[s]?.componentObserver?.add({component:e,type:exports.OBSERVER_TYPE.ADD,componentName:t})}(r,r.name),function(e,t=e.name){if(t&&d[t]){if(!(e&&(s=e,s&&s.constructor&&"componentName"in s.constructor)))throw new Error("component param must be an instance of Component");var s;if(!e.gameObject||!e.gameObject.id)throw new Error("component should be add to a gameObject");for(const s of d[t]){const{property:r,key:o}=l(e,s.prop);y({obj:r,key:o,prop:s,component:e,componentName:t})}}}(r,r.name),this.components.push(r),this._componentCache[s]=r,r.awake&&r.awake(),r}removeComponent(e){let t;if("string"==typeof e?t=e:e instanceof c?t=e.name:e.componentName&&(t=e.componentName),"Transform"===t)throw new Error("Transform can't be removed");return this._removeComponent(t)}_removeComponent(e){const t=this.components.findIndex(({name:t})=>t===e);if(-1===t)return;const s=this.components.splice(t,1)[0];return delete this._componentCache[e],delete s.__componentDefaultParams,s.onDestroy&&s.onDestroy(),f(s,e),s.gameObject=void 0,s}getComponent(e){let t;return"string"==typeof e?t=e:e instanceof c?t=e.name:e.componentName&&(t=e.componentName),void 0!==this._componentCache[t]?this._componentCache[t]:void 0}remove(){if(this.parent)return this.parent.removeChild(this)}destroy(){if(this.transform){Array.from(this.transform.children).forEach(({gameObject:e})=>{e.destroy()}),this.remove(),this.transform.clearChildren();for(const e in this._componentCache)this._removeComponent(e);this.components.length=0,this.destroyed=!0}else console.error("Cannot destroy gameObject that have already been destroyed.")}}class b{constructor(){this.events=[]}add({component:e,prop:s,type:r,componentName:o}){if(r===exports.OBSERVER_TYPE.REMOVE){if(this.events.find(t=>t.component===e&&t.type===exports.OBSERVER_TYPE.ADD))return void(this.events=this.events.filter(t=>t.component!==e));this.events=this.events.filter(t=>t.component!==e)}const n=this.events.findIndex(o=>o.component===e&&t.isEqual(o.prop,s)&&o.type===r);n>-1&&this.events.splice(n,1),this.events.push({gameObject:e.gameObject,component:e,prop:s,type:r,componentName:o})}getChanged(){return this.events}get changed(){return this.events}clear(){const e=this.events;return this.events=[],e}}class T{constructor(e){this.started=!1,this.componentObserver=new b,this.__systemDefaultParams=e;const t=this.constructor;this.name=t.systemName}destroy(){this.componentObserver=null,this.__systemDefaultParams=null,this.onDestroy?.()}}const S=function(){let e=null;return e=Date.now?Date.now:()=>(new Date).getTime(),e}(),O={originTime:0,playbackRate:1};class R{constructor(e,t){e instanceof R&&(t=e,e={}),e=Object.assign({},O,e),t&&(this._parent=t),this._createTime=S(),this._timeMark=[{globalTime:this.globalTime,localTime:-e.originTime,entropy:-e.originTime,playbackRate:e.playbackRate,globalEntropy:0}],this._parent&&(this._timeMark[0].globalEntropy=this._parent.entropy),this._playbackRate=e.playbackRate}get globalTime(){return this.parent?this.parent.currentTime:S()-this._createTime}get parent(){return this._parent}get lastTimeMark(){return this._timeMark[this._timeMark.length-1]}markTime({time:e=this.currentTime,entropy:t=this.entropy,playbackRate:s=this.playbackRate}={}){const r={globalTime:this.globalTime,localTime:e,entropy:t,playbackRate:s,globalEntropy:this.globalEntropy};this._timeMark.push(r)}get currentTime(){const{localTime:e,globalTime:t}=this.lastTimeMark;return e+(this.globalTime-t)*this.playbackRate}set currentTime(e){this.markTime({time:e})}get globalEntropy(){return this._parent?this._parent.entropy:this.globalTime}get entropy(){const{entropy:e,globalEntropy:t}=this.lastTimeMark;return e+Math.abs((this.globalEntropy-t)*this.playbackRate)}set entropy(e){if(this.entropy>e){const t=this.seekTimeMark(e);this._timeMark.length=t+1}this.markTime({entropy:e})}fork(e){return new R(e,this)}seekGlobalTime(e){const t=this.seekTimeMark(e),s=this._timeMark[t],{entropy:r,playbackRate:o,globalTime:n}=s;return n+(e-r)/Math.abs(o)}seekLocalTime(e){const t=this.seekTimeMark(e),s=this._timeMark[t],{localTime:r,entropy:o,playbackRate:n}=s;return n>0?r+(e-o):r-(e-o)}seekTimeMark(e){const t=this._timeMark;let s=0,r=t.length-1;if(e<=t[s].entropy)return s;if(e>=t[r].entropy)return r;let o=Math.floor((s+r)/2);for(;o>s&&o<r;){if(e===t[o].entropy)return o;e<t[o].entropy?r=o:e>t[o].entropy&&(s=o),o=Math.floor((s+r)/2)}return s}get playbackRate(){return this._playbackRate}set playbackRate(e){e!==this.playbackRate&&(this.markTime({playbackRate:e}),this._playbackRate=e)}get paused(){if(0===this.playbackRate)return!0;let e=this.parent;for(;e;){if(0===e.playbackRate)return!0;e=e.parent}return!1}}const k={autoStart:!0,frameRate:60};class v{constructor(e){e=Object.assign({},k,e),this._frameCount=0,this._frameDuration=1e3/e.frameRate,this.autoStart=e.autoStart,this.frameRate=e.frameRate,this.timeline=new R({originTime:0,playbackRate:1}),this._lastFrameTime=this.timeline.currentTime,this._tickers=new Set,this._requestId=null,this._ticker=()=>{this._started&&(this._requestId=requestAnimationFrame(this._ticker),this.update())},this.autoStart&&this.start()}update(){const e=this.timeline.currentTime,t=e-this._lastFrameTime;if(t>=this._frameDuration){const s=e-t%this._frameDuration,r=s-this._lastFrameTime;this._lastFrameTime=s;const o={deltaTime:r,delta:r,time:s,currentTime:s,frameCount:++this._frameCount,fps:Math.round(1e3/r)};for(const e of this._tickers)"function"==typeof e&&e(o)}}add(e){this._tickers.add(e)}remove(e){this._tickers.delete(e)}start(){this._started||(this._started=!0,this.timeline.playbackRate=1,this._requestId=requestAnimationFrame(this._ticker))}pause(){this._started=!1,this.timeline.playbackRate=0}setPlaybackRate(e){this.timeline.playbackRate=e}}class w extends _{constructor(e,t){super(e,t),this.gameObjects=[],this.scene=this}addGameObject(e){this.gameObjects.push(e),e.transform&&(e.transform.inScene=!0)}removeGameObject(e){const t=this.gameObjects.indexOf(e);-1!==t&&(e.transform&&(e.transform.inScene=!1),this.gameObjects.splice(t,1))}destroy(){this.scene=null,super.destroy(),this.gameObjects=null,this.canvas=null}}const L="0.0.38",M="combos-game:plugin-init-success",x="combos-game:ready",C="combos-game:set-playing",N="combos-game:state-changed";function A(e,t){if("undefined"!=typeof window&&window.parent&&window.parent!==window)try{window.parent.postMessage(e,t)}catch{}}function P(e,t="*"){A({type:M,systemName:e.systemName,engineVersion:L,...e.packageName?{packageName:e.packageName}:{},...e.packageVersion?{packageVersion:e.packageVersion}:{}},t)}function I(e,t="*"){A({type:x,engineVersion:L,...void 0===e?{}:{error:e instanceof Error?e.message:String(e)}},t)}function D(e,t="*"){A({type:N,playing:e.playing,started:e.started},t)}function j(e){if(!e||"object"!=typeof e)return null;const t=e;return t.type!==C||"boolean"!=typeof t.playing?null:t.playing}const X=["knoffice.tech","converge.ai"];function V(e,t){if(t.includes("*"))return!0;if(0===t.length)return!1;let s;try{s=new URL(e)}catch{return!1}const r=e.toLowerCase(),o=s.hostname.toLowerCase();for(const e of t){const t=e.trim();if(!t)continue;if(t.includes("://")){if(r===t.toLowerCase())return!0;continue}const s=t.toLowerCase().replace(/^\./,"");if(o===s||o.endsWith(`.${s}`))return!0}return!1}function G(e){if(!e?.length)return[...X];if(e.includes("*"))return["*"];const t=new Set,s=[];for(const r of[...X,...e]){const e=r.trim();e&&!t.has(e)&&(t.add(e),s.push(e))}return s}function $(e){if("systemName"in e){const t=e.systemName;if("string"==typeof t)return t}return"UnknownSystem"}function F(e){const t=e;return{packageName:"string"==typeof t.packageName?t.packageName:void 0,packageVersion:"string"==typeof t.packageVersion?t.packageVersion:void 0}}var U;exports.LOAD_SCENE_MODE=void 0,(U=exports.LOAD_SCENE_MODE||(exports.LOAD_SCENE_MODE={})).SINGLE="SINGLE",U.MULTI_CANVAS="MULTI_CANVAS";const B=e=>{if((e instanceof T||e instanceof c)&&!e.started){e.started=!0;try{e.start&&e.start()}catch(t){e instanceof c?console.error(`${function(e){if("componentName"in e){const t=e.componentName;if("string"==typeof t)return t}return"UnknownComponent"}(e.constructor)} start error`,t):console.error(`${$(e.constructor)} start error`,t)}}};class Y extends i.default{constructor({systems:e,frameRate:t=60,autoStart:s=!0,needScene:r=!0,onSystemsBootstrapComplete:o,pluginInitNotifyTargetOrigin:n="*",allowedMessageOrigins:a}={}){if(super(),this.playing=!1,this.started=!1,this.multiScenes=[],this.systems=[],this.pluginInitNotifyTargetOrigin="*",this.allowedMessageOrigins=G(),this.onHostMessage=e=>{if(!V(e.origin,this.allowedMessageOrigins))return;const t=j(e.data);null!==t&&this.setPlaying(t)},this.pluginInitNotifyTargetOrigin=n,this.allowedMessageOrigins=G(a),this.ticker=new v({autoStart:!1,frameRate:t}),this.initTicker(),"undefined"!=typeof window&&window.addEventListener("message",this.onHostMessage),e&&e.length){const t=[...e];this.bootstrapSystemsAndMaybeStart(t,r,s,o)}else o?.(this),this.notifyReady()}setPlaying(e){e?this.started?this.resume():this.start():this.pause()}notifyReady(e){I(e,this.pluginInitNotifyTargetOrigin)}notifyStateChanged(){D({playing:this.playing,started:this.started},this.pluginInitNotifyTargetOrigin)}async bootstrapSystemsAndMaybeStart(e,t,s,r){let o;try{for(const t of e)await this.addSystem(t);t&&this.loadScene({scene:new w("scene")}),s&&this.start()}catch(e){o=e,console.error("Game bootstrap failed",e)}finally{r?.(this,o),this.notifyReady(o)}}get scene(){return this._scene}set scene(e){this._scene=e}get gameObjects(){return(e=>{const t=e?.scene?.gameObjects||[],s=e?.multiScenes.map(({gameObjects:e})=>e);let r=[];for(const e of s)r=[...r,...e];return[...t,...r]})(this)}async addSystem(e,s){let r;if(e instanceof Function)r=new e(s);else{if(!(e instanceof T))return void console.warn("can only add System");r=e}if(!this.systems.find(e=>e.constructor===r.constructor)){r.game=this,r.init&&await Promise.resolve(r.init(r.__systemDefaultParams)),P({systemName:$(r.constructor),...F(r.constructor)},this.pluginInitNotifyTargetOrigin),function(e,t){m[t.systemName]=t.observerInfo,h[t.systemName]=e}(r,r.constructor),function(e){const s=[];e instanceof Array?s.push(...e):s.push(e);for(const e of s)for(const s in e.observerInfo){d[s]=d[s]||[];const r=d[s];for(const o of e.observerInfo[s])-1===r.findIndex(e=>t.isEqual(e,o))&&d[s].push(o)}}(r.constructor);try{r.awake&&r.awake()}catch(e){console.error(`${$(r.constructor)} awake error`,e)}return this.systems.push(r),r}console.warn(`${$(r.constructor)} System has been added`)}removeSystem(e){if(!e)return;let t=-1;"string"==typeof e?t=this.systems.findIndex(t=>t.name===e):e instanceof Function?t=this.systems.findIndex(t=>t.constructor===e):e instanceof T&&(t=this.systems.findIndex(t=>t===e)),t>-1&&(this.systems[t].destroy&&this.systems[t].destroy(),this.systems.splice(t,1))}getSystem(e){return this.systems.find(t=>"string"==typeof e?t.name===e:t instanceof e)}pause(){this.playing&&(this.playing=!1,this.ticker.pause(),this.triggerPause(),this.notifyStateChanged())}start(){this.playing||(this.playing=!0,this.started=!0,this.ticker.start(),this.notifyStateChanged())}resume(){this.playing||(this.playing=!0,this.ticker.start(),this.triggerResume(),this.notifyStateChanged())}initTicker(){this.ticker.add(e=>{this.scene&&((e,t=[])=>{for(const s of t)for(const t of s.components)try{B(t),t.update&&t.update(e)}catch(e){console.error(`gameObject: ${s.name} ${t.name} update error`,e)}for(const s of t)for(const t of s.components)try{t.lateUpdate&&t.lateUpdate(e)}catch(e){console.error(`gameObject: ${s.name} ${t.name} lateUpdate error`,e)}})(e,this.gameObjects);for(const t of this.systems)try{B(t),t.update&&t.update(e)}catch(e){console.error(`${$(t.constructor)} update error`,e)}for(const t of this.systems)try{t.lateUpdate&&t.lateUpdate(e)}catch(e){console.error(`${$(t.constructor)} lateUpdate error`,e)}})}triggerResume(){(e=>{for(const t of e)for(const e of t.components)try{e.onResume&&e.onResume()}catch(s){console.error(`gameObject: ${t.name}, ${e.name}, onResume error`,s)}})(this.gameObjects);for(const e of this.systems)try{e.onResume&&e.onResume()}catch(t){console.error(`${$(e.constructor)}, onResume error`,t)}}triggerPause(){(e=>{for(const t of e)for(const e of t.components)try{e.onPause&&e.onPause()}catch(s){console.error(`gameObject: ${t.name}, ${e.name}, onPause error`,s)}})(this.gameObjects);for(const e of this.systems)try{e.onPause&&e.onPause()}catch(t){console.error(`${$(e.constructor)}, onPause error`,t)}}destroySystems(){for(const e of[...this.systems])this.removeSystem(e);this.systems.length=0}destroy(){"undefined"!=typeof window&&window.removeEventListener("message",this.onHostMessage),this.removeAllListeners(),this.pause(),this.scene.destroy(),this.destroySystems(),this.ticker=null,this.scene=null,this.canvas=null,this.multiScenes=null}loadScene({scene:e,mode:t=exports.LOAD_SCENE_MODE.SINGLE,params:s={}}){if(e){switch(e.game=this,t){case exports.LOAD_SCENE_MODE.SINGLE:this.scene=e;break;case exports.LOAD_SCENE_MODE.MULTI_CANVAS:this.multiScenes.push(e)}this.emit("sceneChanged",{scene:e,mode:t,params:s})}}}function H(e,t){e.constructor.IDEProps||(e.constructor.IDEProps=[]),e.constructor.IDEProps.push(t)}function q(e={}){return function(t){if(!t.observerInfo){for(const t in e)for(const s in e[t]){let r;"string"==typeof e[t][s]&&(e[t][s]=[e[t][s]]),Array.isArray(e[t][s])&&(r={prop:e[t][s],deep:!1},e[t][s]=r),r=e[t][s],"string"==typeof r.prop&&(r.prop=[r.prop])}t.observerInfo=e}}}var z;exports.LOAD_EVENT=void 0,(z=exports.LOAD_EVENT||(exports.LOAD_EVENT={})).START="start",z.PROGRESS="progress",z.LOADED="loaded",z.COMPLETE="complete",z.ERROR="error";class J extends i.default{constructor({resource:e,resourceTotal:t}){super(),this.progress=0,this.resourceTotal=0,this.resourceLoadedCount=0,this.resource=e,this.resourceTotal=t,0===t&&this.resource.emit(exports.LOAD_EVENT.COMPLETE,this)}onStart(){this.resource.emit(exports.LOAD_EVENT.START,this)}onProgress(e){this.resourceLoadedCount++,this.progress=Math.floor(this.resourceLoadedCount/this.resourceTotal*100)/100,e.success?this.resource.emit(exports.LOAD_EVENT.LOADED,this,e):this.resource.emit(exports.LOAD_EVENT.ERROR,this,e),this.resource.emit(exports.LOAD_EVENT.PROGRESS,this,e),this.resourceLoadedCount===this.resourceTotal&&this.resource.emit(exports.LOAD_EVENT.COMPLETE,this)}}const W={AbstractLoadStrategy:o.AbstractLoadStrategy,AudioLoadStrategy:o.AudioLoadStrategy,ImageLoadStrategy:o.ImageLoadStrategy,XhrResponseType:o.XhrResponseType,MediaElementLoadStrategy:o.MediaElementLoadStrategy,VideoLoadStrategy:o.VideoLoadStrategy,XhrLoadStrategy:o.XhrLoadStrategy,Loader:o.Loader,Resource:o.Resource,ResourceType:o.ResourceType,ResourceState:o.ResourceState};var K;exports.RESOURCE_TYPE=void 0,(K=exports.RESOURCE_TYPE||(exports.RESOURCE_TYPE={})).IMAGE="IMAGE",K.SPRITE="SPRITE",K.SPRITE_ANIMATION="SPRITE_ANIMATION",K.AUDIO="AUDIO",K.VIDEO="VIDEO",K.GLB="GLB",o.XhrLoadStrategy.setExtensionXhrType("json",o.XhrResponseType.Json),o.XhrLoadStrategy.setExtensionXhrType("tex",o.XhrResponseType.Json),o.XhrLoadStrategy.setExtensionXhrType("ske",o.XhrResponseType.Json),o.XhrLoadStrategy.setExtensionXhrType("mp3",o.XhrResponseType.Buffer),o.XhrLoadStrategy.setExtensionXhrType("wav",o.XhrResponseType.Buffer),o.XhrLoadStrategy.setExtensionXhrType("aac",o.XhrResponseType.Buffer),o.XhrLoadStrategy.setExtensionXhrType("ogg",o.XhrResponseType.Buffer),o.XhrLoadStrategy.setExtensionXhrType("glb",o.XhrResponseType.Buffer),o.XhrLoadStrategy.setExtensionXhrType("gltf",o.XhrResponseType.Json);const Q={png:o.ImageLoadStrategy,jpg:o.ImageLoadStrategy,jpeg:o.ImageLoadStrategy,webp:o.ImageLoadStrategy,json:o.XhrLoadStrategy,tex:o.XhrLoadStrategy,ske:o.XhrLoadStrategy,audio:o.XhrLoadStrategy,video:o.VideoLoadStrategy,glb:o.XhrLoadStrategy,gltf:o.XhrLoadStrategy};class Z extends i.default{constructor(e){super(),this.timeout=6e3,this.preProcessResourceHandlers=[],this.resourcesMap={},this.makeInstanceFunctions={},this.destroyInstanceFunctions={},this.promiseMap={},this.loaders=[],e&&"number"==typeof e.timeout&&(this.timeout=e.timeout)}loadConfig(e){this.addResource(e),this.preload()}loadSingle(e){return this.addResource([e]),this.getResource(e.name)}addResource(e){if(!e||e.length<1)console.warn("no resources");else for(const t of e)this.resourcesMap[t.name]?console.warn(t.name+" was already added"):(this.resourcesMap[t.name]=t,this.resourcesMap[t.name].data={})}addPreProcessResourceHandler(e){this.preProcessResourceHandlers.push(e)}removePreProcessResourceHandler(e){this.preProcessResourceHandlers.splice(this.preProcessResourceHandlers.indexOf(e),1)}preload(){const e=[];for(const t in this.resourcesMap){const s=this.resourcesMap[t];!s.preload||s.complete||this.promiseMap[t]||e.push(s.name)}this.progress=new J({resource:this,resourceTotal:e.length}),this.loadResource({names:e,preload:!0})}async getResource(e){return this.loadResource({names:[e]}),this.promiseMap[e]||Promise.resolve({})}async instance(e){const t=this.resourcesMap[e];return this.makeInstanceFunctions[t.type]&&await this.makeInstanceFunctions[t.type](t)}async destroy(e){await this._destroy(e)}async _destroy(e,t=!1){const s=this.resourcesMap[e];if(s){if(!t)try{this.destroyInstanceFunctions[s.type]&&await this.destroyInstanceFunctions[s.type](s)}catch(e){console.warn(`destroy resource ${s.name} error with '${e.message}'`)}delete this.promiseMap[e],s.data={},s.complete=!1,s.instance=void 0}}registerResourceType(e,t=e){if(exports.RESOURCE_TYPE[e])throw new Error(`The type ${e} already exists in RESOURCE_TYPE`);exports.RESOURCE_TYPE[e]=t}registerInstance(e,t){this.makeInstanceFunctions[e]=t}registerDestroy(e,t){this.destroyInstanceFunctions[e]=t}loadResource({names:e=[],preload:t=!1}){const s=e.filter(e=>!this.promiseMap[e]&&this.resourcesMap[e]);if(!s.length)return;const r={},o=this.getLoader(t);s.forEach(e=>{this.promiseMap[e]=new Promise(t=>r[e]=t);const s=this.resourcesMap[e];for(const e of this.preProcessResourceHandlers)e(s);for(const n in s.src){const a=s.src[n].type;"data"===a?(s.data[n]=s.src[n].data,this.doComplete(e,r[e],t)):o.add({url:s.src[n].url,name:`${s.name}_${n}`,strategy:Q[a],metadata:{key:n,name:s.name,resolves:r}})}}),o.load()}async doComplete(e,t,s=!1){const r=this.resourcesMap[e],o={name:e,resource:this.resourcesMap[e],success:!0};if(this.checkAllLoaded(e))try{r.instance=await this.instance(e),r.complete=!0,s&&this.progress.onProgress(o),t(r)}catch(e){console.error(e),r.complete=!1,s&&(o.errMsg=e.message,o.success=!1,this.progress.onProgress(o)),t({})}}checkAllLoaded(e){const t=this.resourcesMap[e];return Array.from(Object.keys(t.src)).every(e=>t.data[e])}getLoader(e=!1){let t=this.loaders.find(({loading:e})=>!e);return t||(t=new o.Loader,this.loaders.push(t)),e&&t.onStart.once(()=>{this.progress.onStart()}),t.onLoad.add((t,s)=>{this.onLoad({preload:e,resource:s})}),t.onError.add((t,s,r)=>{this.onError({errMsg:t,resource:r,preload:e})}),t.onComplete.once(()=>{t.onLoad.detachAll(),t.onError.detachAll(),t.reset()}),t}async onLoad({preload:e=!1,resource:t}){const{metadata:{key:s,name:r,resolves:o},data:n}=t;this.resourcesMap[r].data[s]=n,this.doComplete(r,o[r],e)}async onError({errMsg:e,preload:t=!1,resource:s}){const{metadata:{name:r,resolves:o}}=s;if(this._destroy(r,!0),o[r]({}),t){const t={name:r,resource:this.resourcesMap[r],success:!1,errMsg:e};this.progress.onProgress(t)}}}const ee=new Z,te={IDEProp:H,componentObserver:q};console.log(`@combos-fun/engine version: ${L}`),exports.COMBOS_GAME_PLUGIN_INIT_SUCCESS=M,exports.COMBOS_GAME_READY=x,exports.COMBOS_GAME_SET_PLAYING=C,exports.COMBOS_GAME_STATE_CHANGED=N,exports.Component=c,exports.DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES=X,exports.Game=Y,exports.GameObject=_,exports.IDEProp=H,exports.RESOURCE_TYPE_STRATEGY=Q,exports.Scene=w,exports.System=T,exports.Transform=g,exports.componentObserver=q,exports.decorators=te,exports.isAllowedMessageOrigin=V,exports.mergeAllowedMessageOrigins=G,exports.parseSetPlayingMessage=j,exports.postParentGameReady=I,exports.postParentGameState=D,exports.postParentPluginInitSuccess=P,exports.resource=ee,exports.resourceLoader=W,exports.version=L;
|
|
1
|
+
"use strict";var e=require("eventemitter3"),t=require("lodash-es"),s=require("tslib"),r=require("@combos-fun/inspector-decorator"),o=require("resource-loader");function n(e){return e&&e.__esModule?e:{default:e}}var a,i=n(e);class c extends i.default{get game(){return this.gameObject?.scene?.game}constructor(e){super(),this.started=!1;const t=this.constructor;this.name=t.componentName,this.__componentDefaultParams=e}}exports.OBSERVER_TYPE=void 0,(a=exports.OBSERVER_TYPE||(exports.OBSERVER_TYPE={})).ADD="ADD",a.REMOVE="REMOVE",a.CHANGE="CHANGE";const p={},m={},h={},l={};function d(e,t){p[e.gameObject.id]||(p[e.gameObject.id]={});const s=p[e.gameObject.id],r=e.name+"_"+t.join(",");if(s[r])return s[r];const o=t.length-1;let n=e;for(let e=0;e<o;e++){if(void 0===n[t[e]]||null===n[t[e]])return{property:void 0,key:void 0};n=n[t[e]]}return s[r]={property:n,key:t[o]},s[r]}function u({systemName:e,componentName:t,component:s,prop:r,type:o}){m[e]?.componentObserver?.add({component:s,prop:r,type:o,componentName:t})}function f({obj:e,key:s,prop:r,component:o,componentName:n}){if(void 0!==e)if(s in e){if(Object.defineProperty(e,`_${s}`,{enumerable:!1,writable:!0,value:e[s]}),r.deep&&t.isObject(e[s]))for(const t of Object.keys(e[s]))f({obj:e[s],key:t,prop:r,component:o,componentName:n});Object.defineProperty(e,s,{enumerable:!0,set(a){e[`_${s}`]!==a&&(e[`_${s}`]=a,function({prop:e,component:s,componentName:r}){for(const o in h){const n=(h[o]||{})[r];n&&(n.findIndex(s=>t.isEqual(s,e))>-1&&u({systemName:o,componentName:r,component:s,prop:e,type:exports.OBSERVER_TYPE.CHANGE}))}}({prop:r,component:o,componentName:n}))},get:()=>e[`_${s}`]})}else console.error(`prop ${s} not in component: ${n}, Can not observer`)}function y(e,t=e.name){for(const s in h){(h[s]||{})[t]&&m[s]?.componentObserver?.add({component:e,type:exports.OBSERVER_TYPE.REMOVE,componentName:t})}!function(e){e.gameObject&&delete p[e.gameObject.id]}(e)}class g extends c{constructor(){super(...arguments),this.name="Transform",this._parent=null,this.inScene=!1,this.children=[],this.position={x:0,y:0},this.size={width:0,height:0},this.origin={x:0,y:0},this.anchor={x:0,y:0},this.scale={x:1,y:1},this.skew={x:0,y:0},this.rotation=0}static{this.componentName="Transform"}init(e={}){const t=["position","size","origin","anchor","scale","skew"];for(const s of t)Object.assign(this[s],e[s]);this.rotation=e.rotation??this.rotation}set parent(e){e?e.addChild(this):this.parent&&this.parent.removeChild(this)}get parent(){return this._parent}addChild(e){if(e.parent===this){const t=this.children.findIndex(t=>t===e);this.children.splice(t,1)}else e.parent&&e.parent.removeChild(e);e._parent=this,this.children.push(e)}removeChild(e){const t=this.children.findIndex(t=>t===e);t>-1&&(this.children.splice(t,1),e._parent=null)}clearChildren(){this.children.length=0}}s.__decorate([r.Field({type:"vector2",step:1,group:"Transform",label:"Position",description:"Position on the design canvas (x right, y down)."})],g.prototype,"position",void 0),s.__decorate([r.Field({type:"size",step:1,min:0,group:"Transform",label:"Size",description:"Width and height of the object in design pixels."})],g.prototype,"size",void 0),s.__decorate([r.Field({type:"vector2",step:.1,group:"Transform",label:"Origin",description:"Local origin used for layout math."})],g.prototype,"origin",void 0),s.__decorate([r.Field({type:"vector2",step:.1,group:"Transform",label:"Anchor",description:"Anchor point (0–1) used when positioning and scaling."})],g.prototype,"anchor",void 0),s.__decorate([r.Field({type:"vector2",step:.1,group:"Transform",label:"Scale",description:"Scale multipliers on X and Y (1 = original size)."})],g.prototype,"scale",void 0),s.__decorate([r.Field({type:"vector2",step:.1,group:"Transform",label:"Skew",description:"Skew amounts on X and Y."})],g.prototype,"skew",void 0),s.__decorate([r.Field({type:"number",step:.1,group:"Transform",label:"Rotation",description:"Rotation in radians.",editor:"number-stepper"})],g.prototype,"rotation",void 0);let E=0;class b{constructor(e,t){this._componentCache={},this.components=[],this.destroyed=!1,this._name=e,this.id=++E,this.addComponent(g,t)}get transform(){return this.getComponent(g)}get parent(){return this.transform&&this.transform.parent&&this.transform.parent.gameObject}get name(){return this._name}set scene(e){if(this._scene===e)return;const t=this._scene;if(this._scene=e,this.transform&&this.transform.children)for(const t of this.transform.children)t.gameObject.scene=e;e?e.addGameObject(this):t&&t.removeGameObject(this)}get scene(){return this._scene}addChild(e){if(e&&e.transform&&e!==this){if(!(e instanceof b))throw new Error("addChild only receive GameObject");if(!this.transform)throw new Error(`gameObject '${this.name}' has been destroy`);e.transform.parent=this.transform,e.scene=this.scene}}removeChild(e){return e instanceof b&&e.parent&&e.parent===this?(e.transform.parent=null,e.scene=null,e):e}addComponent(e,t){if(this.destroyed)return;const s=function(e){return e instanceof c?e.name:e instanceof Function?e.componentName:void 0}(e);if(this._componentCache[s])return;let r;if(e instanceof Function)r=new e(t);else{if(!(e instanceof c))throw new Error("addComponent recieve Component and Component Constructor");r=e}if(r.gameObject)throw new Error(`component has been added on gameObject ${r.gameObject.name}`);return r.gameObject=this,r.init&&r.init(r.__componentDefaultParams),function(e,t=e.name){for(const s in h)(h[s]||{})[t]&&m[s]?.componentObserver?.add({component:e,type:exports.OBSERVER_TYPE.ADD,componentName:t})}(r,r.name),function(e,t=e.name){if(t&&l[t]){if(!(e&&(s=e,s&&s.constructor&&"componentName"in s.constructor)))throw new Error("component param must be an instance of Component");var s;if(!e.gameObject||!e.gameObject.id)throw new Error("component should be add to a gameObject");for(const s of l[t]){const{property:r,key:o}=d(e,s.prop);f({obj:r,key:o,prop:s,component:e,componentName:t})}}}(r,r.name),this.components.push(r),this._componentCache[s]=r,r.awake&&r.awake(),r}removeComponent(e){let t;if("string"==typeof e?t=e:e instanceof c?t=e.name:e.componentName&&(t=e.componentName),"Transform"===t)throw new Error("Transform can't be removed");return this._removeComponent(t)}_removeComponent(e){const t=this.components.findIndex(({name:t})=>t===e);if(-1===t)return;const s=this.components.splice(t,1)[0];return delete this._componentCache[e],delete s.__componentDefaultParams,s.onDestroy&&s.onDestroy(),y(s,e),s.gameObject=void 0,s}getComponent(e){let t;return"string"==typeof e?t=e:e instanceof c?t=e.name:e.componentName&&(t=e.componentName),void 0!==this._componentCache[t]?this._componentCache[t]:void 0}remove(){if(this.parent)return this.parent.removeChild(this)}destroy(){if(this.transform){Array.from(this.transform.children).forEach(({gameObject:e})=>{e.destroy()}),this.remove(),this.transform.clearChildren();for(const e in this._componentCache)this._removeComponent(e);this.components.length=0,this.destroyed=!0}else console.error("Cannot destroy gameObject that have already been destroyed.")}}class S{constructor(){this.events=[]}add({component:e,prop:s,type:r,componentName:o}){if(r===exports.OBSERVER_TYPE.REMOVE){if(this.events.find(t=>t.component===e&&t.type===exports.OBSERVER_TYPE.ADD))return void(this.events=this.events.filter(t=>t.component!==e));this.events=this.events.filter(t=>t.component!==e)}const n=this.events.findIndex(o=>o.component===e&&t.isEqual(o.prop,s)&&o.type===r);n>-1&&this.events.splice(n,1),this.events.push({gameObject:e.gameObject,component:e,prop:s,type:r,componentName:o})}getChanged(){return this.events}get changed(){return this.events}clear(){const e=this.events;return this.events=[],e}}class T{constructor(e){this.started=!1,this.componentObserver=new S,this.__systemDefaultParams=e;const t=this.constructor;this.name=t.systemName}destroy(){this.componentObserver=null,this.__systemDefaultParams=null,this.onDestroy?.()}}const _=function(){let e=null;return e=Date.now?Date.now:()=>(new Date).getTime(),e}(),O={originTime:0,playbackRate:1};class R{constructor(e,t){e instanceof R&&(t=e,e={}),e=Object.assign({},O,e),t&&(this._parent=t),this._createTime=_(),this._timeMark=[{globalTime:this.globalTime,localTime:-e.originTime,entropy:-e.originTime,playbackRate:e.playbackRate,globalEntropy:0}],this._parent&&(this._timeMark[0].globalEntropy=this._parent.entropy),this._playbackRate=e.playbackRate}get globalTime(){return this.parent?this.parent.currentTime:_()-this._createTime}get parent(){return this._parent}get lastTimeMark(){return this._timeMark[this._timeMark.length-1]}markTime({time:e=this.currentTime,entropy:t=this.entropy,playbackRate:s=this.playbackRate}={}){const r={globalTime:this.globalTime,localTime:e,entropy:t,playbackRate:s,globalEntropy:this.globalEntropy};this._timeMark.push(r)}get currentTime(){const{localTime:e,globalTime:t}=this.lastTimeMark;return e+(this.globalTime-t)*this.playbackRate}set currentTime(e){this.markTime({time:e})}get globalEntropy(){return this._parent?this._parent.entropy:this.globalTime}get entropy(){const{entropy:e,globalEntropy:t}=this.lastTimeMark;return e+Math.abs((this.globalEntropy-t)*this.playbackRate)}set entropy(e){if(this.entropy>e){const t=this.seekTimeMark(e);this._timeMark.length=t+1}this.markTime({entropy:e})}fork(e){return new R(e,this)}seekGlobalTime(e){const t=this.seekTimeMark(e),s=this._timeMark[t],{entropy:r,playbackRate:o,globalTime:n}=s;return n+(e-r)/Math.abs(o)}seekLocalTime(e){const t=this.seekTimeMark(e),s=this._timeMark[t],{localTime:r,entropy:o,playbackRate:n}=s;return n>0?r+(e-o):r-(e-o)}seekTimeMark(e){const t=this._timeMark;let s=0,r=t.length-1;if(e<=t[s].entropy)return s;if(e>=t[r].entropy)return r;let o=Math.floor((s+r)/2);for(;o>s&&o<r;){if(e===t[o].entropy)return o;e<t[o].entropy?r=o:e>t[o].entropy&&(s=o),o=Math.floor((s+r)/2)}return s}get playbackRate(){return this._playbackRate}set playbackRate(e){e!==this.playbackRate&&(this.markTime({playbackRate:e}),this._playbackRate=e)}get paused(){if(0===this.playbackRate)return!0;let e=this.parent;for(;e;){if(0===e.playbackRate)return!0;e=e.parent}return!1}}const k={autoStart:!0,frameRate:60};class x{constructor(e){e=Object.assign({},k,e),this._frameCount=0,this._frameDuration=1e3/e.frameRate,this.autoStart=e.autoStart,this.frameRate=e.frameRate,this.timeline=new R({originTime:0,playbackRate:1}),this._lastFrameTime=this.timeline.currentTime,this._tickers=new Set,this._requestId=null,this._ticker=()=>{this._started&&(this._requestId=requestAnimationFrame(this._ticker),this.update())},this.autoStart&&this.start()}update(){const e=this.timeline.currentTime,t=e-this._lastFrameTime;if(t>=this._frameDuration){const s=e-t%this._frameDuration,r=s-this._lastFrameTime;this._lastFrameTime=s;const o={deltaTime:r,delta:r,time:s,currentTime:s,frameCount:++this._frameCount,fps:Math.round(1e3/r)};for(const e of this._tickers)"function"==typeof e&&e(o)}}add(e){this._tickers.add(e)}remove(e){this._tickers.delete(e)}start(){this._started||(this._started=!0,this.timeline.playbackRate=1,this._requestId=requestAnimationFrame(this._ticker))}pause(){this._started=!1,this.timeline.playbackRate=0}setPlaybackRate(e){this.timeline.playbackRate=e}}class w extends b{constructor(e,t){super(e,t),this.gameObjects=[],this.scene=this}addGameObject(e){this.gameObjects.push(e),e.transform&&(e.transform.inScene=!0)}removeGameObject(e){const t=this.gameObjects.indexOf(e);-1!==t&&(e.transform&&(e.transform.inScene=!1),this.gameObjects.splice(t,1))}destroy(){this.scene=null,super.destroy(),this.gameObjects=null,this.canvas=null}}const L="0.0.40",v="combos-game:plugin-init-success",M="combos-game:ready",A="combos-game:set-playing",C="combos-game:state-changed";function j(e,t){if("undefined"!=typeof window&&window.parent&&window.parent!==window)try{window.parent.postMessage(e,t)}catch{}}function N(e,t="*"){j({type:v,systemName:e.systemName,engineVersion:L,...e.packageName?{packageName:e.packageName}:{},...e.packageVersion?{packageVersion:e.packageVersion}:{}},t)}function I(e,t="*"){j({type:M,engineVersion:L,...void 0===e?{}:{error:e instanceof Error?e.message:String(e)}},t)}function P(e,t="*"){j({type:C,playing:e.playing,started:e.started},t)}function D(e){if(!e||"object"!=typeof e)return null;const t=e;return t.type!==A||"boolean"!=typeof t.playing?null:t.playing}const X=["knoffice.tech","converge.ai"];function V(e,t){if(t.includes("*"))return!0;if(0===t.length)return!1;let s;try{s=new URL(e)}catch{return!1}const r=e.toLowerCase(),o=s.hostname.toLowerCase();for(const e of t){const t=e.trim();if(!t)continue;if(t.includes("://")){if(r===t.toLowerCase())return!0;continue}const s=t.toLowerCase().replace(/^\./,"");if(o===s||o.endsWith(`.${s}`))return!0}return!1}function $(e){if(!e?.length)return[...X];if(e.includes("*"))return["*"];const t=new Set,s=[];for(const r of[...X,...e]){const e=r.trim();e&&!t.has(e)&&(t.add(e),s.push(e))}return s}function G(e){if("systemName"in e){const t=e.systemName;if("string"==typeof t)return t}return"UnknownSystem"}function F(e){const t=e;return{packageName:"string"==typeof t.packageName?t.packageName:void 0,packageVersion:"string"==typeof t.packageVersion?t.packageVersion:void 0}}var B;exports.LOAD_SCENE_MODE=void 0,(B=exports.LOAD_SCENE_MODE||(exports.LOAD_SCENE_MODE={})).SINGLE="SINGLE",B.MULTI_CANVAS="MULTI_CANVAS";const U=e=>{if((e instanceof T||e instanceof c)&&!e.started){e.started=!0;try{e.start&&e.start()}catch(t){e instanceof c?console.error(`${function(e){if("componentName"in e){const t=e.componentName;if("string"==typeof t)return t}return"UnknownComponent"}(e.constructor)} start error`,t):console.error(`${G(e.constructor)} start error`,t)}}};class Y extends i.default{constructor({systems:e,frameRate:t=60,autoStart:s=!0,needScene:r=!0,onSystemsBootstrapComplete:o,pluginInitNotifyTargetOrigin:n="*",allowedMessageOrigins:a}={}){if(super(),this.playing=!1,this.started=!1,this.multiScenes=[],this.systems=[],this.pluginInitNotifyTargetOrigin="*",this.allowedMessageOrigins=$(),this.onHostMessage=e=>{if(!V(e.origin,this.allowedMessageOrigins))return;const t=D(e.data);null!==t&&this.setPlaying(t)},this.pluginInitNotifyTargetOrigin=n,this.allowedMessageOrigins=$(a),this.ticker=new x({autoStart:!1,frameRate:t}),this.initTicker(),"undefined"!=typeof window&&window.addEventListener("message",this.onHostMessage),e&&e.length){const t=[...e];this.bootstrapSystemsAndMaybeStart(t,r,s,o)}else o?.(this),this.notifyReady()}setPlaying(e){e?this.started?this.resume():this.start():this.pause()}notifyReady(e){I(e,this.pluginInitNotifyTargetOrigin)}notifyStateChanged(){P({playing:this.playing,started:this.started},this.pluginInitNotifyTargetOrigin)}async bootstrapSystemsAndMaybeStart(e,t,s,r){let o;try{for(const t of e)await this.addSystem(t);t&&this.loadScene({scene:new w("scene")}),s&&this.start()}catch(e){o=e,console.error("Game bootstrap failed",e)}finally{r?.(this,o),this.notifyReady(o)}}get scene(){return this._scene}set scene(e){this._scene=e}get gameObjects(){return(e=>{const t=e?.scene?.gameObjects||[],s=e?.multiScenes.map(({gameObjects:e})=>e);let r=[];for(const e of s)r=[...r,...e];return[...t,...r]})(this)}async addSystem(e,s){let r;if(e instanceof Function)r=new e(s);else{if(!(e instanceof T))return void console.warn("can only add System");r=e}if(!this.systems.find(e=>e.constructor===r.constructor)){r.game=this,r.init&&await Promise.resolve(r.init(r.__systemDefaultParams)),N({systemName:G(r.constructor),...F(r.constructor)},this.pluginInitNotifyTargetOrigin),function(e,t){h[t.systemName]=t.observerInfo,m[t.systemName]=e}(r,r.constructor),function(e){const s=[];e instanceof Array?s.push(...e):s.push(e);for(const e of s)for(const s in e.observerInfo){l[s]=l[s]||[];const r=l[s];for(const o of e.observerInfo[s])-1===r.findIndex(e=>t.isEqual(e,o))&&l[s].push(o)}}(r.constructor);try{r.awake&&r.awake()}catch(e){console.error(`${G(r.constructor)} awake error`,e)}return this.systems.push(r),r}console.warn(`${G(r.constructor)} System has been added`)}removeSystem(e){if(!e)return;let t=-1;"string"==typeof e?t=this.systems.findIndex(t=>t.name===e):e instanceof Function?t=this.systems.findIndex(t=>t.constructor===e):e instanceof T&&(t=this.systems.findIndex(t=>t===e)),t>-1&&(this.systems[t].destroy&&this.systems[t].destroy(),this.systems.splice(t,1))}getSystem(e){return this.systems.find(t=>"string"==typeof e?t.name===e:t instanceof e)}pause(){this.playing&&(this.playing=!1,this.ticker.pause(),this.triggerPause(),this.notifyStateChanged())}start(){this.playing||(this.playing=!0,this.started=!0,this.ticker.start(),this.notifyStateChanged())}resume(){this.playing||(this.playing=!0,this.ticker.start(),this.triggerResume(),this.notifyStateChanged())}initTicker(){this.ticker.add(e=>{this.scene&&((e,t=[])=>{for(const s of t)for(const t of s.components)try{U(t),t.update&&t.update(e)}catch(e){console.error(`gameObject: ${s.name} ${t.name} update error`,e)}for(const s of t)for(const t of s.components)try{t.lateUpdate&&t.lateUpdate(e)}catch(e){console.error(`gameObject: ${s.name} ${t.name} lateUpdate error`,e)}})(e,this.gameObjects);for(const t of this.systems)try{U(t),t.update&&t.update(e)}catch(e){console.error(`${G(t.constructor)} update error`,e)}for(const t of this.systems)try{t.lateUpdate&&t.lateUpdate(e)}catch(e){console.error(`${G(t.constructor)} lateUpdate error`,e)}})}triggerResume(){(e=>{for(const t of e)for(const e of t.components)try{e.onResume&&e.onResume()}catch(s){console.error(`gameObject: ${t.name}, ${e.name}, onResume error`,s)}})(this.gameObjects);for(const e of this.systems)try{e.onResume&&e.onResume()}catch(t){console.error(`${G(e.constructor)}, onResume error`,t)}}triggerPause(){(e=>{for(const t of e)for(const e of t.components)try{e.onPause&&e.onPause()}catch(s){console.error(`gameObject: ${t.name}, ${e.name}, onPause error`,s)}})(this.gameObjects);for(const e of this.systems)try{e.onPause&&e.onPause()}catch(t){console.error(`${G(e.constructor)}, onPause error`,t)}}destroySystems(){for(const e of[...this.systems])this.removeSystem(e);this.systems.length=0}destroy(){"undefined"!=typeof window&&window.removeEventListener("message",this.onHostMessage),this.removeAllListeners(),this.pause(),this.scene.destroy(),this.destroySystems(),this.ticker=null,this.scene=null,this.canvas=null,this.multiScenes=null}loadScene({scene:e,mode:t=exports.LOAD_SCENE_MODE.SINGLE,params:s={}}){if(e){switch(e.game=this,t){case exports.LOAD_SCENE_MODE.SINGLE:this.scene=e;break;case exports.LOAD_SCENE_MODE.MULTI_CANVAS:this.multiScenes.push(e)}this.emit("sceneChanged",{scene:e,mode:t,params:s})}}}function q(e,t){e.constructor.IDEProps||(e.constructor.IDEProps=[]),e.constructor.IDEProps.push(t)}function z(e={}){return function(t){if(!t.observerInfo){for(const t in e)for(const s in e[t]){let r;"string"==typeof e[t][s]&&(e[t][s]=[e[t][s]]),Array.isArray(e[t][s])&&(r={prop:e[t][s],deep:!1},e[t][s]=r),r=e[t][s],"string"==typeof r.prop&&(r.prop=[r.prop])}t.observerInfo=e}}}var H;exports.LOAD_EVENT=void 0,(H=exports.LOAD_EVENT||(exports.LOAD_EVENT={})).START="start",H.PROGRESS="progress",H.LOADED="loaded",H.COMPLETE="complete",H.ERROR="error";class J extends i.default{constructor({resource:e,resourceTotal:t}){super(),this.progress=0,this.resourceTotal=0,this.resourceLoadedCount=0,this.resource=e,this.resourceTotal=t,0===t&&this.resource.emit(exports.LOAD_EVENT.COMPLETE,this)}onStart(){this.resource.emit(exports.LOAD_EVENT.START,this)}onProgress(e){this.resourceLoadedCount++,this.progress=Math.floor(this.resourceLoadedCount/this.resourceTotal*100)/100,e.success?this.resource.emit(exports.LOAD_EVENT.LOADED,this,e):this.resource.emit(exports.LOAD_EVENT.ERROR,this,e),this.resource.emit(exports.LOAD_EVENT.PROGRESS,this,e),this.resourceLoadedCount===this.resourceTotal&&this.resource.emit(exports.LOAD_EVENT.COMPLETE,this)}}const W={image:"png",json:"json",tex:"tex",ske:"ske",audio:"audio",video:"video",model:"glb",mtl:"mtl",bin:"bin"},K={png:"png",jpg:"jpg",jpeg:"jpeg",webp:"webp",json:"json",tex:"tex",ske:"ske",mp3:"audio",wav:"audio",aac:"audio",ogg:"audio",mp4:"video",webm:"video",glb:"glb",gltf:"gltf",fbx:"fbx",obj:"obj",mtl:"mtl",stl:"stl",dae:"dae",ply:"ply",bin:"bin"};function Q(e,t){return K[function(e){const t=e.split("?")[0].split("#")[0],s=t.lastIndexOf(".");return s<0?"":t.slice(s+1).toLowerCase()}(e)]||W[t]||"png"}function Z(e,t,s){if("string"==typeof t){const r=t.trim();if(!r)throw ee(s,e);return{type:Q(r,e),url:r}}if(!t||"object"!=typeof t||Array.isArray(t))throw new Error(`Resource "${s}" src.${e} must be a url string or { type, url }.`);const r=t;if("data"===r.type)return r;const o="string"==typeof r.url?r.url.trim():"";if(!o)throw ee(s,e);return{...r,type:r.type||Q(o,e),url:o}}function ee(e,t){return new Error(`Resource "${e}" src.${t}.url is required. Use { type, url } (e.g. { type: "webp", url: "https://..." }). A flat path string is also accepted and will be normalized.`)}function te(e,t,s="(unnamed)"){if(null==e)throw new Error(`Resource "${s}" src is required.`);if("string"==typeof e){const r=function(e){return"AUDIO"===e?"audio":"VIDEO"===e?"video":"MODEL"===e||"GLB"===e?"model":"image"}(t);return{[r]:Z(r,e,s)}}if("object"!=typeof e||Array.isArray(e))throw new Error(`Resource "${s}" src must be a url string or a slot object.`);const r={};for(const[t,o]of Object.entries(e))null!=o&&(r[t]=Z(t,o,s));if(0===Object.keys(r).length)throw new Error(`Resource "${s}" src has no loadable slots.`);return r}const se={AbstractLoadStrategy:o.AbstractLoadStrategy,AudioLoadStrategy:o.AudioLoadStrategy,ImageLoadStrategy:o.ImageLoadStrategy,XhrResponseType:o.XhrResponseType,MediaElementLoadStrategy:o.MediaElementLoadStrategy,VideoLoadStrategy:o.VideoLoadStrategy,XhrLoadStrategy:o.XhrLoadStrategy,Loader:o.Loader,Resource:o.Resource,ResourceType:o.ResourceType,ResourceState:o.ResourceState};function re(e){const t=e.frame;return t&&"object"==typeof t?{...e,frame:t,rotated:Boolean(e.rotated),trimmed:Boolean(e.trimmed),spriteSourceSize:e.spriteSourceSize,sourceSize:e.sourceSize}:null}function oe(e,t,s){for(const r of e){if(!r||"object"!=typeof r)continue;const e=r,o=String(e.filename||e.name||"");if(!o)continue;const n=re(e);if(!n)continue;t[o]=n;const a=o.lastIndexOf("/");if(a>0){const e=o.slice(0,a);s[e]||(s[e]=[]),s[e].includes(o)||s[e].push(o)}}}var ne;exports.RESOURCE_TYPE=void 0,(ne=exports.RESOURCE_TYPE||(exports.RESOURCE_TYPE={})).IMAGE="IMAGE",ne.SPRITE="SPRITE",ne.SPRITE_ANIMATION="SPRITE_ANIMATION",ne.AUDIO="AUDIO",ne.VIDEO="VIDEO",ne.GLB="GLB",ne.MODEL="MODEL",o.XhrLoadStrategy.setExtensionXhrType("json",o.XhrResponseType.Json),o.XhrLoadStrategy.setExtensionXhrType("tex",o.XhrResponseType.Json),o.XhrLoadStrategy.setExtensionXhrType("ske",o.XhrResponseType.Json),o.XhrLoadStrategy.setExtensionXhrType("mp3",o.XhrResponseType.Buffer),o.XhrLoadStrategy.setExtensionXhrType("wav",o.XhrResponseType.Buffer),o.XhrLoadStrategy.setExtensionXhrType("aac",o.XhrResponseType.Buffer),o.XhrLoadStrategy.setExtensionXhrType("ogg",o.XhrResponseType.Buffer),o.XhrLoadStrategy.setExtensionXhrType("glb",o.XhrResponseType.Buffer),o.XhrLoadStrategy.setExtensionXhrType("gltf",o.XhrResponseType.Json),o.XhrLoadStrategy.setExtensionXhrType("fbx",o.XhrResponseType.Buffer),o.XhrLoadStrategy.setExtensionXhrType("stl",o.XhrResponseType.Buffer),o.XhrLoadStrategy.setExtensionXhrType("ply",o.XhrResponseType.Buffer),o.XhrLoadStrategy.setExtensionXhrType("bin",o.XhrResponseType.Buffer),o.XhrLoadStrategy.setExtensionXhrType("obj",o.XhrResponseType.Text),o.XhrLoadStrategy.setExtensionXhrType("mtl",o.XhrResponseType.Text),o.XhrLoadStrategy.setExtensionXhrType("dae",o.XhrResponseType.Text);const ae={png:o.ImageLoadStrategy,jpg:o.ImageLoadStrategy,jpeg:o.ImageLoadStrategy,webp:o.ImageLoadStrategy,json:o.XhrLoadStrategy,tex:o.XhrLoadStrategy,ske:o.XhrLoadStrategy,audio:o.XhrLoadStrategy,video:o.VideoLoadStrategy,glb:o.XhrLoadStrategy,gltf:o.XhrLoadStrategy,fbx:o.XhrLoadStrategy,obj:o.XhrLoadStrategy,mtl:o.XhrLoadStrategy,stl:o.XhrLoadStrategy,dae:o.XhrLoadStrategy,ply:o.XhrLoadStrategy,bin:o.XhrLoadStrategy};class ie extends i.default{constructor(e){super(),this.timeout=6e3,this.preProcessResourceHandlers=[],this.resourcesMap={},this.makeInstanceFunctions={},this.destroyInstanceFunctions={},this.promiseMap={},this.loaders=[],e&&"number"==typeof e.timeout&&(this.timeout=e.timeout)}loadConfig(e){this.addResource(e),this.preload()}loadSingle(e){return this.addResource([e]),this.getResource(e.name)}addResource(e){if(!e||e.length<1)console.warn("no resources");else for(const t of e)this.resourcesMap[t.name]?console.warn(t.name+" was already added"):this.resourcesMap[t.name]={...t,src:te(t.src,String(t.type),t.name),data:{}}}addPreProcessResourceHandler(e){this.preProcessResourceHandlers.push(e)}removePreProcessResourceHandler(e){this.preProcessResourceHandlers.splice(this.preProcessResourceHandlers.indexOf(e),1)}preload(){const e=[];for(const t in this.resourcesMap){const s=this.resourcesMap[t];!s.preload||s.complete||this.promiseMap[t]||e.push(s.name)}this.progress=new J({resource:this,resourceTotal:e.length}),this.loadResource({names:e,preload:!0})}async getResource(e){return this.loadResource({names:[e]}),this.promiseMap[e]||Promise.resolve({})}async instance(e){const t=this.resourcesMap[e];return this.makeInstanceFunctions[t.type]&&await this.makeInstanceFunctions[t.type](t)}async destroy(e){await this._destroy(e)}async _destroy(e,t=!1){const s=this.resourcesMap[e];if(s){if(!t)try{this.destroyInstanceFunctions[s.type]&&await this.destroyInstanceFunctions[s.type](s)}catch(e){console.warn(`destroy resource ${s.name} error with '${e.message}'`)}delete this.promiseMap[e],s.data={},s.complete=!1,s.instance=void 0}}registerResourceType(e,t=e){if(exports.RESOURCE_TYPE[e])throw new Error(`The type ${e} already exists in RESOURCE_TYPE`);exports.RESOURCE_TYPE[e]=t}registerInstance(e,t){this.makeInstanceFunctions[e]=t}registerDestroy(e,t){this.destroyInstanceFunctions[e]=t}loadResource({names:e=[],preload:t=!1}){const s=e.filter(e=>!this.promiseMap[e]&&this.resourcesMap[e]);if(!s.length)return;const r={},o=this.getLoader(t);s.forEach(e=>{this.promiseMap[e]=new Promise(t=>r[e]=t);const s=this.resourcesMap[e];for(const e of this.preProcessResourceHandlers)e(s);s.src=te(s.src,String(s.type),s.name);for(const n in s.src){const a=s.src[n].type;"data"===a?(s.data[n]=s.src[n].data,this.doComplete(e,r[e],t)):o.add({url:s.src[n].url,name:`${s.name}_${n}`,strategy:ae[a],metadata:{key:n,name:s.name,resolves:r}})}}),o.load()}async doComplete(e,t,s=!1){const r=this.resourcesMap[e],o={name:e,resource:this.resourcesMap[e],success:!0};if(this.checkAllLoaded(e))try{r.instance=await this.instance(e),r.complete=!0,s&&this.progress.onProgress(o),t(r)}catch(e){console.error(e),r.complete=!1,s&&(o.errMsg=e.message,o.success=!1,this.progress.onProgress(o)),t({})}}checkAllLoaded(e){const t=this.resourcesMap[e];return Array.from(Object.keys(t.src)).every(e=>t.data[e])}getLoader(e=!1){let t=this.loaders.find(({loading:e})=>!e);return t||(t=new o.Loader,this.loaders.push(t)),e&&t.onStart.once(()=>{this.progress.onStart()}),t.onLoad.add((t,s)=>{this.onLoad({preload:e,resource:s})}),t.onError.add((t,s,r)=>{this.onError({errMsg:t,resource:r,preload:e})}),t.onComplete.once(()=>{t.onLoad.detachAll(),t.onError.detachAll(),t.reset()}),t}async onLoad({preload:e=!1,resource:t}){const{metadata:{key:s,name:r,resolves:o},data:n}=t;this.resourcesMap[r].data[s]=n,this.doComplete(r,o[r],e)}async onError({errMsg:e,preload:t=!1,resource:s}){const{metadata:{name:r,resolves:o}}=s;if(this._destroy(r,!0),o[r]({}),t){const t={name:r,resource:this.resourcesMap[r],success:!1,errMsg:e};this.progress.onProgress(t)}}}const ce=new ie,pe={IDEProp:q,componentObserver:z};console.log(`@combos-fun/engine version: ${L}`),exports.COMBOS_GAME_PLUGIN_INIT_SUCCESS=v,exports.COMBOS_GAME_READY=M,exports.COMBOS_GAME_SET_PLAYING=A,exports.COMBOS_GAME_STATE_CHANGED=C,exports.Component=c,exports.DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES=X,exports.Game=Y,exports.GameObject=b,exports.IDEProp=q,exports.RESOURCE_TYPE_STRATEGY=ae,exports.Scene=w,exports.System=T,exports.Transform=g,exports.componentObserver=z,exports.decorators=pe,exports.isAllowedMessageOrigin=V,exports.mergeAllowedMessageOrigins=$,exports.normalizeResourceSrc=te,exports.normalizeSpritesheetData=function(e){if(!e||"object"!=typeof e)return{frames:{},animations:{},meta:{scale:1}};const t=e;if(function(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}(t.frames))return{...t,frames:t.frames,animations:{...t.animations||{}},meta:{scale:1,...t.meta||{}}};const s={},r={...t.animations||{}};if(Array.isArray(t.textures)){for(const e of t.textures)e&&"object"==typeof e&&Array.isArray(e.frames)&&oe(e.frames,s,r);const e=t.textures[0]||{},o=e.scale??t.meta?.scale??1;return{frames:s,animations:r,meta:{scale:"number"==typeof o||"string"==typeof o?o:1,image:"string"==typeof e.image?e.image:void 0,size:e.size,format:e.format,...t.meta||{}}}}return Array.isArray(t.frames)?(oe(t.frames,s,r),{frames:s,animations:r,meta:{scale:1,...t.meta||{}}}):{frames:{},animations:r,meta:{scale:1,...t.meta||{}}}},exports.parseSetPlayingMessage=D,exports.postParentGameReady=I,exports.postParentGameState=P,exports.postParentPluginInitSuccess=N,exports.resource=ce,exports.resourceLoader=se,exports.version=L;
|
package/dist/engine.d.ts
CHANGED
|
@@ -738,6 +738,79 @@ declare enum LOAD_EVENT {
|
|
|
738
738
|
'ERROR' = "error"
|
|
739
739
|
}
|
|
740
740
|
|
|
741
|
+
/** One media slot after normalization. */
|
|
742
|
+
interface NormalizedSrcSlot {
|
|
743
|
+
type: string;
|
|
744
|
+
url?: string;
|
|
745
|
+
data?: unknown;
|
|
746
|
+
size?: {
|
|
747
|
+
width: number;
|
|
748
|
+
height: number;
|
|
749
|
+
};
|
|
750
|
+
texture?: {
|
|
751
|
+
type: string;
|
|
752
|
+
url: string;
|
|
753
|
+
size?: {
|
|
754
|
+
width: number;
|
|
755
|
+
height: number;
|
|
756
|
+
};
|
|
757
|
+
} | Array<{
|
|
758
|
+
type: string;
|
|
759
|
+
url: string;
|
|
760
|
+
size?: {
|
|
761
|
+
width: number;
|
|
762
|
+
height: number;
|
|
763
|
+
};
|
|
764
|
+
}>;
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Accept the documented `{ type, url }` slots, plus the common guesses
|
|
768
|
+
* `src: "file.png"` and `src: { image: "a.webp", json: "a.json" }`.
|
|
769
|
+
*/
|
|
770
|
+
declare function normalizeResourceSrc(src: unknown, resourceType?: string, resourceName?: string): Record<string, NormalizedSrcSlot>;
|
|
771
|
+
|
|
772
|
+
type SpritesheetFrame = {
|
|
773
|
+
frame: {
|
|
774
|
+
x: number;
|
|
775
|
+
y: number;
|
|
776
|
+
w: number;
|
|
777
|
+
h: number;
|
|
778
|
+
};
|
|
779
|
+
rotated?: boolean;
|
|
780
|
+
trimmed?: boolean;
|
|
781
|
+
spriteSourceSize?: {
|
|
782
|
+
x: number;
|
|
783
|
+
y: number;
|
|
784
|
+
w: number;
|
|
785
|
+
h: number;
|
|
786
|
+
};
|
|
787
|
+
sourceSize?: {
|
|
788
|
+
w: number;
|
|
789
|
+
h: number;
|
|
790
|
+
};
|
|
791
|
+
[key: string]: unknown;
|
|
792
|
+
};
|
|
793
|
+
type PixiSpritesheetData = {
|
|
794
|
+
frames: Record<string, SpritesheetFrame>;
|
|
795
|
+
animations: Record<string, string[]>;
|
|
796
|
+
meta: {
|
|
797
|
+
scale: number | string;
|
|
798
|
+
image?: string;
|
|
799
|
+
size?: {
|
|
800
|
+
w: number;
|
|
801
|
+
h: number;
|
|
802
|
+
};
|
|
803
|
+
[key: string]: unknown;
|
|
804
|
+
};
|
|
805
|
+
};
|
|
806
|
+
/**
|
|
807
|
+
* Pixi `Spritesheet` reads `data.meta.scale` and a name→frame `frames` map.
|
|
808
|
+
* TexturePacker multi-atlas (`textures[].frames` as an array) is accepted and
|
|
809
|
+
* rewritten to that hash. Always returns a `meta.scale` so construction cannot
|
|
810
|
+
* throw `Cannot read properties of undefined (reading 'scale')`.
|
|
811
|
+
*/
|
|
812
|
+
declare function normalizeSpritesheetData(raw: unknown): PixiSpritesheetData;
|
|
813
|
+
|
|
741
814
|
/** Resource type */
|
|
742
815
|
declare enum RESOURCE_TYPE {
|
|
743
816
|
'IMAGE' = "IMAGE",
|
|
@@ -745,7 +818,8 @@ declare enum RESOURCE_TYPE {
|
|
|
745
818
|
'SPRITE_ANIMATION' = "SPRITE_ANIMATION",
|
|
746
819
|
'AUDIO' = "AUDIO",
|
|
747
820
|
'VIDEO' = "VIDEO",
|
|
748
|
-
'GLB' = "GLB"
|
|
821
|
+
'GLB' = "GLB",
|
|
822
|
+
'MODEL' = "MODEL"
|
|
749
823
|
}
|
|
750
824
|
/** Resource item */
|
|
751
825
|
interface SrcBase {
|
|
@@ -943,7 +1017,7 @@ declare function isAllowedMessageOrigin(origin: string, allowed: readonly string
|
|
|
943
1017
|
declare function mergeAllowedMessageOrigins(extra?: string[]): string[];
|
|
944
1018
|
|
|
945
1019
|
/** Generated at build from package.json */
|
|
946
|
-
declare const version = "0.0.
|
|
1020
|
+
declare const version = "0.0.40";
|
|
947
1021
|
|
|
948
1022
|
/** Decorators util */
|
|
949
1023
|
declare const decorators: {
|
|
@@ -951,5 +1025,5 @@ declare const decorators: {
|
|
|
951
1025
|
componentObserver: typeof componentObserver;
|
|
952
1026
|
};
|
|
953
1027
|
|
|
954
|
-
export { COMBOS_GAME_PLUGIN_INIT_SUCCESS, COMBOS_GAME_READY, COMBOS_GAME_SET_PLAYING, COMBOS_GAME_STATE_CHANGED, Component, DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, Game, GameObject, IDEProp, LOAD_EVENT, LOAD_SCENE_MODE, ObserverType as OBSERVER_TYPE, RESOURCE_TYPE, RESOURCE_TYPE_STRATEGY, Scene, System, Transform, componentObserver, decorators, isAllowedMessageOrigin, mergeAllowedMessageOrigins, parseSetPlayingMessage, postParentGameReady, postParentGameState, postParentPluginInitSuccess, resource, resourceLoader, version };
|
|
955
|
-
export type { CombosGamePluginInitSuccessMessage, CombosGameReadyMessage, CombosGameSetPlayingMessage, CombosGameStateChangedMessage, ObserverEvent as ComponentChanged, ComponentParams, GameParams, ObserverInfo, PluginStruct, PureObserverInfo, ResourceBase, SystemConstructor, TransformParams, UpdateParams };
|
|
1028
|
+
export { COMBOS_GAME_PLUGIN_INIT_SUCCESS, COMBOS_GAME_READY, COMBOS_GAME_SET_PLAYING, COMBOS_GAME_STATE_CHANGED, Component, DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, Game, GameObject, IDEProp, LOAD_EVENT, LOAD_SCENE_MODE, ObserverType as OBSERVER_TYPE, RESOURCE_TYPE, RESOURCE_TYPE_STRATEGY, Scene, System, Transform, componentObserver, decorators, isAllowedMessageOrigin, mergeAllowedMessageOrigins, normalizeResourceSrc, normalizeSpritesheetData, parseSetPlayingMessage, postParentGameReady, postParentGameState, postParentPluginInitSuccess, resource, resourceLoader, version };
|
|
1029
|
+
export type { CombosGamePluginInitSuccessMessage, CombosGameReadyMessage, CombosGameSetPlayingMessage, CombosGameStateChangedMessage, ObserverEvent as ComponentChanged, ComponentParams, GameParams, NormalizedSrcSlot, ObserverInfo, PixiSpritesheetData, PluginStruct, PureObserverInfo, ResourceBase, ResourceStruct, SystemConstructor, TransformParams, UpdateParams };
|
package/dist/engine.esm.js
CHANGED
|
@@ -995,7 +995,7 @@ class Scene extends GameObject {
|
|
|
995
995
|
}
|
|
996
996
|
|
|
997
997
|
/** Generated at build from package.json */
|
|
998
|
-
const version = "0.0.
|
|
998
|
+
const version = "0.0.40";
|
|
999
999
|
|
|
1000
1000
|
/**
|
|
1001
1001
|
* Sent to `window.parent` after each `System.init` completes during `Game.addSystem`
|
|
@@ -1636,6 +1636,117 @@ class Progress extends EventEmitter {
|
|
|
1636
1636
|
}
|
|
1637
1637
|
}
|
|
1638
1638
|
|
|
1639
|
+
const SLOT_DEFAULT_TYPE = {
|
|
1640
|
+
image: 'png',
|
|
1641
|
+
json: 'json',
|
|
1642
|
+
tex: 'tex',
|
|
1643
|
+
ske: 'ske',
|
|
1644
|
+
audio: 'audio',
|
|
1645
|
+
video: 'video',
|
|
1646
|
+
model: 'glb',
|
|
1647
|
+
mtl: 'mtl',
|
|
1648
|
+
bin: 'bin',
|
|
1649
|
+
};
|
|
1650
|
+
const EXT_TO_TYPE = {
|
|
1651
|
+
png: 'png',
|
|
1652
|
+
jpg: 'jpg',
|
|
1653
|
+
jpeg: 'jpeg',
|
|
1654
|
+
webp: 'webp',
|
|
1655
|
+
json: 'json',
|
|
1656
|
+
tex: 'tex',
|
|
1657
|
+
ske: 'ske',
|
|
1658
|
+
mp3: 'audio',
|
|
1659
|
+
wav: 'audio',
|
|
1660
|
+
aac: 'audio',
|
|
1661
|
+
ogg: 'audio',
|
|
1662
|
+
mp4: 'video',
|
|
1663
|
+
webm: 'video',
|
|
1664
|
+
glb: 'glb',
|
|
1665
|
+
gltf: 'gltf',
|
|
1666
|
+
fbx: 'fbx',
|
|
1667
|
+
obj: 'obj',
|
|
1668
|
+
mtl: 'mtl',
|
|
1669
|
+
stl: 'stl',
|
|
1670
|
+
dae: 'dae',
|
|
1671
|
+
ply: 'ply',
|
|
1672
|
+
bin: 'bin',
|
|
1673
|
+
};
|
|
1674
|
+
function extensionOf(url) {
|
|
1675
|
+
const path = url.split('?')[0].split('#')[0];
|
|
1676
|
+
const dot = path.lastIndexOf('.');
|
|
1677
|
+
if (dot < 0)
|
|
1678
|
+
return '';
|
|
1679
|
+
return path.slice(dot + 1).toLowerCase();
|
|
1680
|
+
}
|
|
1681
|
+
function typeFromUrl(url, slot) {
|
|
1682
|
+
return EXT_TO_TYPE[extensionOf(url)] || SLOT_DEFAULT_TYPE[slot] || 'png';
|
|
1683
|
+
}
|
|
1684
|
+
function defaultSlotForResourceType(resourceType) {
|
|
1685
|
+
if (resourceType === 'AUDIO')
|
|
1686
|
+
return 'audio';
|
|
1687
|
+
if (resourceType === 'VIDEO')
|
|
1688
|
+
return 'video';
|
|
1689
|
+
if (resourceType === 'MODEL' || resourceType === 'GLB')
|
|
1690
|
+
return 'model';
|
|
1691
|
+
return 'image';
|
|
1692
|
+
}
|
|
1693
|
+
function wrapSlot(slot, value, resourceName) {
|
|
1694
|
+
if (typeof value === 'string') {
|
|
1695
|
+
const url = value.trim();
|
|
1696
|
+
if (!url) {
|
|
1697
|
+
throw missingUrlError(resourceName, slot);
|
|
1698
|
+
}
|
|
1699
|
+
return { type: typeFromUrl(url, slot), url };
|
|
1700
|
+
}
|
|
1701
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
1702
|
+
throw new Error(`Resource "${resourceName}" src.${slot} must be a url string or { type, url }.`);
|
|
1703
|
+
}
|
|
1704
|
+
const slotValue = value;
|
|
1705
|
+
if (slotValue.type === 'data') {
|
|
1706
|
+
return slotValue;
|
|
1707
|
+
}
|
|
1708
|
+
const url = typeof slotValue.url === 'string' ? slotValue.url.trim() : '';
|
|
1709
|
+
if (!url) {
|
|
1710
|
+
throw missingUrlError(resourceName, slot);
|
|
1711
|
+
}
|
|
1712
|
+
return {
|
|
1713
|
+
...slotValue,
|
|
1714
|
+
type: slotValue.type || typeFromUrl(url, slot),
|
|
1715
|
+
url,
|
|
1716
|
+
};
|
|
1717
|
+
}
|
|
1718
|
+
function missingUrlError(resourceName, slot) {
|
|
1719
|
+
return new Error(`Resource "${resourceName}" src.${slot}.url is required. ` +
|
|
1720
|
+
`Use { type, url } (e.g. { type: "webp", url: "https://..." }). ` +
|
|
1721
|
+
`A flat path string is also accepted and will be normalized.`);
|
|
1722
|
+
}
|
|
1723
|
+
/**
|
|
1724
|
+
* Accept the documented `{ type, url }` slots, plus the common guesses
|
|
1725
|
+
* `src: "file.png"` and `src: { image: "a.webp", json: "a.json" }`.
|
|
1726
|
+
*/
|
|
1727
|
+
function normalizeResourceSrc(src, resourceType, resourceName = '(unnamed)') {
|
|
1728
|
+
if (src == null) {
|
|
1729
|
+
throw new Error(`Resource "${resourceName}" src is required.`);
|
|
1730
|
+
}
|
|
1731
|
+
if (typeof src === 'string') {
|
|
1732
|
+
const slot = defaultSlotForResourceType(resourceType);
|
|
1733
|
+
return { [slot]: wrapSlot(slot, src, resourceName) };
|
|
1734
|
+
}
|
|
1735
|
+
if (typeof src !== 'object' || Array.isArray(src)) {
|
|
1736
|
+
throw new Error(`Resource "${resourceName}" src must be a url string or a slot object.`);
|
|
1737
|
+
}
|
|
1738
|
+
const out = {};
|
|
1739
|
+
for (const [slot, value] of Object.entries(src)) {
|
|
1740
|
+
if (value == null)
|
|
1741
|
+
continue;
|
|
1742
|
+
out[slot] = wrapSlot(slot, value, resourceName);
|
|
1743
|
+
}
|
|
1744
|
+
if (Object.keys(out).length === 0) {
|
|
1745
|
+
throw new Error(`Resource "${resourceName}" src has no loadable slots.`);
|
|
1746
|
+
}
|
|
1747
|
+
return out;
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1639
1750
|
const resourceLoader = {
|
|
1640
1751
|
AbstractLoadStrategy,
|
|
1641
1752
|
AudioLoadStrategy,
|
|
@@ -1650,6 +1761,102 @@ const resourceLoader = {
|
|
|
1650
1761
|
ResourceState
|
|
1651
1762
|
};
|
|
1652
1763
|
|
|
1764
|
+
function isFrameMap(frames) {
|
|
1765
|
+
return !!frames && typeof frames === 'object' && !Array.isArray(frames);
|
|
1766
|
+
}
|
|
1767
|
+
function frameFromPackedItem(item) {
|
|
1768
|
+
const frame = item.frame;
|
|
1769
|
+
if (!frame || typeof frame !== 'object')
|
|
1770
|
+
return null;
|
|
1771
|
+
return {
|
|
1772
|
+
...item,
|
|
1773
|
+
frame: frame,
|
|
1774
|
+
rotated: Boolean(item.rotated),
|
|
1775
|
+
trimmed: Boolean(item.trimmed),
|
|
1776
|
+
spriteSourceSize: item.spriteSourceSize,
|
|
1777
|
+
sourceSize: item.sourceSize,
|
|
1778
|
+
};
|
|
1779
|
+
}
|
|
1780
|
+
function collectArrayFrames(list, frames, animations) {
|
|
1781
|
+
for (const raw of list) {
|
|
1782
|
+
if (!raw || typeof raw !== 'object')
|
|
1783
|
+
continue;
|
|
1784
|
+
const item = raw;
|
|
1785
|
+
const name = String(item.filename || item.name || '');
|
|
1786
|
+
if (!name)
|
|
1787
|
+
continue;
|
|
1788
|
+
const packed = frameFromPackedItem(item);
|
|
1789
|
+
if (!packed)
|
|
1790
|
+
continue;
|
|
1791
|
+
frames[name] = packed;
|
|
1792
|
+
const slash = name.lastIndexOf('/');
|
|
1793
|
+
if (slash > 0) {
|
|
1794
|
+
const anim = name.slice(0, slash);
|
|
1795
|
+
if (!animations[anim])
|
|
1796
|
+
animations[anim] = [];
|
|
1797
|
+
if (!animations[anim].includes(name))
|
|
1798
|
+
animations[anim].push(name);
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
/**
|
|
1803
|
+
* Pixi `Spritesheet` reads `data.meta.scale` and a name→frame `frames` map.
|
|
1804
|
+
* TexturePacker multi-atlas (`textures[].frames` as an array) is accepted and
|
|
1805
|
+
* rewritten to that hash. Always returns a `meta.scale` so construction cannot
|
|
1806
|
+
* throw `Cannot read properties of undefined (reading 'scale')`.
|
|
1807
|
+
*/
|
|
1808
|
+
function normalizeSpritesheetData(raw) {
|
|
1809
|
+
if (!raw || typeof raw !== 'object') {
|
|
1810
|
+
return { frames: {}, animations: {}, meta: { scale: 1 } };
|
|
1811
|
+
}
|
|
1812
|
+
const json = raw;
|
|
1813
|
+
if (isFrameMap(json.frames)) {
|
|
1814
|
+
return {
|
|
1815
|
+
...json,
|
|
1816
|
+
frames: json.frames,
|
|
1817
|
+
animations: { ...(json.animations || {}) },
|
|
1818
|
+
meta: { scale: 1, ...(json.meta || {}) },
|
|
1819
|
+
};
|
|
1820
|
+
}
|
|
1821
|
+
const frames = {};
|
|
1822
|
+
const animations = { ...(json.animations || {}) };
|
|
1823
|
+
if (Array.isArray(json.textures)) {
|
|
1824
|
+
for (const sheet of json.textures) {
|
|
1825
|
+
if (!sheet || typeof sheet !== 'object')
|
|
1826
|
+
continue;
|
|
1827
|
+
if (Array.isArray(sheet.frames)) {
|
|
1828
|
+
collectArrayFrames(sheet.frames, frames, animations);
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
const first = json.textures[0] || {};
|
|
1832
|
+
const scale = first.scale ?? json.meta?.scale ?? 1;
|
|
1833
|
+
return {
|
|
1834
|
+
frames,
|
|
1835
|
+
animations,
|
|
1836
|
+
meta: {
|
|
1837
|
+
scale: typeof scale === 'number' || typeof scale === 'string' ? scale : 1,
|
|
1838
|
+
image: typeof first.image === 'string' ? first.image : undefined,
|
|
1839
|
+
size: first.size,
|
|
1840
|
+
format: first.format,
|
|
1841
|
+
...(json.meta || {}),
|
|
1842
|
+
},
|
|
1843
|
+
};
|
|
1844
|
+
}
|
|
1845
|
+
if (Array.isArray(json.frames)) {
|
|
1846
|
+
collectArrayFrames(json.frames, frames, animations);
|
|
1847
|
+
return {
|
|
1848
|
+
frames,
|
|
1849
|
+
animations,
|
|
1850
|
+
meta: { scale: 1, ...(json.meta || {}) },
|
|
1851
|
+
};
|
|
1852
|
+
}
|
|
1853
|
+
return {
|
|
1854
|
+
frames: {},
|
|
1855
|
+
animations,
|
|
1856
|
+
meta: { scale: 1, ...(json.meta || {}) },
|
|
1857
|
+
};
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1653
1860
|
/** Resource type */
|
|
1654
1861
|
var RESOURCE_TYPE;
|
|
1655
1862
|
(function (RESOURCE_TYPE) {
|
|
@@ -1659,6 +1866,7 @@ var RESOURCE_TYPE;
|
|
|
1659
1866
|
RESOURCE_TYPE["AUDIO"] = "AUDIO";
|
|
1660
1867
|
RESOURCE_TYPE["VIDEO"] = "VIDEO";
|
|
1661
1868
|
RESOURCE_TYPE["GLB"] = "GLB";
|
|
1869
|
+
RESOURCE_TYPE["MODEL"] = "MODEL";
|
|
1662
1870
|
})(RESOURCE_TYPE || (RESOURCE_TYPE = {}));
|
|
1663
1871
|
XhrLoadStrategy.setExtensionXhrType('json', XhrResponseType.Json);
|
|
1664
1872
|
XhrLoadStrategy.setExtensionXhrType('tex', XhrResponseType.Json);
|
|
@@ -1669,6 +1877,13 @@ XhrLoadStrategy.setExtensionXhrType('aac', XhrResponseType.Buffer);
|
|
|
1669
1877
|
XhrLoadStrategy.setExtensionXhrType('ogg', XhrResponseType.Buffer);
|
|
1670
1878
|
XhrLoadStrategy.setExtensionXhrType('glb', XhrResponseType.Buffer);
|
|
1671
1879
|
XhrLoadStrategy.setExtensionXhrType('gltf', XhrResponseType.Json);
|
|
1880
|
+
XhrLoadStrategy.setExtensionXhrType('fbx', XhrResponseType.Buffer);
|
|
1881
|
+
XhrLoadStrategy.setExtensionXhrType('stl', XhrResponseType.Buffer);
|
|
1882
|
+
XhrLoadStrategy.setExtensionXhrType('ply', XhrResponseType.Buffer);
|
|
1883
|
+
XhrLoadStrategy.setExtensionXhrType('bin', XhrResponseType.Buffer);
|
|
1884
|
+
XhrLoadStrategy.setExtensionXhrType('obj', XhrResponseType.Text);
|
|
1885
|
+
XhrLoadStrategy.setExtensionXhrType('mtl', XhrResponseType.Text);
|
|
1886
|
+
XhrLoadStrategy.setExtensionXhrType('dae', XhrResponseType.Text);
|
|
1672
1887
|
const RESOURCE_TYPE_STRATEGY = {
|
|
1673
1888
|
png: ImageLoadStrategy,
|
|
1674
1889
|
jpg: ImageLoadStrategy,
|
|
@@ -1681,6 +1896,13 @@ const RESOURCE_TYPE_STRATEGY = {
|
|
|
1681
1896
|
video: VideoLoadStrategy,
|
|
1682
1897
|
glb: XhrLoadStrategy,
|
|
1683
1898
|
gltf: XhrLoadStrategy,
|
|
1899
|
+
fbx: XhrLoadStrategy,
|
|
1900
|
+
obj: XhrLoadStrategy,
|
|
1901
|
+
mtl: XhrLoadStrategy,
|
|
1902
|
+
stl: XhrLoadStrategy,
|
|
1903
|
+
dae: XhrLoadStrategy,
|
|
1904
|
+
ply: XhrLoadStrategy,
|
|
1905
|
+
bin: XhrLoadStrategy,
|
|
1684
1906
|
};
|
|
1685
1907
|
/**
|
|
1686
1908
|
* Resource manager
|
|
@@ -1727,8 +1949,11 @@ class Resource extends EventEmitter {
|
|
|
1727
1949
|
console.warn(res.name + ' was already added');
|
|
1728
1950
|
continue;
|
|
1729
1951
|
}
|
|
1730
|
-
this.resourcesMap[res.name] =
|
|
1731
|
-
|
|
1952
|
+
this.resourcesMap[res.name] = {
|
|
1953
|
+
...res,
|
|
1954
|
+
src: normalizeResourceSrc(res.src, String(res.type), res.name),
|
|
1955
|
+
data: {},
|
|
1956
|
+
};
|
|
1732
1957
|
}
|
|
1733
1958
|
}
|
|
1734
1959
|
/** dd resource preprocesser*/
|
|
@@ -1817,6 +2042,7 @@ class Resource extends EventEmitter {
|
|
|
1817
2042
|
for (const handler of this.preProcessResourceHandlers) {
|
|
1818
2043
|
handler(res);
|
|
1819
2044
|
}
|
|
2045
|
+
res.src = normalizeResourceSrc(res.src, String(res.type), res.name);
|
|
1820
2046
|
for (const key in res.src) {
|
|
1821
2047
|
const resourceType = res.src[key].type;
|
|
1822
2048
|
if (resourceType === 'data') {
|
|
@@ -1926,5 +2152,5 @@ const decorators = {
|
|
|
1926
2152
|
};
|
|
1927
2153
|
console.log(`@combos-fun/engine version: ${version}`);
|
|
1928
2154
|
|
|
1929
|
-
export { COMBOS_GAME_PLUGIN_INIT_SUCCESS, COMBOS_GAME_READY, COMBOS_GAME_SET_PLAYING, COMBOS_GAME_STATE_CHANGED, Component, DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, Game, GameObject, IDEProp, LOAD_EVENT, LOAD_SCENE_MODE, ObserverType as OBSERVER_TYPE, RESOURCE_TYPE, RESOURCE_TYPE_STRATEGY, Scene, System, Transform, componentObserver, decorators, isAllowedMessageOrigin, mergeAllowedMessageOrigins, parseSetPlayingMessage, postParentGameReady, postParentGameState, postParentPluginInitSuccess, resource, resourceLoader, version };
|
|
2155
|
+
export { COMBOS_GAME_PLUGIN_INIT_SUCCESS, COMBOS_GAME_READY, COMBOS_GAME_SET_PLAYING, COMBOS_GAME_STATE_CHANGED, Component, DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, Game, GameObject, IDEProp, LOAD_EVENT, LOAD_SCENE_MODE, ObserverType as OBSERVER_TYPE, RESOURCE_TYPE, RESOURCE_TYPE_STRATEGY, Scene, System, Transform, componentObserver, decorators, isAllowedMessageOrigin, mergeAllowedMessageOrigins, normalizeResourceSrc, normalizeSpritesheetData, parseSetPlayingMessage, postParentGameReady, postParentGameState, postParentPluginInitSuccess, resource, resourceLoader, version };
|
|
1930
2156
|
//# sourceMappingURL=engine.esm.js.map
|