@energy8platform/game-engine 0.10.10 → 0.11.0

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 (49) hide show
  1. package/README.md +185 -74
  2. package/dist/index.cjs.js +1280 -296
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.d.ts +362 -46
  5. package/dist/index.esm.js +1281 -298
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/lua.cjs.js +16 -21
  8. package/dist/lua.cjs.js.map +1 -1
  9. package/dist/lua.d.ts +0 -2
  10. package/dist/lua.esm.js +16 -21
  11. package/dist/lua.esm.js.map +1 -1
  12. package/dist/react.cjs.js +2372 -11
  13. package/dist/react.cjs.js.map +1 -1
  14. package/dist/react.d.ts +17 -6
  15. package/dist/react.esm.js +2372 -12
  16. package/dist/react.esm.js.map +1 -1
  17. package/dist/ui.cjs.js +1553 -632
  18. package/dist/ui.cjs.js.map +1 -1
  19. package/dist/ui.d.ts +374 -46
  20. package/dist/ui.esm.js +1553 -634
  21. package/dist/ui.esm.js.map +1 -1
  22. package/dist/vite.cjs.js +1 -11
  23. package/dist/vite.cjs.js.map +1 -1
  24. package/dist/vite.d.ts +1 -1
  25. package/dist/vite.esm.js +1 -11
  26. package/dist/vite.esm.js.map +1 -1
  27. package/package.json +3 -18
  28. package/src/index.ts +3 -3
  29. package/src/lua/LuaEngine.ts +8 -18
  30. package/src/lua/SimulationRunner.ts +7 -3
  31. package/src/react/applyProps.ts +86 -0
  32. package/src/react/extendAll.ts +27 -6
  33. package/src/react/index.ts +1 -1
  34. package/src/react/jsx.d.ts +222 -0
  35. package/src/react/reconciler.ts +22 -5
  36. package/src/ui/BalanceDisplay.ts +31 -38
  37. package/src/ui/Button.ts +217 -53
  38. package/src/ui/FlexContainer.ts +479 -0
  39. package/src/ui/Label.ts +13 -0
  40. package/src/ui/Layout.ts +86 -87
  41. package/src/ui/Modal.ts +11 -1
  42. package/src/ui/Panel.ts +108 -36
  43. package/src/ui/ProgressBar.ts +85 -31
  44. package/src/ui/ScrollContainer.ts +397 -45
  45. package/src/ui/Toast.ts +47 -17
  46. package/src/ui/WinDisplay.ts +51 -39
  47. package/src/ui/index.ts +5 -11
  48. package/src/ui/view.ts +28 -0
  49. package/src/vite/index.ts +1 -11
@@ -1,5 +1,6 @@
1
1
  import { Container } from 'pixi.js';
2
2
  import { Label } from './Label';
3
+ import { Tween } from '../animation/Tween';
3
4
  import { Easing } from '../animation/Easing';
4
5
 
