@energy8platform/game-engine 0.21.0 → 0.23.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 (65) hide show
  1. package/dist/host.d.ts +3 -5
  2. package/dist/index.cjs.js +0 -2532
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.d.ts +3 -1020
  5. package/dist/index.esm.js +2 -2522
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/slot.cjs.js +0 -30
  8. package/dist/slot.cjs.js.map +1 -1
  9. package/dist/slot.d.ts +2 -25
  10. package/dist/slot.esm.js +1 -30
  11. package/dist/slot.esm.js.map +1 -1
  12. package/dist/vite.cjs.js +0 -5
  13. package/dist/vite.cjs.js.map +1 -1
  14. package/dist/vite.esm.js +0 -5
  15. package/dist/vite.esm.js.map +1 -1
  16. package/package.json +4 -37
  17. package/src/host/index.ts +0 -1
  18. package/src/host/types.ts +0 -3
  19. package/src/index.ts +0 -28
  20. package/src/slot/index.ts +0 -2
  21. package/src/vite/index.ts +0 -5
  22. package/dist/react-jsx.cjs.js +0 -3
  23. package/dist/react-jsx.cjs.js.map +0 -1
  24. package/dist/react-jsx.d.ts +0 -602
  25. package/dist/react-jsx.esm.js +0 -2
  26. package/dist/react-jsx.esm.js.map +0 -1
  27. package/dist/react.cjs.js +0 -3802
  28. package/dist/react.cjs.js.map +0 -1
  29. package/dist/react.d.ts +0 -1467
  30. package/dist/react.esm.js +0 -3786
  31. package/dist/react.esm.js.map +0 -1
  32. package/dist/ui.cjs.js +0 -3014
  33. package/dist/ui.cjs.js.map +0 -1
  34. package/dist/ui.d.ts +0 -1116
  35. package/dist/ui.esm.js +0 -2998
  36. package/dist/ui.esm.js.map +0 -1
  37. package/src/react/EngineContext.ts +0 -26
  38. package/src/react/ReactScene.ts +0 -88
  39. package/src/react/applyProps.ts +0 -271
  40. package/src/react/catalogue.ts +0 -17
  41. package/src/react/createPixiRoot.ts +0 -31
  42. package/src/react/extendAll.ts +0 -74
  43. package/src/react/hooks.ts +0 -46
  44. package/src/react/index.ts +0 -29
  45. package/src/react/jsx-runtime.ts +0 -346
  46. package/src/react/reconciler.ts +0 -338
  47. package/src/slot/freeSpins/FreeSpinsSession.ts +0 -40
  48. package/src/state/StateMachine.ts +0 -231
  49. package/src/state/index.ts +0 -1
  50. package/src/ui/BalanceDisplay.ts +0 -159
  51. package/src/ui/Button.ts +0 -304
  52. package/src/ui/FlexContainer.ts +0 -775
  53. package/src/ui/Label.ts +0 -124
  54. package/src/ui/LabelValue.ts +0 -122
  55. package/src/ui/Layout.ts +0 -291
  56. package/src/ui/Modal.ts +0 -170
  57. package/src/ui/Panel.ts +0 -204
  58. package/src/ui/ProgressBar.ts +0 -170
  59. package/src/ui/ScrollContainer.ts +0 -478
  60. package/src/ui/Slider.ts +0 -241
  61. package/src/ui/Toast.ts +0 -150
  62. package/src/ui/Toggle.ts +0 -201
  63. package/src/ui/WinDisplay.ts +0 -145
  64. package/src/ui/index.ts +0 -33
  65. package/src/ui/view.ts +0 -28
