@thewhateverapp/tile-sdk 0.15.3 → 0.15.4

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.
Files changed (51) hide show
  1. package/dist/excalibur/index.d.ts +48 -0
  2. package/dist/excalibur/index.d.ts.map +1 -0
  3. package/dist/excalibur/index.js +51 -0
  4. package/dist/react/ExcaliburGame.d.ts +109 -0
  5. package/dist/react/ExcaliburGame.d.ts.map +1 -0
  6. package/dist/react/ExcaliburGame.js +215 -0
  7. package/dist/react/index.js +3 -3
  8. package/dist/scene/index.d.ts +3 -41
  9. package/dist/scene/index.d.ts.map +1 -1
  10. package/dist/scene/index.js +1 -49
  11. package/dist/spec/schema.d.ts +12 -12
  12. package/package.json +7 -7
  13. package/dist/pixi/index.d.ts +0 -43
  14. package/dist/pixi/index.d.ts.map +0 -1
  15. package/dist/pixi/index.js +0 -46
  16. package/dist/react/PixiGame.d.ts +0 -138
  17. package/dist/react/PixiGame.d.ts.map +0 -1
  18. package/dist/react/PixiGame.js +0 -237
  19. package/dist/scene/SceneContext.d.ts +0 -173
  20. package/dist/scene/SceneContext.d.ts.map +0 -1
  21. package/dist/scene/SceneContext.js +0 -89
  22. package/dist/scene/SceneFromJson.d.ts +0 -34
  23. package/dist/scene/SceneFromJson.d.ts.map +0 -1
  24. package/dist/scene/SceneFromJson.js +0 -97
  25. package/dist/scene/SceneRenderer.d.ts +0 -29
  26. package/dist/scene/SceneRenderer.d.ts.map +0 -1
  27. package/dist/scene/SceneRenderer.js +0 -312
  28. package/dist/scene/camera/CameraController.d.ts +0 -6
  29. package/dist/scene/camera/CameraController.d.ts.map +0 -1
  30. package/dist/scene/camera/CameraController.js +0 -90
  31. package/dist/scene/components/ComponentRunner.d.ts +0 -22
  32. package/dist/scene/components/ComponentRunner.d.ts.map +0 -1
  33. package/dist/scene/components/ComponentRunner.js +0 -210
  34. package/dist/scene/effects/GlowFilter.d.ts +0 -38
  35. package/dist/scene/effects/GlowFilter.d.ts.map +0 -1
  36. package/dist/scene/effects/GlowFilter.js +0 -40
  37. package/dist/scene/effects/ParticleSystem.d.ts +0 -52
  38. package/dist/scene/effects/ParticleSystem.d.ts.map +0 -1
  39. package/dist/scene/effects/ParticleSystem.js +0 -107
  40. package/dist/scene/entities/EntityGraphics.d.ts +0 -26
  41. package/dist/scene/entities/EntityGraphics.d.ts.map +0 -1
  42. package/dist/scene/entities/EntityGraphics.js +0 -226
  43. package/dist/scene/input/InputManager.d.ts +0 -18
  44. package/dist/scene/input/InputManager.d.ts.map +0 -1
  45. package/dist/scene/input/InputManager.js +0 -86
  46. package/dist/scene/physics/PhysicsEngine.d.ts +0 -15
  47. package/dist/scene/physics/PhysicsEngine.d.ts.map +0 -1
  48. package/dist/scene/physics/PhysicsEngine.js +0 -260
  49. package/dist/scene/timeline/TimelineExecutor.d.ts +0 -6
  50. package/dist/scene/timeline/TimelineExecutor.d.ts.map +0 -1
  51. package/dist/scene/timeline/TimelineExecutor.js +0 -241
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thewhateverapp/tile-sdk",
3
- "version": "0.15.3",
3
+ "version": "0.15.4",
4
4
  "description": "SDK for building interactive tiles on The Whatever App platform",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -13,9 +13,9 @@
13
13
  "types": "./dist/react/index.d.ts",
14
14
  "import": "./dist/react/index.js"
15
15
  },