5
6
  export interface WinDisplayConfig {
@@ -19,7 +20,7 @@ export interface WinDisplayConfig {
19
20
  * Win amount display with countup animation.
20
21
  *
21
22
  * Shows a dramatic countup from 0 to the win amount, with optional
22
- * scale pop effect — typical of slot games.
23
+ * scale pop effect — typical of slot games. Uses engine Tween system.
23
24
  *
24
25
  * @example
25
26
  * ```ts
@@ -30,9 +31,12 @@ export interface WinDisplayConfig {
30
31
  * ```
31
32
  */
32
33
  export class WinDisplay extends Container {
34
+ readonly __uiComponent = true as const;
35
+
33
36
  private _label: Label;
34
37
  private _config: Required<Pick<WinDisplayConfig, 'currency' | 'locale' | 'countupDuration' | 'popScale'>>;
35
- private _cancelCountup = false;
38
+ /** Internal target for Tween countup */
39
+ private _tweenTarget = { value: 0 };
36
40
 
37
41
  constructor(config: WinDisplayConfig = {}) {
38
42
  super();
@@ -67,54 +71,48 @@ export class WinDisplay extends Container {
67
71
  */
68
72
  async showWin(amount: number): Promise<void> {
69
73
  this.visible = true;
70
- this._cancelCountup = false;
71
74
  this.alpha = 1;
72
75
 
73
- const duration = this._config.countupDuration;
74
- const startTime = Date.now();
76
+ // Cancel any running animation
77
+ Tween.killTweensOf(this._tweenTarget);
78
+ Tween.killTweensOf(this);
75
79
 
76
- // Scale pop
80
+ // Setup countup
81
+ this._tweenTarget.value = 0;
77
82
  this.scale.set(0.5);
78
83
 
79
- return new Promise<void>((resolve) => {
80
- const tick = () => {
81
- if (this._cancelCountup) {
82
- this.displayAmount(amount);
83
- resolve();
84
- return;
85
- }
86
-
87
- const elapsed = Date.now() - startTime;
88
- const t = Math.min(elapsed / duration, 1);
89
- const eased = Easing.easeOutCubic(t);
90
-
91
- // Countup
92
- const current = amount * eased;
93
- this.displayAmount(current);
94
-
95
- // Scale animation
96
- const scaleT = Math.min(elapsed / 300, 1);
97
- const scaleEased = Easing.easeOutBack(scaleT);
98
- const targetScale = 1;
99
- this.scale.set(0.5 + (targetScale - 0.5) * scaleEased);
100
-
101
- if (t < 1) {
102
- requestAnimationFrame(tick);
103
- } else {
104
- this.displayAmount(amount);
105
- this.scale.set(1);
106
- resolve();
107
- }
108
- };
109
- requestAnimationFrame(tick);
110
- });
84
+ // Scale pop animation
85
+ const scalePromise = Tween.to(
86
+ this,
87
+ { 'scale.x': 1, 'scale.y': 1 },
88
+ 300,
89
+ Easing.easeOutBack,
90
+ );
91
+
92
+ // Countup animation
93
+ const countupPromise = Tween.to(
94
+ this._tweenTarget,
95
+ { value: amount },
96
+ this._config.countupDuration,
97
+ Easing.easeOutCubic,
98
+ () => {
99
+ this.displayAmount(this._tweenTarget.value);
100
+ },
101
+ );
102
+
103
+ await Promise.all([scalePromise, countupPromise]);
104
+
105
+ // Ensure final value is exact
106
+ this.displayAmount(amount);
107
+ this.scale.set(1);
111
108
  }
112
109
 
113
110
  /**
114
111
  * Skip the countup animation and show the final amount immediately.
115
112
  */
116
113
  skipCountup(amount: number): void {
117
- this._cancelCountup = true;
114
+ Tween.killTweensOf(this._tweenTarget);
115
+ Tween.killTweensOf(this);
118
116
  this.displayAmount(amount);
119
117
  this.scale.set(1);
120
118
  }
@@ -123,6 +121,8 @@ export class WinDisplay extends Container {
123
121
  * Hide the win display.
124
122
  */
125
123
  hide(): void {
124
+ Tween.killTweensOf(this._tweenTarget);
125
+ Tween.killTweensOf(this);
126
126
  this.visible = false;
127
127
  this._label.text = '';
128
128
  }
@@ -130,4 +130,16 @@ export class WinDisplay extends Container {
130
130
  private displayAmount(amount: number): void {
131
131
  this._label.setCurrency(amount, this._config.currency, this._config.locale);
132
132
  }
133
+
134
+ /** React reconciler update hook */
135
+ updateConfig(changed: Record<string, any>): void {
136
+ if ('currency' in changed) this._config.currency = changed.currency;
137
+ if ('locale' in changed) this._config.locale = changed.locale;
138
+ }
139
+
140
+ override destroy(options?: boolean | { children?: boolean; texture?: boolean; textureSource?: boolean }): void {
141
+ Tween.killTweensOf(this._tweenTarget);
142
+ Tween.killTweensOf(this);
143
+ super.destroy(options);
144
+ }
133
145
  }
package/src/ui/index.ts CHANGED
@@ -1,7 +1,10 @@
1
- // ─── @pixi/layout setup (must be imported before creating containers) ────
2
- import '@pixi/layout';
1
+ // ─── View helpers ─────────────────────────────────────────
2
+ export { resolveView } from './view';
3
+ export type { ViewInput } from './view';
3
4
 
4
5
  // ─── Engine UI Components ─────────────────────────────────
6
+ export { FlexContainer } from './FlexContainer';
7
+ export type { FlexContainerConfig, FlexDirection, JustifyContent, AlignItems, FlexItemConfig } from './FlexContainer';
5
8
  export { Button } from './Button';
6
9
  export type { ButtonConfig, ButtonState } from './Button';
7
10
  export { ProgressBar } from './ProgressBar';
@@ -22,12 +25,3 @@ export { Layout } from './Layout';
22
25
  export type { LayoutConfig, LayoutDirection, LayoutAlignment, LayoutAnchor } from './Layout';
23
26
  export { ScrollContainer } from './ScrollContainer';
24
27
  export type { ScrollContainerConfig, ScrollDirection } from './ScrollContainer';
25
-
26
- // ─── Direct access to @pixi/ui and @pixi/layout ──────────
27
- // These packages are optional peer dependencies.
28
- // For any classes or types not wrapped by the engine (e.g. Slider, CheckBox,
29
- // Input, Select, RadioGroup, List, etc.), import directly:
30
- //
31
- // import { Slider, CheckBox } from '@pixi/ui';
32
- // import { LayoutContainer } from '@pixi/layout/components';
33
- //
package/src/ui/view.ts ADDED
@@ -0,0 +1,28 @@
1
+ import { Container, Sprite, Texture } from 'pixi.js';
2
+
3
+ /**
4
+ * Universal view input type for UI component visual slots.
5
+ *
6
+ * - `string` — texture name, resolved via `Sprite.from()`
7
+ * - `Texture` — wrapped in a `Sprite`
8
+ * - `Container` — used as-is (Sprite, Graphics, NineSliceSprite, AnimatedSprite, custom...)
9
+ */
10
+ export type ViewInput = string | Texture | Container;
11
+
12
+ /**
13
+ * Resolve a ViewInput to a Container instance.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * resolveView('btn-idle') // → Sprite.from('btn-idle')
18
+ * resolveView(someTexture) // → new Sprite(someTexture)
19
+ * resolveView(myCustomContainer) // → myCustomContainer (as-is)
20
+ * resolveView(undefined) // → null
21
+ * ```
22
+ */
23
+ export function resolveView(input: ViewInput | undefined | null): Container | null {
24
+ if (input == null) return null;
25
+ if (typeof input === 'string') return Sprite.from(input);
26
+ if (input instanceof Texture) return new Sprite(input);
27
+ return input;
28
+ }
package/src/vite/index.ts CHANGED
@@ -214,7 +214,7 @@ function luaPlugin(configPath: string): Plugin {
214
214
  * Define a Vite configuration tailored for Energy8 casino games.
215
215
  *
216
216
  * Merges sensible defaults for iGaming projects:
217
- * - Build target: ESNext (required for yoga-layout WASM top-level await)
217
+ * - Build target: ESNext
218
218
  * - Asset inlining threshold: 8KB
219
219
  * - Source maps for dev, none for prod
220
220
  * - Optional DevBridge auto-injection in dev mode
@@ -272,11 +272,6 @@ export function defineGameConfig(config: GameConfig = {}): UserConfig {
272
272
  resolve: {
273
273
  dedupe: [
274
274
  'pixi.js',
275
- '@pixi/layout',
276
- '@pixi/layout/components',
277
- '@pixi/ui',
278
- 'yoga-layout',
279
- 'yoga-layout/load',
280
275
  'react',
281
276
  'react-dom',
282
277
  'react-reconciler',
@@ -287,15 +282,10 @@ export function defineGameConfig(config: GameConfig = {}): UserConfig {
287
282
  optimizeDeps: {
288
283
  include: [
289
284
  'pixi.js',
290
- '@pixi/layout',
291
- '@pixi/layout/components',
292
- '@pixi/ui',
293
- 'yoga-layout/load',
294
285
  'react',
295
286
  'react-dom',
296
287
  ],
297
288
  exclude: [
298
- 'yoga-layout',
299
289
  'fengari',
300
290
  ],
301
291
  esbuildOptions: {