@@ -1,159 +0,0 @@
1
- import { Container } from 'pixi.js';
2
- import { Label } from './Label';
3
- import { Tween } from '../animation/Tween';
4
- import { Easing } from '../animation/Easing';
5
-
6
- export interface BalanceDisplayConfig {
7
- /** Label prefix (e.g., "BALANCE") */
8
- prefix?: string;
9
- /** Text style overrides */
10
- style?: Record<string, unknown>;
11
- /** Currency code */
12
- currency?: string;
13
- /** Locale for number formatting */
14
- locale?: string;
15
- /** Max width */
16
- maxWidth?: number;
17
- /** Animate value changes */
18
- animated?: boolean;
19
- /** Animation duration in ms */
20
- animationDuration?: number;
21
- }
22
-
23
- /**
24
- * Reactive balance display component.
25
- *
26
- * Automatically formats currency and can animate value changes
27
- * with a smooth countup/countdown effect using engine Tween.
28
- *
29
- * @example
30
- * ```ts
31
- * const balance = new BalanceDisplay({ currency: 'USD', animated: true });
32
- * balance.setValue(1000);
33
- *
34
- * // Wire to SDK
35
- * sdk.on('balanceUpdate', ({ balance: val }) => balance.setValue(val));
36
- * ```
37
- */
38
- export class BalanceDisplay extends Container {
39
- readonly __uiComponent = true as const;
40
-
41
- private _prefixLabel: Label | null = null;
42
- private _valueLabel: Label;
43
- private _config: Required<Pick<BalanceDisplayConfig, 'currency' | 'locale' | 'animated' | 'animationDuration'>>;
44
- private _currentValue = 0;
45
- private _displayedValue = 0;
46
- /** Internal target for Tween animation */
47
- private _tweenTarget = { value: 0 };
48
-
49
- constructor(config: BalanceDisplayConfig = {}) {
50
- super();
51
-
52
- this._config = {
53
- currency: config.currency ?? 'USD',
54
- locale: config.locale ?? 'en-US',
55
- animated: config.animated ?? true,
56
- animationDuration: config.animationDuration ?? 500,
57
- };
58
-
59
- // Prefix label
60
- if (config.prefix) {
61
- this._prefixLabel = new Label({
62
- text: config.prefix,
63
- style: {
64
- fontSize: 16,
65
- fill: 0xaaaaaa,
66
- ...(config.style as any),
67
- },
68
- });
69
- this.addChild(this._prefixLabel);
70
- }
71
-
72
- // Value label
73
- this._valueLabel = new Label({
74
- text: '0.00',
75
- style: {
76
- fontSize: 28,
77
- fontWeight: 'bold',
78
- fill: 0xffffff,
79
- ...(config.style as any),
80
- },
81
- maxWidth: config.maxWidth,
82
- autoFit: !!config.maxWidth,
83
- });
84
- this.addChild(this._valueLabel);
85
-
86
- this.layoutLabels();
87
- }
88
-
89
- /** Current displayed value */
90
- get value(): number {
91
- return this._currentValue;
92
- }
93
-
94
- /**
95
- * Set the balance value. If animated, smoothly counts to the new value.
96
- */
97
- setValue(value: number): void {
98
- const oldValue = this._currentValue;
99
- this._currentValue = value;
100
-
101
- if (this._config.animated && oldValue !== value) {
102
- this.animateValue(oldValue, value);
103
- } else {
104
- this._displayedValue = value;
105
- this.updateDisplay();
106
- }
107
- }
108
-
109
- /**
110
- * Set the currency code.
111
- */
112
- setCurrency(currency: string): void {
113
- this._config.currency = currency;
114
- this.updateDisplay();
115
- }
116
-
117
- private animateValue(from: number, to: number): void {
118
- // Cancel any running animation
119
- Tween.killTweensOf(this._tweenTarget);
120
-
121
- this._tweenTarget.value = from;
122
- Tween.to(
123
- this._tweenTarget,
124
- { value: to },
125
- this._config.animationDuration,
126
- Easing.easeOutCubic,
127
- () => {
128
- this._displayedValue = this._tweenTarget.value;
129
- this.updateDisplay();
130
- },
131
- );
132
- }
133
-
134
- private updateDisplay(): void {
135
- this._valueLabel.setCurrency(
136
- this._displayedValue,
137
- this._config.currency,
138
- this._config.locale,
139
- );
140
- }
141
-
142
- private layoutLabels(): void {
143
- if (this._prefixLabel) {
144
- this._prefixLabel.y = -14;
145
- this._valueLabel.y = 14;
146
- }
147
- }
148
-
149
- /** React reconciler update hook */
150
- updateConfig(changed: Record<string, any>): void {
151
- if ('value' in changed) this.setValue(changed.value);
152
- if ('currency' in changed) this.setCurrency(changed.currency);
153
- }
154
-
155
- override destroy(options?: boolean | { children?: boolean; texture?: boolean; textureSource?: boolean }): void {
156
- Tween.killTweensOf(this._tweenTarget);
157
- super.destroy(options);
158
- }
159
- }
package/src/ui/Button.ts DELETED
@@ -1,304 +0,0 @@
1
- import { Container, Graphics, Text } from 'pixi.js';
2
- import { Tween } from '../animation/Tween';
3
- import { Easing } from '../animation/Easing';
4
- import { resolveView } from './view';
5
- import type { ViewInput } from './view';
6
-
7
- export type ButtonState = 'default' | 'hover' | 'pressed' | 'disabled';
8
-
9
- export interface ButtonConfig {
10
- /** Custom view for default state (string texture name, Texture, or Container) */
11
- defaultView?: ViewInput;
12
- /** Custom view for hover state */
13
- hoverView?: ViewInput;
14
- /** Custom view for pressed state */
15
- pressedView?: ViewInput;
16
- /** Custom view for disabled state */
17
- disabledView?: ViewInput;
18
-
19
- /** Width (for Graphics-based button, ignored when custom views provided) */
20
- width?: number;
21
- /** Height (for Graphics-based button) */
22
- height?: number;
23
- /** Corner radius (for Graphics-based button) */
24
- borderRadius?: number;
25
- /** Colors for each state (for Graphics-based button) */
26
- colors?: Partial<Record<ButtonState, number>>;
27
-
28
- /** Scale on press */
29
- pressScale?: number;
30
- /** Scale animation duration (ms) */
31
- animationDuration?: number;
32
- /** Start disabled */
33
- disabled?: boolean;
34
- /** Button text (rendered on top of the view) */
35
- text?: string;
36
- /** Button text style */
37
- textStyle?: Record<string, unknown>;
38
- /** Press callback */
39
- onPress?: () => void;
40
- }
41
-
42
- const DEFAULT_COLORS: Record<ButtonState, number> = {
43
- default: 0xffd700,
44
- hover: 0xffe44d,
45
- pressed: 0xccac00,
46
- disabled: 0x666666,
47
- };
48
-
49
- function makeGraphicsView(
50
- w: number, h: number, radius: number, color: number,
51
- ): Graphics {
52
- const g = new Graphics();
53
- g.roundRect(-w / 2, -h / 2, w, h, radius).fill(color);
54
- return g;
55
- }
56
-
57
- /**
58
- * Interactive button with per-state custom views and animations.
59
- *
60
- * Each visual state accepts a `ViewInput`: texture name, Texture, or any Container
61
- * (Sprite, NineSliceSprite, AnimatedSprite, custom artwork, etc).
62
- * Falls back to colored Graphics when no custom view is provided.
63
- *
64
- * @example
65
- * ```ts
66
- * // Graphics-based (quick prototyping)
67
- * const btn = new Button({
68
- * width: 200, height: 60, borderRadius: 12,
69
- * colors: { default: 0x22aa22, hover: 0x33cc33 },
70
- * text: 'SPIN',
71
- * onPress: () => spin(),
72
- * });
73
- *
74
- * // Asset-based (production art)
75
- * const btn = new Button({
76
- * defaultView: 'btn-idle',
77
- * hoverView: 'btn-hover',
78
- * pressedView: 'btn-pressed',
79
- * disabledView: 'btn-disabled',
80
- * text: 'SPIN',
81
- * onPress: () => spin(),
82
- * });
83
- *
84
- * // Custom Container view
85
- * const btn = new Button({
86
- * defaultView: myAnimatedSprite,
87
- * text: 'SPIN',
88
- * });
89
- * ```
90
- */
91
- export class Button extends Container {
92
- readonly __uiComponent = true as const;
93
-
94
- private _views: Map<ButtonState, Container> = new Map();
95
- private _state: ButtonState = 'default';
96
- private _enabled = true;
97
- private _config: Required<
98
- Pick<ButtonConfig, 'width' | 'height' | 'borderRadius' | 'pressScale' | 'animationDuration'>
99
- > & ButtonConfig;
100
- private _textObj: Text | null = null;
101
-
102
- /** Press callback */
103
- public onPress?: () => void;
104
-
105
- constructor(config: ButtonConfig = {}) {
106
- super();
107
-
108
- this._config = {
109
- width: config.width ?? 200,
110
- height: config.height ?? 60,
111
- borderRadius: config.borderRadius ?? 8,
112
- pressScale: config.pressScale ?? 0.95,
113
- animationDuration: config.animationDuration ?? 100,
114
- ...config,
115
- };
116
-
117
- this.onPress = config.onPress;
118
- this._buildViews(config);
119
-
120
- // Text
121
- if (config.text) {
122
- this._textObj = new Text({
123
- text: config.text,
124
- style: {
125
- fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
126
- fontSize: 20,
127
- fill: 0xffffff,
128
- fontWeight: 'bold',
129
- ...config.textStyle,
130
- },
131
- });
132
- this._textObj.anchor.set(0.5);
133
- this.addChild(this._textObj);
134
- }
135
-
136
- // Interaction
137
- this.eventMode = 'static';
138
- this.cursor = 'pointer';
139
-
140
- this.on('pointerover', this._onPointerOver, this);
141
- this.on('pointerout', this._onPointerOut, this);
142
- this.on('pointerdown', this._onPointerDown, this);
143
- this.on('pointerup', this._onPointerUp, this);
144
- this.on('pointerupoutside', this._onPointerUpOutside, this);
145
-
146
- if (config.disabled) {
147
- this.enabled = false;
148
- }
149
- }
150
-
151
- /** Current button state */
152
- get state(): ButtonState {
153
- return this._state;
154
- }
155
-
156
- /** Enable the button */
157
- enable(): void {
158
- this.enabled = true;
159
- }
160
-
161
- /** Disable the button */
162
- disable(): void {
163
- this.enabled = false;
164
- }
165
-
166
- /** Whether the button is enabled */
167
- get enabled(): boolean {
168
- return this._enabled;
169
- }
170
-
171
- set enabled(value: boolean) {
172
- this._enabled = value;
173
- this.cursor = value ? 'pointer' : 'default';
174
- this.eventMode = value ? 'static' : 'none';
175
- this._setState(value ? 'default' : 'disabled');
176
- }
177
-
178
- /** Whether the button is disabled */
179
- get disabled(): boolean {
180
- return !this._enabled;
181
- }
182
-
183
- /** Update button text */
184
- set text(value: string) {
185
- if (this._textObj) {
186
- this._textObj.text = value;
187
- }
188
- }
189
-
190
- // ─── View building ──────────────────────────────────
191
-
192
- private _buildViews(config: ButtonConfig): void {
193
- const colorMap = { ...DEFAULT_COLORS, ...config.colors };
194
- const { width, height, borderRadius } = this._config;
195
- const stateViews: Record<ButtonState, ViewInput | undefined> = {
196
- default: config.defaultView,
197
- hover: config.hoverView,
198
- pressed: config.pressedView,
199
- disabled: config.disabledView,
200
- };
201
-
202
- const states: ButtonState[] = ['default', 'hover', 'pressed', 'disabled'];
203
-
204
- for (const state of states) {
205
- const customView = resolveView(stateViews[state]);
206
- const view = customView ?? makeGraphicsView(width, height, borderRadius, colorMap[state]);
207
- view.visible = state === 'default';
208
- this._views.set(state, view);
209
- this.addChild(view);
210
- }
211
- }
212
-
213
- private _rebuildViews(): void {
214
- for (const [, view] of this._views) {
215
- this.removeChild(view);
216
- view.destroy();
217
- }
218
- this._views.clear();
219
-
220
- this._buildViews(this._config);
221
-
222
- // Re-insert views before text
223
- if (this._textObj && this._textObj.parent === this) {
224
- this.setChildIndex(this._textObj, this.children.length - 1);
225
- }
226
- }
227
-
228
- // ─── State management ───────────────────────────────
229
-
230
- private _setState(state: ButtonState): void {
231
- if (this._state === state) return;
232
- this._state = state;
233
-
234
- for (const [s, view] of this._views) {
235
- view.visible = s === state;
236
- }
237
- }
238
-
239
- private _onPointerOver(): void {
240
- if (!this._enabled) return;
241
- this._setState('hover');
242
- Tween.killTweensOf(this);
243
- Tween.to(this, { 'scale.x': 1.03, 'scale.y': 1.03 }, this._config.animationDuration, Easing.easeOutQuad);
244
- }
245
-
246
- private _onPointerOut(): void {
247
- if (!this._enabled) return;
248
- this._setState('default');
249
- Tween.killTweensOf(this);
250
- Tween.to(this, { 'scale.x': 1, 'scale.y': 1 }, this._config.animationDuration, Easing.easeOutQuad);
251
- }
252
-
253
- private _onPointerDown(): void {
254
- if (!this._enabled) return;
255
- this._setState('pressed');
256
- Tween.killTweensOf(this);
257
- const s = this._config.pressScale;
258
- Tween.to(this, { 'scale.x': s, 'scale.y': s }, this._config.animationDuration, Easing.easeOutQuad);
259
- }
260
-
261
- private _onPointerUp(): void {
262
- if (!this._enabled) return;
263
- this._setState('hover');
264
- Tween.killTweensOf(this);
265
- Tween.to(this, { 'scale.x': 1.03, 'scale.y': 1.03 }, this._config.animationDuration, Easing.easeOutQuad);
266
- this.onPress?.();
267
- }
268
-
269
- private _onPointerUpOutside(): void {
270
- if (!this._enabled) return;
271
- this._setState('default');
272
- Tween.killTweensOf(this);
273
- Tween.to(this, { 'scale.x': 1, 'scale.y': 1 }, this._config.animationDuration, Easing.easeOutQuad);
274
- }
275
-
276
- /** React reconciler update hook */
277
- updateConfig(changed: Record<string, any>): void {
278
- if ('text' in changed && this._textObj) this._textObj.text = changed.text;
279
- if ('disabled' in changed) this.enabled = !changed.disabled;
280
- if ('onPress' in changed) this.onPress = changed.onPress;
281
-
282
- const structural = [
283
- 'colors', 'width', 'height', 'borderRadius', 'textStyle',
284
- 'defaultView', 'hoverView', 'pressedView', 'disabledView',
285
- ];
286
- const needsRebuild = structural.some((k) => k in changed);
287
- if (needsRebuild) {
288
- Object.assign(this._config, changed);
289
- this._rebuildViews();
290
- }
291
- }
292
-
293
- override destroy(options?: boolean | { children?: boolean; texture?: boolean; textureSource?: boolean }): void {
294
- Tween.killTweensOf(this);
295
- this.off('pointerover', this._onPointerOver, this);
296
- this.off('pointerout', this._onPointerOut, this);
297
- this.off('pointerdown', this._onPointerDown, this);
298
- this.off('pointerup', this._onPointerUp, this);
299
- this.off('pointerupoutside', this._onPointerUpOutside, this);
300
- this._views.clear();
301
- this._textObj = null;
302
- super.destroy(options);
303
- }
304
- }