@thewhateverapp/tile-sdk 0.15.3 → 0.15.5
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/bridge/TileBridge.d.ts +29 -0
- package/dist/bridge/TileBridge.d.ts.map +1 -1
- package/dist/bridge/TileBridge.js +78 -0
- package/dist/excalibur/index.d.ts +48 -0
- package/dist/excalibur/index.d.ts.map +1 -0
- package/dist/excalibur/index.js +51 -0
- package/dist/react/ExcaliburGame.d.ts +109 -0
- package/dist/react/ExcaliburGame.d.ts.map +1 -0
- package/dist/react/ExcaliburGame.js +215 -0
- package/dist/react/index.js +3 -3
- package/dist/scene/index.d.ts +3 -41
- package/dist/scene/index.d.ts.map +1 -1
- package/dist/scene/index.js +1 -49
- package/dist/spec/schema.d.ts +12 -12
- package/package.json +7 -7
- package/dist/pixi/index.d.ts +0 -43
- package/dist/pixi/index.d.ts.map +0 -1
- package/dist/pixi/index.js +0 -46
- package/dist/react/PixiGame.d.ts +0 -138
- package/dist/react/PixiGame.d.ts.map +0 -1
- package/dist/react/PixiGame.js +0 -237
- package/dist/scene/SceneContext.d.ts +0 -173
- package/dist/scene/SceneContext.d.ts.map +0 -1
- package/dist/scene/SceneContext.js +0 -89
- package/dist/scene/SceneFromJson.d.ts +0 -34
- package/dist/scene/SceneFromJson.d.ts.map +0 -1
- package/dist/scene/SceneFromJson.js +0 -97
- package/dist/scene/SceneRenderer.d.ts +0 -29
- package/dist/scene/SceneRenderer.d.ts.map +0 -1
- package/dist/scene/SceneRenderer.js +0 -312
- package/dist/scene/camera/CameraController.d.ts +0 -6
- package/dist/scene/camera/CameraController.d.ts.map +0 -1
- package/dist/scene/camera/CameraController.js +0 -90
- package/dist/scene/components/ComponentRunner.d.ts +0 -22
- package/dist/scene/components/ComponentRunner.d.ts.map +0 -1
- package/dist/scene/components/ComponentRunner.js +0 -210
- package/dist/scene/effects/GlowFilter.d.ts +0 -38
- package/dist/scene/effects/GlowFilter.d.ts.map +0 -1
- package/dist/scene/effects/GlowFilter.js +0 -40
- package/dist/scene/effects/ParticleSystem.d.ts +0 -52
- package/dist/scene/effects/ParticleSystem.d.ts.map +0 -1
- package/dist/scene/effects/ParticleSystem.js +0 -107
- package/dist/scene/entities/EntityGraphics.d.ts +0 -26
- package/dist/scene/entities/EntityGraphics.d.ts.map +0 -1
- package/dist/scene/entities/EntityGraphics.js +0 -226
- package/dist/scene/input/InputManager.d.ts +0 -18
- package/dist/scene/input/InputManager.d.ts.map +0 -1
- package/dist/scene/input/InputManager.js +0 -86
- package/dist/scene/physics/PhysicsEngine.d.ts +0 -15
- package/dist/scene/physics/PhysicsEngine.d.ts.map +0 -1
- package/dist/scene/physics/PhysicsEngine.js +0 -260
- package/dist/scene/timeline/TimelineExecutor.d.ts +0 -6
- package/dist/scene/timeline/TimelineExecutor.d.ts.map +0 -1
- package/dist/scene/timeline/TimelineExecutor.js +0 -241
|
@@ -107,6 +107,11 @@ export declare class TileBridge {
|
|
|
107
107
|
* Handle keyboard state message from parent (mobile app)
|
|
108
108
|
*/
|
|
109
109
|
private handleKeyboard;
|
|
110
|
+
/**
|
|
111
|
+
* Handle audio status request from parent
|
|
112
|
+
* Returns actual muted state of all media for verification
|
|
113
|
+
*/
|
|
114
|
+
private handleAudioStatusRequest;
|
|
110
115
|
/**
|
|
111
116
|
* Handle visibility state message from parent (mobile app)
|
|
112
117
|
* Used for TikTok-style feeds where tiles are preloaded but not visible
|
|
@@ -381,6 +386,30 @@ export declare class TileBridge {
|
|
|
381
386
|
* Unregister an AudioContext (e.g., when closing it)
|
|
382
387
|
*/
|
|
383
388
|
unregisterAudioContext(ctx: AudioContext): void;
|
|
389
|
+
/**
|
|
390
|
+
* Get actual audio status of all media elements and AudioContexts.
|
|
391
|
+
* This reports the ACTUAL muted state, not just what the parent requested.
|
|
392
|
+
* Useful for debugging race conditions.
|
|
393
|
+
*/
|
|
394
|
+
getActualAudioStatus(): {
|
|
395
|
+
expectedMuted: boolean;
|
|
396
|
+
mediaElements: Array<{
|
|
397
|
+
tagName: string;
|
|
398
|
+
src: string;
|
|
399
|
+
muted: boolean;
|
|
400
|
+
paused: boolean;
|
|
401
|
+
}>;
|
|
402
|
+
audioContexts: Array<{
|
|
403
|
+
state: AudioContextState;
|
|
404
|
+
}>;
|
|
405
|
+
allMuted: boolean;
|
|
406
|
+
mismatch: boolean;
|
|
407
|
+
};
|
|
408
|
+
/**
|
|
409
|
+
* Force re-sync audio state to match visibility.
|
|
410
|
+
* Call this if getActualAudioStatus() shows a mismatch.
|
|
411
|
+
*/
|
|
412
|
+
forceSyncAudioState(): void;
|
|
384
413
|
/**
|
|
385
414
|
* Wait for ready state
|
|
386
415
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TileBridge.d.ts","sourceRoot":"","sources":["../../src/bridge/TileBridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,iGAAiG;IACjG,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAGD,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC;AAEF,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,gBAAgB,CAAmD;IAC3E,OAAO,CAAC,aAAa,CAAoD;IACzE,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAA2B;IAGzC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,cAAc,CAAqB;IAG3C,OAAO,CAAC,aAAa,CAAgD;IAMrE,OAAO,CAAC,eAAe,CAAmD;IAG1E,OAAO,CAAC,yBAAyB,CAAkB;IAGnD,OAAO,CAAC,uBAAuB,CAAqD;IAEpF,OAAO,CAAC,oBAAoB,CAAgC;IAC5D,OAAO,CAAC,mBAAmB,CAAkB;IAG7C,OAAO,CAAC,sBAAsB,CAAa;IAC3C,OAAO,CAAC,wBAAwB,CAAkB;IAClD,OAAO,CAAC,yBAAyB,CAAuE;IACxG,OAAO,CAAC,qBAAqB,CAA8C;IAC3E,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAO;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAO;IAGnC,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,cAAc,CAAwB;gBAElC,cAAc,GAAE,MAAkC,EAAE,MAAM,CAAC,EAAE,UAAU;IAiCnF,OAAO,CAAC,UAAU;IA4ClB;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAwDnC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA0C7B;;OAEG;IACH,OAAO,CAAC,aAAa;IA+BrB;;OAEG;IACH,OAAO,CAAC,cAAc;IAgCtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAuBtB,OAAO,CAAC,aAAa;
|
|
1
|
+
{"version":3,"file":"TileBridge.d.ts","sourceRoot":"","sources":["../../src/bridge/TileBridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,iGAAiG;IACjG,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAGD,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC;AAEF,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,gBAAgB,CAAmD;IAC3E,OAAO,CAAC,aAAa,CAAoD;IACzE,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAA2B;IAGzC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,cAAc,CAAqB;IAG3C,OAAO,CAAC,aAAa,CAAgD;IAMrE,OAAO,CAAC,eAAe,CAAmD;IAG1E,OAAO,CAAC,yBAAyB,CAAkB;IAGnD,OAAO,CAAC,uBAAuB,CAAqD;IAEpF,OAAO,CAAC,oBAAoB,CAAgC;IAC5D,OAAO,CAAC,mBAAmB,CAAkB;IAG7C,OAAO,CAAC,sBAAsB,CAAa;IAC3C,OAAO,CAAC,wBAAwB,CAAkB;IAClD,OAAO,CAAC,yBAAyB,CAAuE;IACxG,OAAO,CAAC,qBAAqB,CAA8C;IAC3E,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAO;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAO;IAGnC,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,cAAc,CAAwB;gBAElC,cAAc,GAAE,MAAkC,EAAE,MAAM,CAAC,EAAE,UAAU;IAiCnF,OAAO,CAAC,UAAU;IA4ClB;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAwDnC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA0C7B;;OAEG;IACH,OAAO,CAAC,aAAa;IA+BrB;;OAEG;IACH,OAAO,CAAC,cAAc;IAgCtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAuBtB,OAAO,CAAC,aAAa;IAqErB,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,oBAAoB;IAoB5B;;OAEG;IACH,OAAO,CAAC,WAAW;IAuBnB;;OAEG;IACH,OAAO,CAAC,cAAc;IAkBtB;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAmBhC;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAoCxB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IA4CzB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA8C1B;;;;;;;OAOG;IACH,OAAO,CAAC,2BAA2B;IAoGnC;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAqCpB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAyCtB,OAAO,CAAC,YAAY;IAmCpB;;;;;OAKG;IACI,cAAc,IAAI,IAAI;IAoC7B;;;;OAIG;IACI,cAAc,IAAI,IAAI;IAkC7B;;;OAGG;IACI,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAI1C;;OAEG;IACI,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,QAAQ,GAAG,OAAkB,GAAG,IAAI;IAOxE;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAOtD;;;OAGG;IACI,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAOpD;;OAEG;IACU,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4B1D;;OAEG;IACU,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B/D;;OAEG;IACU,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAoBlD;;OAEG;IACI,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAOzD;;OAEG;IACU,OAAO,CAAC,OAAO,CAAC,EAAE;QAC7B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,GAAG,CAAC;IAiChB;;OAEG;IACU,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IA8B9D;;OAEG;IACU,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC;IAyB3C;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAoCzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAgCxB;;;;;OAKG;IACU,YAAY,CAAC,OAAO,CAAC,EAAE;QAClC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAC;KACvC,GAAG,OAAO,CAAC;QACV,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IA+CF;;;;;OAKG;IACU,UAAU,CAAC,OAAO,CAAC,EAAE;QAChC,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QACV,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IAwCF;;;;;OAKG;IACU,WAAW,CAAC,OAAO,CAAC,EAAE;QACjC,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,KAAK,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IA6CH;;OAEG;IACI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,MAAM,IAAI;IAgBlE;;OAEG;IACI,SAAS,IAAI,UAAU,GAAG,IAAI;IAIrC;;OAEG;IACI,OAAO,IAAI,OAAO;IAMzB;;;OAGG;IACI,QAAQ,IAAI,MAAM,GAAG,IAAI;IAWhC;;;OAGG;IACI,YAAY,IAAI,aAAa,GAAG,IAAI;IAU3C;;OAEG;IACI,aAAa,IAAI,OAAO;IAO/B;;;;OAIG;IACU,YAAY,CAAC,SAAS,GAAE,MAAc,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAyC5E;;;OAGG;IACI,aAAa,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,IAAI,CAAA;KAAE,KAAK,IAAI,GAAG,MAAM,IAAI;IAM7F;;;OAGG;IACI,gBAAgB,IAAI,aAAa;IAIxC;;OAEG;IACI,iBAAiB,IAAI,OAAO;IAInC;;OAEG;IACI,iBAAiB,IAAI,MAAM;IAIlC;;;;;OAKG;IACI,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,MAAM,IAAI;IAM5E;;;;OAIG;IACI,kBAAkB,IAAI,eAAe;IAI5C;;;OAGG;IACI,SAAS,IAAI,OAAO;IAI3B;;;;OAIG;IACI,OAAO,IAAI,OAAO;IAIzB;;;;;;;;;;OAUG;IACI,kBAAkB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GAAG,MAAM,IAAI;IAkBhF;;;;;;;;;;;;;;;OAeG;IACI,oBAAoB,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI;IAWpD;;OAEG;IACI,sBAAsB,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI;IAKtD;;;;OAIG;IACI,oBAAoB,IAAI;QAC7B,aAAa,EAAE,OAAO,CAAC;QACvB,aAAa,EAAE,KAAK,CAAC;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,OAAO,CAAC;YAAC,MAAM,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;QACxF,aAAa,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,iBAAiB,CAAA;SAAE,CAAC,CAAC;QACnD,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,OAAO,CAAC;KACnB;IAyCD;;;OAGG;IACI,mBAAmB,IAAI,IAAI;IASlC;;;;;OAKG;IACU,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC;IAuBhD,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,aAAa;CAwCtB;AAKD,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,UAAU,CAQ7D"}
|
|
@@ -310,6 +310,12 @@ export class TileBridge {
|
|
|
310
310
|
case 'parent:visibility':
|
|
311
311
|
this.handleVisibility(message.payload);
|
|
312
312
|
break;
|
|
313
|
+
case 'parent:request-audio-status':
|
|
314
|
+
this.handleAudioStatusRequest(message.id);
|
|
315
|
+
break;
|
|
316
|
+
case 'parent:force-audio-sync':
|
|
317
|
+
this.forceSyncAudioState();
|
|
318
|
+
break;
|
|
313
319
|
case 'parent:navigateToPage':
|
|
314
320
|
this.handleParentNavigate({ target: 'page' });
|
|
315
321
|
break;
|
|
@@ -403,6 +409,25 @@ export class TileBridge {
|
|
|
403
409
|
// Emit keyboard update event for listeners
|
|
404
410
|
this.emitEvent('keyboard:update', this.keyboardState);
|
|
405
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Handle audio status request from parent
|
|
414
|
+
* Returns actual muted state of all media for verification
|
|
415
|
+
*/
|
|
416
|
+
handleAudioStatusRequest(requestId) {
|
|
417
|
+
const status = this.getActualAudioStatus();
|
|
418
|
+
console.log('[TileBridge] 📊 Audio status requested:', status);
|
|
419
|
+
this.sendToParent({
|
|
420
|
+
type: 'tile:audio-status',
|
|
421
|
+
payload: status,
|
|
422
|
+
id: requestId,
|
|
423
|
+
});
|
|
424
|
+
// If there's a mismatch, log a warning and auto-fix
|
|
425
|
+
if (status.mismatch) {
|
|
426
|
+
console.warn('[TileBridge] ⚠️ AUDIO MISMATCH DETECTED! Expected:', status.expectedMuted, 'Actual:', status.allMuted);
|
|
427
|
+
console.warn('[TileBridge] 🔄 Auto-fixing mismatch...');
|
|
428
|
+
this.forceSyncAudioState();
|
|
429
|
+
}
|
|
430
|
+
}
|
|
406
431
|
/**
|
|
407
432
|
* Handle visibility state message from parent (mobile app)
|
|
408
433
|
* Used for TikTok-style feeds where tiles are preloaded but not visible
|
|
@@ -1423,6 +1448,59 @@ export class TileBridge {
|
|
|
1423
1448
|
this.trackedAudioContexts.delete(ctx);
|
|
1424
1449
|
console.log(`[TileBridge] 🎵 AudioContext unregistered (${this.trackedAudioContexts.size} remaining)`);
|
|
1425
1450
|
}
|
|
1451
|
+
/**
|
|
1452
|
+
* Get actual audio status of all media elements and AudioContexts.
|
|
1453
|
+
* This reports the ACTUAL muted state, not just what the parent requested.
|
|
1454
|
+
* Useful for debugging race conditions.
|
|
1455
|
+
*/
|
|
1456
|
+
getActualAudioStatus() {
|
|
1457
|
+
const expectedMuted = this.visibilityState.muted ?? true;
|
|
1458
|
+
const mediaElements = [];
|
|
1459
|
+
const audioContexts = [];
|
|
1460
|
+
// Check all media elements
|
|
1461
|
+
if (typeof document !== 'undefined') {
|
|
1462
|
+
const elements = document.querySelectorAll('video, audio');
|
|
1463
|
+
elements.forEach((el) => {
|
|
1464
|
+
const media = el;
|
|
1465
|
+
mediaElements.push({
|
|
1466
|
+
tagName: media.tagName.toLowerCase(),
|
|
1467
|
+
src: media.src?.slice(-50) || 'no-src',
|
|
1468
|
+
muted: media.muted,
|
|
1469
|
+
paused: media.paused,
|
|
1470
|
+
});
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
// Check all AudioContexts
|
|
1474
|
+
this.trackedAudioContexts.forEach((ctx) => {
|
|
1475
|
+
audioContexts.push({ state: ctx.state });
|
|
1476
|
+
});
|
|
1477
|
+
// Determine if all audio is actually muted
|
|
1478
|
+
const allMediaMuted = mediaElements.every((m) => m.muted || m.paused);
|
|
1479
|
+
const allContextsSuspended = audioContexts.every((c) => c.state === 'suspended' || c.state === 'closed');
|
|
1480
|
+
const allMuted = allMediaMuted && allContextsSuspended;
|
|
1481
|
+
// Check for mismatch between expected and actual
|
|
1482
|
+
const mismatch = expectedMuted !== allMuted;
|
|
1483
|
+
return {
|
|
1484
|
+
expectedMuted,
|
|
1485
|
+
mediaElements,
|
|
1486
|
+
audioContexts,
|
|
1487
|
+
allMuted,
|
|
1488
|
+
mismatch,
|
|
1489
|
+
};
|
|
1490
|
+
}
|
|
1491
|
+
/**
|
|
1492
|
+
* Force re-sync audio state to match visibility.
|
|
1493
|
+
* Call this if getActualAudioStatus() shows a mismatch.
|
|
1494
|
+
*/
|
|
1495
|
+
forceSyncAudioState() {
|
|
1496
|
+
console.log('[TileBridge] 🔄 Force syncing audio state');
|
|
1497
|
+
if (this.visibilityState.muted) {
|
|
1498
|
+
this.muteAllMedia();
|
|
1499
|
+
}
|
|
1500
|
+
else {
|
|
1501
|
+
this.unmuteAllMedia();
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1426
1504
|
/**
|
|
1427
1505
|
* Wait for ready state
|
|
1428
1506
|
*
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Excalibur.js game components for tile-sdk
|
|
3
|
+
*
|
|
4
|
+
* Import from '@thewhateverapp/tile-sdk/excalibur' to use Excalibur.js features.
|
|
5
|
+
* Excalibur is a modern 2D game engine with built-in physics, collision detection,
|
|
6
|
+
* and a robust entity-component system.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* import { ExcaliburGame, useEngine, useGameLoop } from '@thewhateverapp/tile-sdk/excalibur';
|
|
11
|
+
* import { Actor, Color, Vector } from 'excalibur';
|
|
12
|
+
*
|
|
13
|
+
* function MyGame() {
|
|
14
|
+
* return (
|
|
15
|
+
* <ExcaliburGame width={256} height={554}>
|
|
16
|
+
* <GameContent />
|
|
17
|
+
* </ExcaliburGame>
|
|
18
|
+
* );
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* function GameContent() {
|
|
22
|
+
* const engine = useEngine();
|
|
23
|
+
*
|
|
24
|
+
* useEffect(() => {
|
|
25
|
+
* if (!engine) return;
|
|
26
|
+
* const actor = new Actor({
|
|
27
|
+
* pos: new Vector(100, 100),
|
|
28
|
+
* width: 50,
|
|
29
|
+
* height: 50,
|
|
30
|
+
* color: Color.Red
|
|
31
|
+
* });
|
|
32
|
+
* engine.currentScene.add(actor);
|
|
33
|
+
* return () => {
|
|
34
|
+
* engine.currentScene.remove(actor);
|
|
35
|
+
* };
|
|
36
|
+
* }, [engine]);
|
|
37
|
+
*
|
|
38
|
+
* useGameLoop((delta) => {
|
|
39
|
+
* // Game logic runs every frame (delta is in milliseconds)
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* return null;
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export { ExcaliburGame, useEngine, useScene, useGameLoop, useGameState, useGameInput, Actor, Vector, Color, Rectangle, Circle, Label, Text, Sprite, TILE_WIDTH, TILE_HEIGHT, } from '../react/ExcaliburGame.js';
|
|
47
|
+
export type { ExcaliburGameProps } from '../react/ExcaliburGame.js';
|
|
48
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/excalibur/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,OAAO,EACL,aAAa,EACb,SAAS,EACT,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,YAAY,EAEZ,KAAK,EACL,MAAM,EACN,KAAK,EACL,SAAS,EACT,MAAM,EACN,KAAK,EACL,IAAI,EACJ,MAAM,EAEN,UAAU,EACV,WAAW,GACZ,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
/**
|
|
3
|
+
* Excalibur.js game components for tile-sdk
|
|
4
|
+
*
|
|
5
|
+
* Import from '@thewhateverapp/tile-sdk/excalibur' to use Excalibur.js features.
|
|
6
|
+
* Excalibur is a modern 2D game engine with built-in physics, collision detection,
|
|
7
|
+
* and a robust entity-component system.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import { ExcaliburGame, useEngine, useGameLoop } from '@thewhateverapp/tile-sdk/excalibur';
|
|
12
|
+
* import { Actor, Color, Vector } from 'excalibur';
|
|
13
|
+
*
|
|
14
|
+
* function MyGame() {
|
|
15
|
+
* return (
|
|
16
|
+
* <ExcaliburGame width={256} height={554}>
|
|
17
|
+
* <GameContent />
|
|
18
|
+
* </ExcaliburGame>
|
|
19
|
+
* );
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* function GameContent() {
|
|
23
|
+
* const engine = useEngine();
|
|
24
|
+
*
|
|
25
|
+
* useEffect(() => {
|
|
26
|
+
* if (!engine) return;
|
|
27
|
+
* const actor = new Actor({
|
|
28
|
+
* pos: new Vector(100, 100),
|
|
29
|
+
* width: 50,
|
|
30
|
+
* height: 50,
|
|
31
|
+
* color: Color.Red
|
|
32
|
+
* });
|
|
33
|
+
* engine.currentScene.add(actor);
|
|
34
|
+
* return () => {
|
|
35
|
+
* engine.currentScene.remove(actor);
|
|
36
|
+
* };
|
|
37
|
+
* }, [engine]);
|
|
38
|
+
*
|
|
39
|
+
* useGameLoop((delta) => {
|
|
40
|
+
* // Game logic runs every frame (delta is in milliseconds)
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* return null;
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export { ExcaliburGame, useEngine, useScene, useGameLoop, useGameState, useGameInput,
|
|
48
|
+
// Re-exported Excalibur classes
|
|
49
|
+
Actor, Vector, Color, Rectangle, Circle, Label, Text, Sprite,
|
|
50
|
+
// Constants
|
|
51
|
+
TILE_WIDTH, TILE_HEIGHT, } from '../react/ExcaliburGame.js';
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ExcaliburGame - Excalibur.js integration for React
|
|
3
|
+
*
|
|
4
|
+
* This component creates an Excalibur Engine imperatively and provides
|
|
5
|
+
* it via React context for game development.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { ExcaliburGame, useEngine, useGameLoop } from '@thewhateverapp/tile-sdk/excalibur';
|
|
10
|
+
* import { Actor, Color, Vector } from 'excalibur';
|
|
11
|
+
*
|
|
12
|
+
* function MyGame() {
|
|
13
|
+
* return (
|
|
14
|
+
* <ExcaliburGame>
|
|
15
|
+
* <GameContent />
|
|
16
|
+
* </ExcaliburGame>
|
|
17
|
+
* );
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* function GameContent() {
|
|
21
|
+
* const engine = useEngine();
|
|
22
|
+
*
|
|
23
|
+
* useEffect(() => {
|
|
24
|
+
* if (!engine) return;
|
|
25
|
+
* const actor = new Actor({
|
|
26
|
+
* pos: new Vector(100, 100),
|
|
27
|
+
* width: 50,
|
|
28
|
+
* height: 50,
|
|
29
|
+
* color: Color.Red
|
|
30
|
+
* });
|
|
31
|
+
* engine.currentScene.add(actor);
|
|
32
|
+
* return () => {
|
|
33
|
+
* engine.currentScene.remove(actor);
|
|
34
|
+
* };
|
|
35
|
+
* }, [engine]);
|
|
36
|
+
*
|
|
37
|
+
* useGameLoop((delta) => {
|
|
38
|
+
* // Game logic runs every frame
|
|
39
|
+
* });
|
|
40
|
+
*
|
|
41
|
+
* return null; // No React children needed - Excalibur manages rendering
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
import React, { type ReactNode } from 'react';
|
|
46
|
+
import { Engine, DisplayMode, type Scene } from 'excalibur';
|
|
47
|
+
export { Actor, Vector, Color, Rectangle, Circle, Label, Text, Sprite } from 'excalibur';
|
|
48
|
+
/**
|
|
49
|
+
* Tile dimensions - standard tile size
|
|
50
|
+
*/
|
|
51
|
+
export declare const TILE_WIDTH = 256;
|
|
52
|
+
export declare const TILE_HEIGHT = 554;
|
|
53
|
+
/**
|
|
54
|
+
* Hook to get the Excalibur Engine
|
|
55
|
+
*/
|
|
56
|
+
export declare function useEngine(): Engine | null;
|
|
57
|
+
/**
|
|
58
|
+
* Hook to get the current scene
|
|
59
|
+
*/
|
|
60
|
+
export declare function useScene(): Scene | null;
|
|
61
|
+
/**
|
|
62
|
+
* useGameLoop - Run a callback every frame
|
|
63
|
+
*
|
|
64
|
+
* @param callback - Function called every frame with delta time (in ms)
|
|
65
|
+
* @param enabled - Whether the loop is active (default: true)
|
|
66
|
+
*/
|
|
67
|
+
export declare function useGameLoop(callback: (delta: number) => void, enabled?: boolean): void;
|
|
68
|
+
export interface ExcaliburGameProps {
|
|
69
|
+
children: ReactNode;
|
|
70
|
+
/** Width in pixels (default: 256 for tile) */
|
|
71
|
+
width?: number;
|
|
72
|
+
/** Height in pixels (default: 554 for tile) */
|
|
73
|
+
height?: number;
|
|
74
|
+
/** Background color (CSS color string, default: black) */
|
|
75
|
+
backgroundColor?: string;
|
|
76
|
+
/** Display mode (default: FitScreen) */
|
|
77
|
+
displayMode?: DisplayMode;
|
|
78
|
+
/** Game options */
|
|
79
|
+
options?: {
|
|
80
|
+
antialiasing?: boolean;
|
|
81
|
+
pixelArt?: boolean;
|
|
82
|
+
suppressPlayButton?: boolean;
|
|
83
|
+
};
|
|
84
|
+
/** Whether game is paused */
|
|
85
|
+
paused?: boolean;
|
|
86
|
+
/** Callback when Engine is ready */
|
|
87
|
+
onMount?: (engine: Engine) => void;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* ExcaliburGame - Main wrapper component for Excalibur.js games
|
|
91
|
+
*
|
|
92
|
+
* Creates an Excalibur Engine and provides it via context.
|
|
93
|
+
* Children can use useEngine() to access the engine and add actors/entities.
|
|
94
|
+
*/
|
|
95
|
+
export declare function ExcaliburGame({ children, width, height, backgroundColor, displayMode, options, paused, onMount, }: ExcaliburGameProps): React.JSX.Element;
|
|
96
|
+
/**
|
|
97
|
+
* useGameState - Helper for managing game state with refs
|
|
98
|
+
*
|
|
99
|
+
* Returns a ref and a forceUpdate function for when you need to trigger re-renders.
|
|
100
|
+
* Use refs for continuous game state (position, velocity) to avoid re-render loops.
|
|
101
|
+
*/
|
|
102
|
+
export declare function useGameState<T extends object>(initialState: T): [React.MutableRefObject<T>, () => void];
|
|
103
|
+
/**
|
|
104
|
+
* useGameInput - Simple keyboard input hook for games
|
|
105
|
+
*
|
|
106
|
+
* Returns a ref with currently pressed keys.
|
|
107
|
+
*/
|
|
108
|
+
export declare function useGameInput(): React.MutableRefObject<Record<string, boolean>>;
|
|
109
|
+
//# sourceMappingURL=ExcaliburGame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExcaliburGame.d.ts","sourceRoot":"","sources":["../../src/react/ExcaliburGame.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,MAAM,EAAE,WAAW,EAAoB,KAAK,KAAK,EAAE,MAAM,WAAW,CAAC;AAG9E,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEzF;;GAEG;AACH,eAAO,MAAM,UAAU,MAAM,CAAC;AAC9B,eAAO,MAAM,WAAW,MAAM,CAAC;AAY/B;;GAEG;AACH,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAMzC;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,KAAK,GAAG,IAAI,CAGvC;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,OAAO,GAAE,OAAc,QAexB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,SAAS,CAAC;IACpB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wCAAwC;IACxC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,mBAAmB;IACnB,OAAO,CAAC,EAAE;QACR,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B,CAAC;IACF,6BAA6B;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,KAAkB,EAClB,MAAoB,EACpB,eAA2B,EAC3B,WAA+B,EAC/B,OAAY,EACZ,MAAc,EACd,OAAO,GACR,EAAE,kBAAkB,qBA+FpB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC3C,YAAY,EAAE,CAAC,GACd,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CASzC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,oDAwB3B"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
/**
|
|
3
|
+
* ExcaliburGame - Excalibur.js integration for React
|
|
4
|
+
*
|
|
5
|
+
* This component creates an Excalibur Engine imperatively and provides
|
|
6
|
+
* it via React context for game development.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* import { ExcaliburGame, useEngine, useGameLoop } from '@thewhateverapp/tile-sdk/excalibur';
|
|
11
|
+
* import { Actor, Color, Vector } from 'excalibur';
|
|
12
|
+
*
|
|
13
|
+
* function MyGame() {
|
|
14
|
+
* return (
|
|
15
|
+
* <ExcaliburGame>
|
|
16
|
+
* <GameContent />
|
|
17
|
+
* </ExcaliburGame>
|
|
18
|
+
* );
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* function GameContent() {
|
|
22
|
+
* const engine = useEngine();
|
|
23
|
+
*
|
|
24
|
+
* useEffect(() => {
|
|
25
|
+
* if (!engine) return;
|
|
26
|
+
* const actor = new Actor({
|
|
27
|
+
* pos: new Vector(100, 100),
|
|
28
|
+
* width: 50,
|
|
29
|
+
* height: 50,
|
|
30
|
+
* color: Color.Red
|
|
31
|
+
* });
|
|
32
|
+
* engine.currentScene.add(actor);
|
|
33
|
+
* return () => {
|
|
34
|
+
* engine.currentScene.remove(actor);
|
|
35
|
+
* };
|
|
36
|
+
* }, [engine]);
|
|
37
|
+
*
|
|
38
|
+
* useGameLoop((delta) => {
|
|
39
|
+
* // Game logic runs every frame
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* return null; // No React children needed - Excalibur manages rendering
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
import React, { createContext, useContext, useRef, useEffect, useState, useCallback, } from 'react';
|
|
47
|
+
import { Engine, DisplayMode, Color as ExColor } from 'excalibur';
|
|
48
|
+
// Re-export Excalibur classes for convenience
|
|
49
|
+
export { Actor, Vector, Color, Rectangle, Circle, Label, Text, Sprite } from 'excalibur';
|
|
50
|
+
/**
|
|
51
|
+
* Tile dimensions - standard tile size
|
|
52
|
+
*/
|
|
53
|
+
export const TILE_WIDTH = 256;
|
|
54
|
+
export const TILE_HEIGHT = 554;
|
|
55
|
+
const ExcaliburContext = createContext(null);
|
|
56
|
+
/**
|
|
57
|
+
* Hook to get the Excalibur Engine
|
|
58
|
+
*/
|
|
59
|
+
export function useEngine() {
|
|
60
|
+
const context = useContext(ExcaliburContext);
|
|
61
|
+
if (!context) {
|
|
62
|
+
throw new Error('useEngine must be used within an ExcaliburGame component');
|
|
63
|
+
}
|
|
64
|
+
return context.engine;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Hook to get the current scene
|
|
68
|
+
*/
|
|
69
|
+
export function useScene() {
|
|
70
|
+
const engine = useEngine();
|
|
71
|
+
return engine?.currentScene || null;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* useGameLoop - Run a callback every frame
|
|
75
|
+
*
|
|
76
|
+
* @param callback - Function called every frame with delta time (in ms)
|
|
77
|
+
* @param enabled - Whether the loop is active (default: true)
|
|
78
|
+
*/
|
|
79
|
+
export function useGameLoop(callback, enabled = true) {
|
|
80
|
+
const context = useContext(ExcaliburContext);
|
|
81
|
+
const callbackRef = useRef(callback);
|
|
82
|
+
callbackRef.current = callback;
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (!context || !enabled)
|
|
85
|
+
return;
|
|
86
|
+
const wrappedCallback = (delta) => {
|
|
87
|
+
callbackRef.current(delta);
|
|
88
|
+
};
|
|
89
|
+
return context.addUpdateCallback(wrappedCallback);
|
|
90
|
+
}, [context, enabled]);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* ExcaliburGame - Main wrapper component for Excalibur.js games
|
|
94
|
+
*
|
|
95
|
+
* Creates an Excalibur Engine and provides it via context.
|
|
96
|
+
* Children can use useEngine() to access the engine and add actors/entities.
|
|
97
|
+
*/
|
|
98
|
+
export function ExcaliburGame({ children, width = TILE_WIDTH, height = TILE_HEIGHT, backgroundColor = '#000000', displayMode = DisplayMode.Fixed, options = {}, paused = false, onMount, }) {
|
|
99
|
+
const containerRef = useRef(null);
|
|
100
|
+
const engineRef = useRef(null);
|
|
101
|
+
const updateCallbacksRef = useRef(new Set());
|
|
102
|
+
const [isReady, setIsReady] = useState(false);
|
|
103
|
+
// Create Excalibur Engine
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
if (!containerRef.current)
|
|
106
|
+
return;
|
|
107
|
+
const engine = new Engine({
|
|
108
|
+
width,
|
|
109
|
+
height,
|
|
110
|
+
displayMode,
|
|
111
|
+
backgroundColor: ExColor.fromHex(backgroundColor),
|
|
112
|
+
canvasElementId: undefined,
|
|
113
|
+
antialiasing: options.antialiasing ?? true,
|
|
114
|
+
pixelArt: options.pixelArt ?? false,
|
|
115
|
+
suppressPlayButton: options.suppressPlayButton ?? true,
|
|
116
|
+
});
|
|
117
|
+
// Mount canvas to container
|
|
118
|
+
containerRef.current.appendChild(engine.canvas);
|
|
119
|
+
engineRef.current = engine;
|
|
120
|
+
// Hook into update cycle to call registered callbacks
|
|
121
|
+
engine.on('preupdate', (evt) => {
|
|
122
|
+
const delta = evt.delta;
|
|
123
|
+
for (const callback of updateCallbacksRef.current) {
|
|
124
|
+
callback(delta);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
// Start the engine
|
|
128
|
+
engine.start().then(() => {
|
|
129
|
+
setIsReady(true);
|
|
130
|
+
onMount?.(engine);
|
|
131
|
+
});
|
|
132
|
+
return () => {
|
|
133
|
+
setIsReady(false);
|
|
134
|
+
updateCallbacksRef.current.clear();
|
|
135
|
+
engine.stop();
|
|
136
|
+
if (containerRef.current?.contains(engine.canvas)) {
|
|
137
|
+
containerRef.current.removeChild(engine.canvas);
|
|
138
|
+
}
|
|
139
|
+
engineRef.current = null;
|
|
140
|
+
};
|
|
141
|
+
}, []); // Only run once on mount
|
|
142
|
+
// Handle size changes
|
|
143
|
+
useEffect(() => {
|
|
144
|
+
if (engineRef.current && engineRef.current.screen) {
|
|
145
|
+
engineRef.current.screen.resolution = { width, height };
|
|
146
|
+
}
|
|
147
|
+
}, [width, height]);
|
|
148
|
+
// Handle background color changes
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
if (engineRef.current) {
|
|
151
|
+
engineRef.current.backgroundColor = ExColor.fromHex(backgroundColor);
|
|
152
|
+
}
|
|
153
|
+
}, [backgroundColor]);
|
|
154
|
+
// Handle pause state
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
if (engineRef.current) {
|
|
157
|
+
if (paused) {
|
|
158
|
+
engineRef.current.stop();
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
engineRef.current.start();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}, [paused]);
|
|
165
|
+
// Context value with engine and update registration
|
|
166
|
+
const contextValue = {
|
|
167
|
+
engine: engineRef.current,
|
|
168
|
+
addUpdateCallback: useCallback((callback) => {
|
|
169
|
+
updateCallbacksRef.current.add(callback);
|
|
170
|
+
return () => {
|
|
171
|
+
updateCallbacksRef.current.delete(callback);
|
|
172
|
+
};
|
|
173
|
+
}, []),
|
|
174
|
+
};
|
|
175
|
+
return (React.createElement("div", { ref: containerRef, style: { width, height, overflow: 'hidden' } }, isReady && (React.createElement(ExcaliburContext.Provider, { value: contextValue }, children))));
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* useGameState - Helper for managing game state with refs
|
|
179
|
+
*
|
|
180
|
+
* Returns a ref and a forceUpdate function for when you need to trigger re-renders.
|
|
181
|
+
* Use refs for continuous game state (position, velocity) to avoid re-render loops.
|
|
182
|
+
*/
|
|
183
|
+
export function useGameState(initialState) {
|
|
184
|
+
const stateRef = useRef(initialState);
|
|
185
|
+
const [, setTick] = useState(0);
|
|
186
|
+
const forceUpdate = useCallback(() => {
|
|
187
|
+
setTick((t) => t + 1);
|
|
188
|
+
}, []);
|
|
189
|
+
return [stateRef, forceUpdate];
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* useGameInput - Simple keyboard input hook for games
|
|
193
|
+
*
|
|
194
|
+
* Returns a ref with currently pressed keys.
|
|
195
|
+
*/
|
|
196
|
+
export function useGameInput() {
|
|
197
|
+
const keysRef = useRef({});
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
const handleKeyDown = (e) => {
|
|
200
|
+
keysRef.current[e.key] = true;
|
|
201
|
+
keysRef.current[e.code] = true;
|
|
202
|
+
};
|
|
203
|
+
const handleKeyUp = (e) => {
|
|
204
|
+
keysRef.current[e.key] = false;
|
|
205
|
+
keysRef.current[e.code] = false;
|
|
206
|
+
};
|
|
207
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
208
|
+
window.addEventListener('keyup', handleKeyUp);
|
|
209
|
+
return () => {
|
|
210
|
+
window.removeEventListener('keydown', handleKeyDown);
|
|
211
|
+
window.removeEventListener('keyup', handleKeyUp);
|
|
212
|
+
};
|
|
213
|
+
}, []);
|
|
214
|
+
return keysRef;
|
|
215
|
+
}
|
package/dist/react/index.js
CHANGED
|
@@ -5,8 +5,8 @@ export { useKeyboard } from './useKeyboard.js';
|
|
|
5
5
|
export { TileContainer } from './TileContainer.js';
|
|
6
6
|
export { withTile } from './withTile.js';
|
|
7
7
|
// TileInitializer removed - router should be injected directly into TileProvider
|
|
8
|
-
// NOTE:
|
|
9
|
-
// to avoid loading
|
|
10
|
-
// import {
|
|
8
|
+
// NOTE: ExcaliburGame and excalibur-related exports are in a SEPARATE entry point
|
|
9
|
+
// to avoid loading excalibur when not needed. Import from:
|
|
10
|
+
// import { ExcaliburGame, useEngine, useGameLoop, ... } from '@thewhateverapp/tile-sdk/excalibur'
|
|
11
11
|
// Overlay components for hybrid tiles (video/image with interactive overlays)
|
|
12
12
|
export * from './overlay/index.js';
|
package/dist/scene/index.d.ts
CHANGED
|
@@ -1,46 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Scene SDK - Runtime renderer for SceneSpecV1
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```tsx
|
|
8
|
-
* // RECOMMENDED: Use SceneFromJson with a JSON file
|
|
9
|
-
* import { SceneFromJson } from '@thewhateverapp/tile-sdk/scene';
|
|
10
|
-
* import sceneJson from './scene.json';
|
|
11
|
-
*
|
|
12
|
-
* export default function TilePage() {
|
|
13
|
-
* return <SceneFromJson json={sceneJson} />;
|
|
14
|
-
* }
|
|
15
|
-
* ```
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* ```tsx
|
|
19
|
-
* // Alternative: Use SceneRenderer with a spec object (for computed values)
|
|
20
|
-
* import { SceneRenderer } from '@thewhateverapp/tile-sdk/scene';
|
|
21
|
-
* import type { SceneSpecV1 } from '@thewhateverapp/scene-sdk';
|
|
22
|
-
*
|
|
23
|
-
* function MyGame() {
|
|
24
|
-
* const spec: SceneSpecV1 = { version: 1, entities: [...] };
|
|
25
|
-
* return <SceneRenderer spec={spec} />;
|
|
26
|
-
* }
|
|
27
|
-
* ```
|
|
4
|
+
* NOTE: Scene rendering is temporarily disabled pending migration from Pixi.js to Excalibur.
|
|
5
|
+
* Use @thewhateverapp/tile-sdk/excalibur for game development instead.
|
|
28
6
|
*/
|
|
29
|
-
export {
|
|
30
|
-
export type { SceneFromJsonProps } from './SceneFromJson.js';
|
|
31
|
-
export { SceneRenderer, useScene } from './SceneRenderer.js';
|
|
32
|
-
export type { SceneRendererProps } from './SceneRenderer.js';
|
|
33
|
-
export { SceneContext, createEntityState, createPlayerState, createCameraState, createInputState, createTimelineState, } from './SceneContext.js';
|
|
34
|
-
export type { SceneContextValue, EntityState, PlayerState, CameraState, InputState, TimelineState, ActiveTween, } from './SceneContext.js';
|
|
35
|
-
export { createEntityGraphics, updateEntityGraphics, } from './entities/EntityGraphics.js';
|
|
36
|
-
export type { EntityGraphics } from './entities/EntityGraphics.js';
|
|
37
|
-
export { usePhysicsEngine, applyImpulse, setVelocity, } from './physics/PhysicsEngine.js';
|
|
38
|
-
export { useInputManager, isJumpPressed, isKeyPressed, isTouching, } from './input/InputManager.js';
|
|
39
|
-
export { useComponentRunner, registerComponent, } from './components/ComponentRunner.js';
|
|
40
|
-
export { useTimelineExecutor } from './timeline/TimelineExecutor.js';
|
|
41
|
-
export { useCameraController } from './camera/CameraController.js';
|
|
42
|
-
export { createGlowOptions, parseColor, isGlowFilterAvailable, createGlowShadow, } from './effects/GlowFilter.js';
|
|
43
|
-
export type { GlowOptions } from './effects/GlowFilter.js';
|
|
44
|
-
export { createEmitter, updateEmitter, drawParticles, burstEmit, } from './effects/ParticleSystem.js';
|
|
45
|
-
export type { Particle, ParticleEmitter } from './effects/ParticleSystem.js';
|
|
7
|
+
export {};
|
|
46
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scene/index.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scene/index.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAKH,OAAO,EAAE,CAAC"}
|