16
- "./pixi": {
17
- "types": "./dist/pixi/index.d.ts",
18
- "import": "./dist/pixi/index.js"
16
+ "./excalibur": {
17
+ "types": "./dist/excalibur/index.d.ts",
18
+ "import": "./dist/excalibur/index.js"
19
19
  },
20
20
  "./spec": {
21
21
  "types": "./dist/spec/index.d.ts",
@@ -70,10 +70,10 @@
70
70
  },
71
71
  "peerDependencies": {
72
72
  "react": "^18.0.0",
73
- "pixi.js": "^7.0.0"
73
+ "excalibur": "^0.29.0"
74
74
  },
75
75
  "peerDependenciesMeta": {
76
- "pixi.js": {
76
+ "excalibur": {
77
77
  "optional": true
78
78
  }
79
79
  },
@@ -82,8 +82,8 @@
82
82
  "@types/node": "^20.0.0",
83
83
  "@types/react": "^18.2.48",
84
84
  "eslint": "^9.39.1",
85
+ "excalibur": "^0.29.3",
85
86
  "next": "^14.2.0",
86
- "pixi.js": "^7.4.2",
87
87
  "typescript": "^5.3.3"
88
88
  }
89
89
  }
@@ -1,43 +0,0 @@
1
- /**
2
- * Pixi.js game components for tile-sdk
3
- *
4
- * Import from '@thewhateverapp/tile-sdk/pixi' to use pixi.js features.
5
- * This uses pixi.js directly (no @pixi/react) for better stability.
6
- *
7
- * @example
8
- * ```tsx
9
- * import { PixiGame, usePixiApp, useGameLoop } from '@thewhateverapp/tile-sdk/pixi';
10
- * import * as PIXI from 'pixi.js';
11
- *
12
- * function MyGame() {
13
- * return (
14
- * <PixiGame width={256} height={554}>
15
- * <GameContent />
16
- * </PixiGame>
17
- * );
18
- * }
19
- *
20
- * function GameContent() {
21
- * const app = usePixiApp();
22
- *
23
- * useEffect(() => {
24
- * if (!app) return;
25
- * const graphics = new PIXI.Graphics();
26
- * graphics.beginFill(0xff0000);
27
- * graphics.drawRect(100, 100, 50, 50);
28
- * graphics.endFill();
29
- * app.stage.addChild(graphics);
30
- * return () => graphics.destroy();
31
- * }, [app]);
32
- *
33
- * useGameLoop((delta) => {
34
- * // Game logic runs every frame
35
- * });
36
- *
37
- * return null;
38
- * }
39
- * ```
40
- */
41
- export { PixiGame, usePixiApp, useApp, useGameLoop, useGameState, useGameInput, useInitialized, Container, Graphics, Text, Sprite, TILE_WIDTH, TILE_HEIGHT, } from '../react/PixiGame.js';
42
- export type { PixiGameProps } from '../react/PixiGame.js';
43
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pixi/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EACL,QAAQ,EACR,UAAU,EACV,MAAM,EACN,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EAEd,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,MAAM,EAEN,UAAU,EACV,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
@@ -1,46 +0,0 @@
1
- 'use client';
2
- /**
3
- * Pixi.js game components for tile-sdk
4
- *
5
- * Import from '@thewhateverapp/tile-sdk/pixi' to use pixi.js features.
6
- * This uses pixi.js directly (no @pixi/react) for better stability.
7
- *
8
- * @example
9
- * ```tsx
10
- * import { PixiGame, usePixiApp, useGameLoop } from '@thewhateverapp/tile-sdk/pixi';
11
- * import * as PIXI from 'pixi.js';
12
- *
13
- * function MyGame() {
14
- * return (
15
- * <PixiGame width={256} height={554}>
16
- * <GameContent />
17
- * </PixiGame>
18
- * );
19
- * }
20
- *
21
- * function GameContent() {
22
- * const app = usePixiApp();
23
- *
24
- * useEffect(() => {
25
- * if (!app) return;
26
- * const graphics = new PIXI.Graphics();
27
- * graphics.beginFill(0xff0000);
28
- * graphics.drawRect(100, 100, 50, 50);
29
- * graphics.endFill();
30
- * app.stage.addChild(graphics);
31
- * return () => graphics.destroy();
32
- * }, [app]);
33
- *
34
- * useGameLoop((delta) => {
35
- * // Game logic runs every frame
36
- * });
37
- *
38
- * return null;
39
- * }
40
- * ```
41
- */
42
- export { PixiGame, usePixiApp, useApp, useGameLoop, useGameState, useGameInput, useInitialized,
43
- // Re-exported PIXI classes
44
- Container, Graphics, Text, Sprite,
45
- // Constants
46
- TILE_WIDTH, TILE_HEIGHT, } from '../react/PixiGame.js';
@@ -1,138 +0,0 @@
1
- /**
2
- * PixiGame - Direct pixi.js integration without @pixi/react
3
- *
4
- * This component creates a PIXI.Application imperatively and provides
5
- * it via React context. This avoids react-reconciler issues that plague
6
- * @pixi/react.
7
- *
8
- * @example
9
- * ```tsx
10
- * import { PixiGame, usePixiApp, useGameLoop } from '@thewhateverapp/tile-sdk/pixi';
11
- *
12
- * function MyGame() {
13
- * return (
14
- * <PixiGame>
15
- * <GameContent />
16
- * </PixiGame>
17
- * );
18
- * }
19
- *
20
- * function GameContent() {
21
- * const app = usePixiApp();
22
- * const containerRef = useRef<PIXI.Container | null>(null);
23
- *
24
- * useEffect(() => {
25
- * if (!app) return;
26
- * const container = new PIXI.Container();
27
- * app.stage.addChild(container);
28
- * containerRef.current = container;
29
- * return () => {
30
- * app.stage.removeChild(container);
31
- * container.destroy();
32
- * };
33
- * }, [app]);
34
- *
35
- * useGameLoop((delta) => {
36
- * // Game logic here
37
- * });
38
- *
39
- * return null; // No React children needed - pixi manages rendering
40
- * }
41
- * ```
42
- */
43
- import React, { type ReactNode } from 'react';
44
- import * as PIXI from 'pixi.js';
45
- export { Container, Graphics, Text, Sprite } from 'pixi.js';
46
- /**
47
- * Tile dimensions - standard tile size
48
- */
49
- export declare const TILE_WIDTH = 256;
50
- export declare const TILE_HEIGHT = 554;
51
- /**
52
- * Hook to get the PIXI Application
53
- */
54
- export declare function usePixiApp(): PIXI.Application | null;
55
- /**
56
- * Hook to get the PIXI Application (alias for backwards compatibility)
57
- */
58
- export declare function useApp(): PIXI.Application | null;
59
- /**
60
- * useGameLoop - Run a callback every frame
61
- *
62
- * @param callback - Function called every frame with delta time (in frames, ~1 at 60fps)
63
- * @param enabled - Whether the loop is active (default: true)
64
- */
65
- export declare function useGameLoop(callback: (delta: number) => void, enabled?: boolean): void;
66
- export interface PixiGameProps {
67
- children: ReactNode;
68
- /** Width in pixels (default: 256 for tile) */
69
- width?: number;
70
- /** Height in pixels (default: 554 for tile) */
71
- height?: number;
72
- /** Background color (default: black) */
73
- background?: number;
74
- /** Stage options */
75
- options?: {
76
- antialias?: boolean;
77
- resolution?: number;
78
- autoDensity?: boolean;
79
- };
80
- /** Whether game is paused */
81
- paused?: boolean;
82
- /** Callback when Application is ready */
83
- onMount?: (app: PIXI.Application) => void;
84
- }
85
- /**
86
- * PixiGame - Main wrapper component for pixi.js games
87
- *
88
- * Creates a PIXI.Application and provides it via context.
89
- * Children can use usePixiApp() to access the app and create pixi objects.
90
- */
91
- export declare function PixiGame({ children, width, height, background, options, paused, onMount, }: PixiGameProps): React.JSX.Element;
92
- /**
93
- * useGameState - Helper for managing game state with refs
94
- *
95
- * Returns a ref and a forceUpdate function for when you need to trigger re-renders.
96
- * Use refs for continuous game state (position, velocity) to avoid re-render loops.
97
- */
98
- export declare function useGameState<T extends object>(initialState: T): [React.MutableRefObject<T>, () => void];
99
- /**
100
- * useGameInput - Simple keyboard input hook for games
101
- *
102
- * Returns a ref with currently pressed keys.
103
- */
104
- export declare function useGameInput(): React.MutableRefObject<Record<string, boolean>>;
105
- /**
106
- * useInitialized - Helper hook for tracking game object initialization
107
- *
108
- * Returns an initRef that should be set to true AFTER all game objects are
109
- * created in useEffect, and checked as the FIRST line in useGameLoop.
110
- *
111
- * @example
112
- * ```tsx
113
- * function GameContent() {
114
- * const app = usePixiApp();
115
- * const initRef = useInitialized();
116
- * const playerRef = useRef<PIXI.Graphics | null>(null);
117
- *
118
- * useEffect(() => {
119
- * if (!app) return;
120
- * const player = new PIXI.Graphics();
121
- * // ... setup player ...
122
- * playerRef.current = player;
123
- * initRef.current = true; // Set AFTER all refs are ready
124
- * return () => {
125
- * initRef.current = false;
126
- * player.destroy();
127
- * };
128
- * }, [app]);
129
- *
130
- * useGameLoop((delta) => {
131
- * if (!initRef.current || !playerRef.current) return; // REQUIRED!
132
- * // ... safe to use playerRef.current ...
133
- * });
134
- * }
135
- * ```
136
- */
137
- export declare function useInitialized(): React.MutableRefObject<boolean>;
138
- //# sourceMappingURL=PixiGame.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PixiGame.d.ts","sourceRoot":"","sources":["../../src/react/PixiGame.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAGhC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,UAAU,MAAM,CAAC;AAC9B,eAAO,MAAM,WAAW,MAAM,CAAC;AAY/B;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAMpD;AAED;;GAEG;AACH,wBAAgB,MAAM,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAEhD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,OAAO,GAAE,OAAc,QAexB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,SAAS,CAAC;IACpB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oBAAoB;IACpB,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,CAAC;IACF,6BAA6B;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yCAAyC;IACzC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC;CAC3C;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,KAAkB,EAClB,MAAoB,EACpB,UAAqB,EACrB,OAAY,EACZ,MAAc,EACd,OAAO,GACR,EAAE,aAAa,qBAqFf;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;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,cAAc,IAAI,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAEhE"}
@@ -1,237 +0,0 @@
1
- 'use client';
2
- /**
3
- * PixiGame - Direct pixi.js integration without @pixi/react
4
- *
5
- * This component creates a PIXI.Application imperatively and provides
6
- * it via React context. This avoids react-reconciler issues that plague
7
- * @pixi/react.
8
- *
9
- * @example
10
- * ```tsx
11
- * import { PixiGame, usePixiApp, useGameLoop } from '@thewhateverapp/tile-sdk/pixi';
12
- *
13
- * function MyGame() {
14
- * return (
15
- * <PixiGame>
16
- * <GameContent />
17
- * </PixiGame>
18
- * );
19
- * }
20
- *
21
- * function GameContent() {
22
- * const app = usePixiApp();
23
- * const containerRef = useRef<PIXI.Container | null>(null);
24
- *
25
- * useEffect(() => {
26
- * if (!app) return;
27
- * const container = new PIXI.Container();
28
- * app.stage.addChild(container);
29
- * containerRef.current = container;
30
- * return () => {
31
- * app.stage.removeChild(container);
32
- * container.destroy();
33
- * };
34
- * }, [app]);
35
- *
36
- * useGameLoop((delta) => {
37
- * // Game logic here
38
- * });
39
- *
40
- * return null; // No React children needed - pixi manages rendering
41
- * }
42
- * ```
43
- */
44
- import React, { createContext, useContext, useRef, useEffect, useState, useCallback, } from 'react';
45
- import * as PIXI from 'pixi.js';
46
- // Re-export PIXI classes for convenience
47
- export { Container, Graphics, Text, Sprite } from 'pixi.js';
48
- /**
49
- * Tile dimensions - standard tile size
50
- */
51
- export const TILE_WIDTH = 256;
52
- export const TILE_HEIGHT = 554;
53
- const PixiContext = createContext(null);
54
- /**
55
- * Hook to get the PIXI Application
56
- */
57
- export function usePixiApp() {
58
- const context = useContext(PixiContext);
59
- if (!context) {
60
- throw new Error('usePixiApp must be used within a PixiGame component');
61
- }
62
- return context.app;
63
- }
64
- /**
65
- * Hook to get the PIXI Application (alias for backwards compatibility)
66
- */
67
- export function useApp() {
68
- return usePixiApp();
69
- }
70
- /**
71
- * useGameLoop - Run a callback every frame
72
- *
73
- * @param callback - Function called every frame with delta time (in frames, ~1 at 60fps)
74
- * @param enabled - Whether the loop is active (default: true)
75
- */
76
- export function useGameLoop(callback, enabled = true) {
77
- const context = useContext(PixiContext);
78
- const callbackRef = useRef(callback);
79
- callbackRef.current = callback;
80
- useEffect(() => {
81
- if (!context || !enabled)
82
- return;
83
- const wrappedCallback = (delta) => {
84
- callbackRef.current(delta);
85
- };
86
- return context.addTickerCallback(wrappedCallback);
87
- }, [context, enabled]);
88
- }
89
- /**
90
- * PixiGame - Main wrapper component for pixi.js games
91
- *
92
- * Creates a PIXI.Application and provides it via context.
93
- * Children can use usePixiApp() to access the app and create pixi objects.
94
- */
95
- export function PixiGame({ children, width = TILE_WIDTH, height = TILE_HEIGHT, background = 0x000000, options = {}, paused = false, onMount, }) {
96
- const containerRef = useRef(null);
97
- const appRef = useRef(null);
98
- const tickerCallbacksRef = useRef(new Set());
99
- const [isReady, setIsReady] = useState(false);
100
- // Create PIXI Application
101
- useEffect(() => {
102
- if (!containerRef.current)
103
- return;
104
- const app = new PIXI.Application({
105
- width,
106
- height,
107
- backgroundColor: background,
108
- antialias: options.antialias ?? true,
109
- resolution: options.resolution ?? (typeof window !== 'undefined' ? window.devicePixelRatio : 1),
110
- autoDensity: options.autoDensity ?? true,
111
- });
112
- containerRef.current.appendChild(app.view);
113
- appRef.current = app;
114
- // Add master ticker callback that calls all registered callbacks
115
- app.ticker.add((delta) => {
116
- for (const callback of tickerCallbacksRef.current) {
117
- callback(delta);
118
- }
119
- });
120
- setIsReady(true);
121
- onMount?.(app);
122
- return () => {
123
- setIsReady(false);
124
- tickerCallbacksRef.current.clear();
125
- app.destroy(true, { children: true, texture: true, baseTexture: true });
126
- appRef.current = null;
127
- };
128
- }, []); // Only run once on mount
129
- // Handle size changes
130
- useEffect(() => {
131
- if (appRef.current) {
132
- appRef.current.renderer.resize(width, height);
133
- }
134
- }, [width, height]);
135
- // Handle background color changes
136
- useEffect(() => {
137
- if (appRef.current) {
138
- appRef.current.renderer.background.color = background;
139
- }
140
- }, [background]);
141
- // Handle pause state
142
- useEffect(() => {
143
- if (appRef.current) {
144
- if (paused) {
145
- appRef.current.ticker.stop();
146
- }
147
- else {
148
- appRef.current.ticker.start();
149
- }
150
- }
151
- }, [paused]);
152
- // Context value with app and ticker registration
153
- const contextValue = {
154
- app: appRef.current,
155
- addTickerCallback: useCallback((callback) => {
156
- tickerCallbacksRef.current.add(callback);
157
- return () => {
158
- tickerCallbacksRef.current.delete(callback);
159
- };
160
- }, []),
161
- };
162
- return (React.createElement("div", { ref: containerRef, style: { width, height } }, isReady && (React.createElement(PixiContext.Provider, { value: contextValue }, children))));
163
- }
164
- /**
165
- * useGameState - Helper for managing game state with refs
166
- *
167
- * Returns a ref and a forceUpdate function for when you need to trigger re-renders.
168
- * Use refs for continuous game state (position, velocity) to avoid re-render loops.
169
- */
170
- export function useGameState(initialState) {
171
- const stateRef = useRef(initialState);
172
- const [, setTick] = useState(0);
173
- const forceUpdate = useCallback(() => {
174
- setTick((t) => t + 1);
175
- }, []);
176
- return [stateRef, forceUpdate];
177
- }
178
- /**
179
- * useGameInput - Simple keyboard input hook for games
180
- *
181
- * Returns a ref with currently pressed keys.
182
- */
183
- export function useGameInput() {
184
- const keysRef = useRef({});
185
- useEffect(() => {
186
- const handleKeyDown = (e) => {
187
- keysRef.current[e.key] = true;
188
- keysRef.current[e.code] = true;
189
- };
190
- const handleKeyUp = (e) => {
191
- keysRef.current[e.key] = false;
192
- keysRef.current[e.code] = false;
193
- };
194
- window.addEventListener('keydown', handleKeyDown);
195
- window.addEventListener('keyup', handleKeyUp);
196
- return () => {
197
- window.removeEventListener('keydown', handleKeyDown);
198
- window.removeEventListener('keyup', handleKeyUp);
199
- };
200
- }, []);
201
- return keysRef;
202
- }
203
- /**
204
- * useInitialized - Helper hook for tracking game object initialization
205
- *
206
- * Returns an initRef that should be set to true AFTER all game objects are
207
- * created in useEffect, and checked as the FIRST line in useGameLoop.
208
- *
209
- * @example
210
- * ```tsx
211
- * function GameContent() {
212
- * const app = usePixiApp();
213
- * const initRef = useInitialized();
214
- * const playerRef = useRef<PIXI.Graphics | null>(null);
215
- *
216
- * useEffect(() => {
217
- * if (!app) return;
218
- * const player = new PIXI.Graphics();
219
- * // ... setup player ...
220
- * playerRef.current = player;
221
- * initRef.current = true; // Set AFTER all refs are ready
222
- * return () => {
223
- * initRef.current = false;
224
- * player.destroy();
225
- * };
226
- * }, [app]);
227
- *
228
- * useGameLoop((delta) => {
229
- * if (!initRef.current || !playerRef.current) return; // REQUIRED!
230
- * // ... safe to use playerRef.current ...
231
- * });
232
- * }
233
- * ```
234
- */
235
- export function useInitialized() {
236
- return useRef(false);
237
- }
@@ -1,173 +0,0 @@
1
- import { type MutableRefObject } from 'react';
2
- import type { SceneSpecV1, Entity, CameraConfig } from '@thewhateverapp/scene-sdk';
3
- import type { Engine, Body } from 'matter-js';
4
- /**
5
- * Runtime entity state - mutable for performance
6
- */
7
- export interface EntityState {
8
- /** Entity definition from spec */
9
- entity: Entity;
10
- /** Current position (updated by physics/components) */
11
- x: number;
12
- y: number;
13
- /** Current rotation in radians */
14
- rotation: number;
15
- /** Current scale */
16
- scaleX: number;
17
- scaleY: number;
18
- /** Current velocity (for physics/movement) */
19
- velocityX: number;
20
- velocityY: number;
21
- /** Whether entity is visible */
22
- visible: boolean;
23
- /** Current fill color (can be animated) */
24
- fill?: string;
25
- /** Current alpha (can be animated) */
26
- alpha: number;
27
- /** Matter.js body (if entity has physics) */
28
- body?: Body;
29
- /** Whether entity is destroyed */
30
- destroyed: boolean;
31
- /** Custom component state */
32
- componentState: Record<string, unknown>;
33
- }
34
- /**
35
- * Player-specific state for dash games
36
- */
37
- export interface PlayerState {
38
- /** Has the game started (waiting for first jump) */
39
- started: boolean;
40
- /** Is player on ground */
41
- grounded: boolean;
42
- /** Is player dead */
43
- dead: boolean;
44
- /** Current jump count (for double jump) */
45
- jumpCount: number;
46
- /** Last checkpoint position */
47
- checkpointX: number;
48
- checkpointY: number;
49
- /** Is touching a jump orb */
50
- touchingOrb: string | null;
51
- /** Gravity direction (1 = down, -1 = up) */
52
- gravityDir: number;
53
- /** Current speed multiplier */
54
- speedMultiplier: number;
55
- /** Death count */
56
- deaths: number;
57
- /** Level complete */
58
- complete: boolean;
59
- /** Invincibility frames (prevents instant re-death after respawn) */
60
- invincible: boolean;
61
- /** Invincibility time remaining in ms */
62
- invincibilityTimeRemaining: number;
63
- }
64
- /**
65
- * Camera state
66
- */
67
- export interface CameraState {
68
- x: number;
69
- y: number;
70
- zoom: number;
71
- shakeIntensity: number;
72
- shakeTimeRemaining: number;
73
- }
74
- /**
75
- * Input state
76
- */
77
- export interface InputState {
78
- /** Is jump/action pressed (space, tap, or up arrow) */
79
- jumpPressed: boolean;
80
- /** Is currently touching (for hold detection) */
81
- touching: boolean;
82
- /** Keys currently held */
83
- keys: Record<string, boolean>;
84
- }
85
- /**
86
- * Timeline state
87
- */
88
- export interface TimelineState {
89
- /** Elapsed time in ms */
90
- elapsedMs: number;
91
- /** Current beat (based on BPM) */
92
- currentBeat: number;
93
- /** Index of next event to process */
94
- nextEventIndex: number;
95
- /** Active tweens */
96
- activeTweens: ActiveTween[];
97
- }
98
- /**
99
- * Active tween animation
100
- */
101
- export interface ActiveTween {
102
- targetId: string;
103
- property: string;
104
- startValue: number;
105
- endValue: number;
106
- startTime: number;
107
- duration: number;
108
- easing: string;
109
- }
110
- /**
111
- * Scene context value - all scene runtime state
112
- */
113
- export interface SceneContextValue {
114
- /** Compiled scene spec */
115
- spec: SceneSpecV1;
116
- /** Entity states by ID */
117
- entities: MutableRefObject<Map<string, EntityState>>;
118
- /** Layer order (front to back) */
119
- layers: string[];
120
- /** Player state (for dash games) */
121
- player: MutableRefObject<PlayerState>;
122
- /** Camera state */
123
- camera: MutableRefObject<CameraState>;
124
- /** Input state */
125
- input: MutableRefObject<InputState>;
126
- /** Timeline state */
127
- timeline: MutableRefObject<TimelineState>;
128
- /** Matter.js engine */
129
- engine: MutableRefObject<Engine | null>;
130
- /** Emit an event to parent */
131
- emitEvent: (event: string, data?: unknown) => void;
132
- /** Get entity state by ID */
133
- getEntity: (id: string) => EntityState | undefined;
134
- /** Spawn an entity from prefab */
135
- spawnEntity: (prefabId: string, x: number, y: number) => void;
136
- /** Destroy an entity */
137
- destroyEntity: (id: string) => void;
138
- /** Respawn player at checkpoint */
139
- respawnPlayer: () => void;
140
- /** BPM for beat calculations */
141
- bpm: number;
142
- /** Start time for timeline */
143
- startTime: number;
144
- }
145
- /**
146
- * Scene context
147
- */
148
- export declare const SceneContext: import("react").Context<SceneContextValue | null>;
149
- /**
150
- * Hook to access scene context
151
- */
152
- export declare function useScene(): SceneContextValue;
153
- /**
154
- * Create initial entity state from entity definition
155
- */
156
- export declare function createEntityState(entity: Entity): EntityState;
157
- /**
158
- * Create initial player state
159
- */
160
- export declare function createPlayerState(): PlayerState;
161
- /**
162
- * Create initial camera state from config
163
- */
164
- export declare function createCameraState(config?: CameraConfig): CameraState;
165
- /**
166
- * Create initial input state
167
- */
168
- export declare function createInputState(): InputState;
169
- /**
170
- * Create initial timeline state
171
- */
172
- export declare function createTimelineState(): TimelineState;
173
- //# sourceMappingURL=SceneContext.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SceneContext.d.ts","sourceRoot":"","sources":["../../src/scene/SceneContext.tsx"],"names":[],"mappings":"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"}