pixi-reels 0.1.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.
- package/LICENSE +28 -0
- package/README.md +167 -0
- package/dist/SpineSymbol-B40TevSr.cjs +2 -0
- package/dist/SpineSymbol-B40TevSr.cjs.map +1 -0
- package/dist/SpineSymbol-D2jhCzFW.js +82 -0
- package/dist/SpineSymbol-D2jhCzFW.js.map +1 -0
- package/dist/config/SpeedPresets.d.ts +49 -0
- package/dist/config/SpeedPresets.d.ts.map +1 -0
- package/dist/config/defaults.d.ts +12 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/types.d.ts +93 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/core/Reel.d.ts +106 -0
- package/dist/core/Reel.d.ts.map +1 -0
- package/dist/core/ReelMotion.d.ts +43 -0
- package/dist/core/ReelMotion.d.ts.map +1 -0
- package/dist/core/ReelSet.d.ts +101 -0
- package/dist/core/ReelSet.d.ts.map +1 -0
- package/dist/core/ReelSetBuilder.d.ts +102 -0
- package/dist/core/ReelSetBuilder.d.ts.map +1 -0
- package/dist/core/ReelViewport.d.ts +43 -0
- package/dist/core/ReelViewport.d.ts.map +1 -0
- package/dist/core/StopSequencer.d.ts +26 -0
- package/dist/core/StopSequencer.d.ts.map +1 -0
- package/dist/debug/debug.d.ts +65 -0
- package/dist/debug/debug.d.ts.map +1 -0
- package/dist/events/EventEmitter.d.ts +25 -0
- package/dist/events/EventEmitter.d.ts.map +1 -0
- package/dist/events/ReelEvents.d.ts +40 -0
- package/dist/events/ReelEvents.d.ts.map +1 -0
- package/dist/frame/FrameBuilder.d.ts +50 -0
- package/dist/frame/FrameBuilder.d.ts.map +1 -0
- package/dist/frame/OffsetCalculator.d.ts +19 -0
- package/dist/frame/OffsetCalculator.d.ts.map +1 -0
- package/dist/frame/RandomSymbolProvider.d.ts +27 -0
- package/dist/frame/RandomSymbolProvider.d.ts.map +1 -0
- package/dist/index.cjs +5 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1454 -0
- package/dist/index.js.map +1 -0
- package/dist/pool/ObjectPool.d.ts +36 -0
- package/dist/pool/ObjectPool.d.ts.map +1 -0
- package/dist/speed/SpeedManager.d.ts +38 -0
- package/dist/speed/SpeedManager.d.ts.map +1 -0
- package/dist/spin/SpinController.d.ts +71 -0
- package/dist/spin/SpinController.d.ts.map +1 -0
- package/dist/spin/modes/CascadeMode.d.ts +16 -0
- package/dist/spin/modes/CascadeMode.d.ts.map +1 -0
- package/dist/spin/modes/ImmediateMode.d.ts +10 -0
- package/dist/spin/modes/ImmediateMode.d.ts.map +1 -0
- package/dist/spin/modes/SpinningMode.d.ts +18 -0
- package/dist/spin/modes/SpinningMode.d.ts.map +1 -0
- package/dist/spin/modes/StandardMode.d.ts +10 -0
- package/dist/spin/modes/StandardMode.d.ts.map +1 -0
- package/dist/spin/phases/AnticipationPhase.d.ts +24 -0
- package/dist/spin/phases/AnticipationPhase.d.ts.map +1 -0
- package/dist/spin/phases/PhaseFactory.d.ts +21 -0
- package/dist/spin/phases/PhaseFactory.d.ts.map +1 -0
- package/dist/spin/phases/ReelPhase.d.ts +39 -0
- package/dist/spin/phases/ReelPhase.d.ts.map +1 -0
- package/dist/spin/phases/SpinPhase.d.ts +25 -0
- package/dist/spin/phases/SpinPhase.d.ts.map +1 -0
- package/dist/spin/phases/StartPhase.d.ts +26 -0
- package/dist/spin/phases/StartPhase.d.ts.map +1 -0
- package/dist/spin/phases/StopPhase.d.ts +37 -0
- package/dist/spin/phases/StopPhase.d.ts.map +1 -0
- package/dist/spine/SpineReelSymbol.d.ts +111 -0
- package/dist/spine/SpineReelSymbol.d.ts.map +1 -0
- package/dist/spine/index.d.ts +5 -0
- package/dist/spine/index.d.ts.map +1 -0
- package/dist/spine.cjs +2 -0
- package/dist/spine.cjs.map +1 -0
- package/dist/spine.js +123 -0
- package/dist/spine.js.map +1 -0
- package/dist/spotlight/SymbolSpotlight.d.ts +70 -0
- package/dist/spotlight/SymbolSpotlight.d.ts.map +1 -0
- package/dist/symbols/AnimatedSpriteSymbol.d.ts +30 -0
- package/dist/symbols/AnimatedSpriteSymbol.d.ts.map +1 -0
- package/dist/symbols/ReelSymbol.d.ts +84 -0
- package/dist/symbols/ReelSymbol.d.ts.map +1 -0
- package/dist/symbols/SpineSymbol.d.ts +34 -0
- package/dist/symbols/SpineSymbol.d.ts.map +1 -0
- package/dist/symbols/SpriteSymbol.d.ts +29 -0
- package/dist/symbols/SpriteSymbol.d.ts.map +1 -0
- package/dist/symbols/SymbolFactory.d.ts +20 -0
- package/dist/symbols/SymbolFactory.d.ts.map +1 -0
- package/dist/symbols/SymbolRegistry.d.ts +25 -0
- package/dist/symbols/SymbolRegistry.d.ts.map +1 -0
- package/dist/testing/FakeTicker.d.ts +45 -0
- package/dist/testing/FakeTicker.d.ts.map +1 -0
- package/dist/testing/HeadlessSymbol.d.ts +28 -0
- package/dist/testing/HeadlessSymbol.d.ts.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/testHarness.d.ts +70 -0
- package/dist/testing/testHarness.d.ts.map +1 -0
- package/dist/utils/Disposable.d.ts +10 -0
- package/dist/utils/Disposable.d.ts.map +1 -0
- package/dist/utils/TickerRef.d.ts +30 -0
- package/dist/utils/TickerRef.d.ts.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ReelSymbol } from '../symbols/ReelSymbol.js';
|
|
2
|
+
/**
|
|
3
|
+
* The physics of one reel — move symbols down, wrap them around.
|
|
4
|
+
*
|
|
5
|
+
* Every frame, `ReelMotion.update(delta)` adds `delta` to each symbol's
|
|
6
|
+
* Y coordinate. A symbol whose position falls off the bottom wraps back
|
|
7
|
+
* to the top (and vice versa — reels can run upward). Each wrap fires
|
|
8
|
+
* the `_onSymbolWrapped` callback so the owning `Reel` can ask the
|
|
9
|
+
* `FrameBuilder` for the next identity to paint on it.
|
|
10
|
+
*
|
|
11
|
+
* Maintains the invariant that `_symbols[0]` is always the visually
|
|
12
|
+
* topmost symbol and `_symbols[N-1]` is always the bottommost. On each
|
|
13
|
+
* wrap, the wrapping symbol is moved to the front (or back) of the array
|
|
14
|
+
* so the ordering stays consistent with the grid. `snapToGrid` and the
|
|
15
|
+
* visible window selection rely on this.
|
|
16
|
+
*/
|
|
17
|
+
export declare class ReelMotion {
|
|
18
|
+
private _symbols;
|
|
19
|
+
private _bufferAbove;
|
|
20
|
+
private _onSymbolWrapped;
|
|
21
|
+
private _symbolHeight;
|
|
22
|
+
private _symbolGapY;
|
|
23
|
+
private _slotHeight;
|
|
24
|
+
private _minY;
|
|
25
|
+
private _maxY;
|
|
26
|
+
constructor(_symbols: ReelSymbol[], symbolHeight: number, symbolGapY: number, _bufferAbove: number, visibleRows: number, _onSymbolWrapped: (symbol: ReelSymbol, arrayIndex: number, direction: 'up' | 'down') => void);
|
|
27
|
+
/**
|
|
28
|
+
* Move all symbols by deltaY pixels (positive = downward).
|
|
29
|
+
* At most one wrap per call (deltaY is capped at half a symbol by the
|
|
30
|
+
* spinning mode, so a single symbol can cross the boundary per tick).
|
|
31
|
+
*/
|
|
32
|
+
displace(deltaY: number): void;
|
|
33
|
+
/** Snap all symbols to their correct grid positions (array index = visual row). */
|
|
34
|
+
snapToGrid(): void;
|
|
35
|
+
/** Position all symbols above the visible area (for cascade mode start). */
|
|
36
|
+
setToTopPosition(): void;
|
|
37
|
+
/** Get the correct Y position for a symbol at a given row. */
|
|
38
|
+
getRowY(row: number): number;
|
|
39
|
+
get slotHeight(): number;
|
|
40
|
+
private _wrapBottomToTop;
|
|
41
|
+
private _wrapTopToBottom;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=ReelMotion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReelMotion.d.ts","sourceRoot":"","sources":["../../src/core/ReelMotion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D;;;;;;;;;;;;;;GAcG;AACH,qBAAa,UAAU;IAQnB,OAAO,CAAC,QAAQ;IAGhB,OAAO,CAAC,YAAY;IAEpB,OAAO,CAAC,gBAAgB;IAZ1B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAS;gBAGZ,QAAQ,EAAE,UAAU,EAAE,EAC9B,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EACV,YAAY,EAAE,MAAM,EAC5B,WAAW,EAAE,MAAM,EACX,gBAAgB,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI;IAStG;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAY9B,mFAAmF;IACnF,UAAU,IAAI,IAAI;IAOlB,4EAA4E;IAC5E,gBAAgB,IAAI,IAAI;IAMxB,8DAA8D;IAC9D,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAI5B,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,gBAAgB;CAUzB"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Container } from 'pixi.js';
|
|
2
|
+
import { Disposable } from '../utils/Disposable.js';
|
|
3
|
+
import { ReelSetInternalConfig } from '../config/types.js';
|
|
4
|
+
import { EventEmitter } from '../events/EventEmitter.js';
|
|
5
|
+
import { ReelSetEvents, SpinResult } from '../events/ReelEvents.js';
|
|
6
|
+
import { Reel } from './Reel.js';
|
|
7
|
+
import { ReelViewport } from './ReelViewport.js';
|
|
8
|
+
import { SpeedManager } from '../speed/SpeedManager.js';
|
|
9
|
+
import { SymbolSpotlight } from '../spotlight/SymbolSpotlight.js';
|
|
10
|
+
import { SymbolFactory } from '../symbols/SymbolFactory.js';
|
|
11
|
+
import { FrameBuilder } from '../frame/FrameBuilder.js';
|
|
12
|
+
import { PhaseFactory } from '../spin/phases/PhaseFactory.js';
|
|
13
|
+
import { SpinningMode } from '../spin/modes/SpinningMode.js';
|
|
14
|
+
export interface ReelSetParams {
|
|
15
|
+
config: ReelSetInternalConfig;
|
|
16
|
+
reels: Reel[];
|
|
17
|
+
viewport: ReelViewport;
|
|
18
|
+
symbolFactory: SymbolFactory;
|
|
19
|
+
frameBuilder: FrameBuilder;
|
|
20
|
+
phaseFactory: PhaseFactory;
|
|
21
|
+
spinningMode: SpinningMode;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The whole slot board as one object.
|
|
25
|
+
*
|
|
26
|
+
* A `ReelSet` is a PixiJS `Container` that owns every reel, the spin
|
|
27
|
+
* controller, the speed manager, and the win spotlight. You `addChild` it
|
|
28
|
+
* to your stage and then drive it from the four public verbs below:
|
|
29
|
+
*
|
|
30
|
+
* - `spin()` — start the reels moving, returns a promise that resolves
|
|
31
|
+
* when every reel has landed (or been slam-stopped)
|
|
32
|
+
* - `setResult(grid)` — tell the reels what to land on; the spin
|
|
33
|
+
* controller consumes this and each reel queues its target symbols
|
|
34
|
+
* - `setAnticipation(reelIndices)` — slow the given reels before they
|
|
35
|
+
* stop, for "will the third scatter land?" tension
|
|
36
|
+
* - `skip()` — land immediately; useful for slam-stop UX
|
|
37
|
+
*
|
|
38
|
+
* Everything else is subsystems: `speed`, `spotlight`, `events`, `viewport`.
|
|
39
|
+
* Construction goes through {@link ReelSetBuilder}, never `new ReelSet()`
|
|
40
|
+
* directly — the builder enforces that every required piece is wired.
|
|
41
|
+
*
|
|
42
|
+
* ```ts
|
|
43
|
+
* const reelSet = new ReelSetBuilder()
|
|
44
|
+
* .reels(5).visibleSymbols(3).symbolSize(140, 140)
|
|
45
|
+
* .symbols((r) => r.register('cherry', SpriteSymbol, { textures }))
|
|
46
|
+
* .ticker(app.ticker)
|
|
47
|
+
* .build();
|
|
48
|
+
* app.stage.addChild(reelSet);
|
|
49
|
+
*
|
|
50
|
+
* const spin = reelSet.spin();
|
|
51
|
+
* reelSet.setResult(await server.spin());
|
|
52
|
+
* await spin;
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* Teardown cascades: one `reelSet.destroy()` disposes every child.
|
|
56
|
+
*/
|
|
57
|
+
export declare class ReelSet extends Container implements Disposable {
|
|
58
|
+
private _events;
|
|
59
|
+
private _reels;
|
|
60
|
+
private _viewport;
|
|
61
|
+
private _spinController;
|
|
62
|
+
private _speedManager;
|
|
63
|
+
private _spotlight;
|
|
64
|
+
private _symbolFactory;
|
|
65
|
+
private _isDestroyed;
|
|
66
|
+
constructor(params: ReelSetParams);
|
|
67
|
+
/** The event emitter for reel-specific events. */
|
|
68
|
+
get events(): EventEmitter<ReelSetEvents>;
|
|
69
|
+
/** Start spinning all reels. Returns a promise that resolves when all reels land. */
|
|
70
|
+
spin(): Promise<SpinResult>;
|
|
71
|
+
/** Set the target result symbols. Triggers the stop sequence. */
|
|
72
|
+
setResult(symbols: string[][]): void;
|
|
73
|
+
/** Set which reels should show anticipation before stopping. */
|
|
74
|
+
setAnticipation(reelIndices: number[]): void;
|
|
75
|
+
/**
|
|
76
|
+
* Override the per-reel stop delay for the current spin (in ms).
|
|
77
|
+
* Pass one value per reel. Cleared at the start of each new spin.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* // Stagger the last two reels more than the default for dramatic effect:
|
|
81
|
+
* reelSet.setStopDelays([0, 140, 280, 600, 1100]);
|
|
82
|
+
*/
|
|
83
|
+
setStopDelays(delays: number[]): void;
|
|
84
|
+
/** Skip/slam-stop: immediately land all reels on target. */
|
|
85
|
+
skip(): void;
|
|
86
|
+
get isSpinning(): boolean;
|
|
87
|
+
/** Speed profile manager. */
|
|
88
|
+
get speed(): SpeedManager;
|
|
89
|
+
/** Change speed and emit event. */
|
|
90
|
+
setSpeed(name: string): void;
|
|
91
|
+
get spotlight(): SymbolSpotlight;
|
|
92
|
+
/** Get all reels. */
|
|
93
|
+
get reels(): readonly Reel[];
|
|
94
|
+
/** Get a reel by index. */
|
|
95
|
+
getReel(index: number): Reel;
|
|
96
|
+
/** Get the viewport. */
|
|
97
|
+
get viewport(): ReelViewport;
|
|
98
|
+
get isDestroyed(): boolean;
|
|
99
|
+
destroy(): void;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=ReelSet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReelSet.d.ts","sourceRoot":"","sources":["../../src/core/ReelSet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAgB,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAkB,MAAM,yBAAyB,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,eAAe,EAA0D,MAAM,iCAAiC,CAAC;AAC1H,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,qBAAqB,CAAC;IAC9B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,QAAQ,EAAE,YAAY,CAAC;IACvB,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBAAa,OAAQ,SAAQ,SAAU,YAAW,UAAU;IAC1D,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,YAAY,CAAS;gBAEjB,MAAM,EAAE,aAAa;IAkCjC,kDAAkD;IAClD,IAAI,MAAM,IAAI,YAAY,CAAC,aAAa,CAAC,CAExC;IAID,qFAAqF;IAC/E,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;IAIjC,iEAAiE;IACjE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI;IAIpC,gEAAgE;IAChE,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,IAAI;IAI5C;;;;;;;OAOG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAIrC,4DAA4D;IAC5D,IAAI,IAAI,IAAI;IAIZ,IAAI,UAAU,IAAI,OAAO,CAExB;IAID,6BAA6B;IAC7B,IAAI,KAAK,IAAI,YAAY,CAExB;IAED,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAO5B,IAAI,SAAS,IAAI,eAAe,CAE/B;IAID,qBAAqB;IACrB,IAAI,KAAK,IAAI,SAAS,IAAI,EAAE,CAE3B;IAED,2BAA2B;IAC3B,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI5B,wBAAwB;IACxB,IAAI,QAAQ,IAAI,YAAY,CAE3B;IAID,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,OAAO,IAAI,IAAI;CAkBhB"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { Ticker } from 'pixi.js';
|
|
2
|
+
import { SpeedProfile, SymbolData, OffsetConfig } from '../config/types.js';
|
|
3
|
+
import { ReelSet } from './ReelSet.js';
|
|
4
|
+
import { SymbolRegistry } from '../symbols/SymbolRegistry.js';
|
|
5
|
+
import { PhaseFactory } from '../spin/phases/PhaseFactory.js';
|
|
6
|
+
import { SpinningMode } from '../spin/modes/SpinningMode.js';
|
|
7
|
+
import { FrameMiddleware } from '../frame/FrameBuilder.js';
|
|
8
|
+
/**
|
|
9
|
+
* The configurator you call before every reel set.
|
|
10
|
+
*
|
|
11
|
+
* `ReelSetBuilder` is a fluent, chainable builder: every call returns the
|
|
12
|
+
* builder so you can string setup onto one expression. It exists for two
|
|
13
|
+
* reasons — it hides the twenty-odd subsystems you'd otherwise have to
|
|
14
|
+
* wire by hand, and its `.build()` step validates that every required
|
|
15
|
+
* piece is present (throws at construction, not at first spin).
|
|
16
|
+
*
|
|
17
|
+
* Required calls (in any order): `.reels(n)`, `.visibleSymbols(n)`,
|
|
18
|
+
* `.symbolSize(w, h)`, `.symbols((registry) => ...)`, `.ticker(app.ticker)`.
|
|
19
|
+
* Optional: `.symbolGap()`, `.weights()`, `.symbolData()`, `.speed()`,
|
|
20
|
+
* `.bufferSymbols()`, `.offset()`, `.frameMiddleware()`, `.phases()`,
|
|
21
|
+
* `.spinningMode()`.
|
|
22
|
+
*
|
|
23
|
+
* Reduces ~100 lines of manual wiring to ~10 lines of configuration.
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* const reelSet = new ReelSetBuilder()
|
|
27
|
+
* .reels(5)
|
|
28
|
+
* .visibleSymbols(3)
|
|
29
|
+
* .symbolSize(200, 200)
|
|
30
|
+
* .symbols((r) => {
|
|
31
|
+
* r.register('cherry', SpriteSymbol, { textures: { cherry: tex } });
|
|
32
|
+
* })
|
|
33
|
+
* .weights({ cherry: 20 })
|
|
34
|
+
* .ticker(app.ticker)
|
|
35
|
+
* .build();
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare class ReelSetBuilder {
|
|
39
|
+
private _reelCount?;
|
|
40
|
+
private _visibleRows?;
|
|
41
|
+
private _symbolWidth?;
|
|
42
|
+
private _symbolHeight?;
|
|
43
|
+
private _symbolGap;
|
|
44
|
+
private _bufferSymbols;
|
|
45
|
+
private _symbolRegistry;
|
|
46
|
+
private _weights;
|
|
47
|
+
private _speeds;
|
|
48
|
+
private _initialSpeed;
|
|
49
|
+
private _offset;
|
|
50
|
+
private _ticker?;
|
|
51
|
+
private _spinningMode;
|
|
52
|
+
private _phaseFactory;
|
|
53
|
+
private _middlewares;
|
|
54
|
+
private _initialFrame?;
|
|
55
|
+
private _symbolDataOverrides;
|
|
56
|
+
/** Set number of reel columns. */
|
|
57
|
+
reels(count: number): this;
|
|
58
|
+
/** Set number of visible symbol rows per reel. */
|
|
59
|
+
visibleSymbols(count: number): this;
|
|
60
|
+
/** Set symbol dimensions in pixels. */
|
|
61
|
+
symbolSize(width: number, height: number): this;
|
|
62
|
+
/** Set gap between symbols. Default: { x: 0, y: 0 }. */
|
|
63
|
+
symbolGap(x: number, y: number): this;
|
|
64
|
+
/** Set number of buffer symbols above/below visible area. Default: 1. */
|
|
65
|
+
bufferSymbols(count: number): this;
|
|
66
|
+
/** Configure symbols via a registry callback. */
|
|
67
|
+
symbols(configurator: (registry: SymbolRegistry) => void): this;
|
|
68
|
+
/** Set weights for random symbol generation. */
|
|
69
|
+
weights(weights: Record<string, number>): this;
|
|
70
|
+
/**
|
|
71
|
+
* Per-symbol metadata overrides (zIndex, unmask, or a custom weight that
|
|
72
|
+
* replaces the one from `weights()`). Merged into the final symbolsData map
|
|
73
|
+
* — any field you don't specify falls back to the default.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* .symbolData({
|
|
77
|
+
* wild: { zIndex: 5 }, // render above neighbours
|
|
78
|
+
* bonus: { zIndex: 10, unmask: true }, // render outside the reel mask
|
|
79
|
+
* })
|
|
80
|
+
*/
|
|
81
|
+
symbolData(overrides: Record<string, Partial<SymbolData>>): this;
|
|
82
|
+
/** Add a named speed profile. */
|
|
83
|
+
speed(name: string, profile: SpeedProfile): this;
|
|
84
|
+
/** Set which speed profile to use initially. Default: 'normal'. */
|
|
85
|
+
initialSpeed(name: string): this;
|
|
86
|
+
/** Set X-axis offset config (e.g., trapezoid perspective). Default: 'none'. */
|
|
87
|
+
offsetConfig(config: OffsetConfig): this;
|
|
88
|
+
/** Set the PixiJS ticker for frame updates. */
|
|
89
|
+
ticker(ticker: Ticker): this;
|
|
90
|
+
/** Set the spinning mode. Default: StandardMode. */
|
|
91
|
+
spinningMode(mode: SpinningMode): this;
|
|
92
|
+
/** Add custom frame middleware. */
|
|
93
|
+
frameMiddleware(middleware: FrameMiddleware): this;
|
|
94
|
+
/** Override default phases. */
|
|
95
|
+
phases(configurator: (factory: PhaseFactory) => void): this;
|
|
96
|
+
/** Set the initial symbol grid (visible symbols only). */
|
|
97
|
+
initialFrame(frame: string[][]): this;
|
|
98
|
+
/** Build the ReelSet. Validates configuration and assembles all internal objects. */
|
|
99
|
+
build(): ReelSet;
|
|
100
|
+
private _validate;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=ReelSetBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReelSetBuilder.d.ts","sourceRoot":"","sources":["../../src/core/ReelSetBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAyB,MAAM,oBAAoB,CAAC;AAGxG,OAAO,EAAE,OAAO,EAAsB,MAAM,cAAc,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAK9D,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAGhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,eAAe,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,aAAa,CAAyB;IAC9C,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,aAAa,CAAC,CAAa;IACnC,OAAO,CAAC,oBAAoB,CAA2C;IAEvE,kCAAkC;IAClC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK1B,kDAAkD;IAClD,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKnC,uCAAuC;IACvC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAM/C,wDAAwD;IACxD,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAKrC,yEAAyE;IACzE,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKlC,iDAAiD;IACjD,OAAO,CAAC,YAAY,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI;IAK/D,gDAAgD;IAChD,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAK9C;;;;;;;;;;OAUG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,IAAI;IAKhE,iCAAiC;IACjC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAKhD,mEAAmE;IACnE,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKhC,+EAA+E;IAC/E,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAKxC,+CAA+C;IAC/C,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK5B,oDAAoD;IACpD,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAKtC,mCAAmC;IACnC,eAAe,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI;IAKlD,+BAA+B;IAC/B,MAAM,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAK3D,0DAA0D;IAC1D,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI;IAKrC,qFAAqF;IACrF,KAAK,IAAI,OAAO;IA4GhB,OAAO,CAAC,SAAS;CA6BlB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Container, Graphics } from 'pixi.js';
|
|
2
|
+
import { Disposable } from '../utils/Disposable.js';
|
|
3
|
+
/**
|
|
4
|
+
* The clipping window + layering tricks for a reel set.
|
|
5
|
+
*
|
|
6
|
+
* The viewport is the "looking-glass" of the slot: a rectangle the size
|
|
7
|
+
* of the visible grid with a PixiJS mask so symbols scrolling above or
|
|
8
|
+
* below the visible rows are hidden. It also provides three stacking
|
|
9
|
+
* layers so win animations can break out of the mask:
|
|
10
|
+
*
|
|
11
|
+
* - `maskedContainer` — the normal place for reels. Clipped to the
|
|
12
|
+
* visible area so buffer rows never leak.
|
|
13
|
+
* - `unmaskedContainer` — rendered on top of the mask. Use for a symbol
|
|
14
|
+
* whose celebration animation expands beyond its cell (a big expanding
|
|
15
|
+
* wild, a splash frame).
|
|
16
|
+
* - `spotlightContainer` — above everything else. Win spotlight lifts
|
|
17
|
+
* winning symbols here temporarily so dim overlay + bounce don't clip.
|
|
18
|
+
*
|
|
19
|
+
* `dimOverlay` is a semi-transparent rectangle the spotlight fades in
|
|
20
|
+
* behind the promoted winners to visually push the losers into the
|
|
21
|
+
* background.
|
|
22
|
+
*/
|
|
23
|
+
export declare class ReelViewport extends Container implements Disposable {
|
|
24
|
+
readonly maskedContainer: Container;
|
|
25
|
+
readonly unmaskedContainer: Container;
|
|
26
|
+
readonly spotlightContainer: Container;
|
|
27
|
+
readonly dimOverlay: Graphics;
|
|
28
|
+
private _mask;
|
|
29
|
+
private _isDestroyed;
|
|
30
|
+
constructor(width: number, height: number, position?: {
|
|
31
|
+
x: number;
|
|
32
|
+
y: number;
|
|
33
|
+
});
|
|
34
|
+
get isDestroyed(): boolean;
|
|
35
|
+
/** Show the dim overlay with given opacity. */
|
|
36
|
+
showDim(alpha?: number): void;
|
|
37
|
+
/** Hide the dim overlay. */
|
|
38
|
+
hideDim(): void;
|
|
39
|
+
/** Update mask size (e.g., for Megaways variable rows). */
|
|
40
|
+
updateMaskSize(width: number, height: number): void;
|
|
41
|
+
destroy(): void;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=ReelViewport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReelViewport.d.ts","sourceRoot":"","sources":["../../src/core/ReelViewport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,YAAa,SAAQ,SAAU,YAAW,UAAU;IAC/D,SAAgB,eAAe,EAAE,SAAS,CAAC;IAC3C,SAAgB,iBAAiB,EAAE,SAAS,CAAC;IAC7C,SAAgB,kBAAkB,EAAE,SAAS,CAAC;IAC9C,SAAgB,UAAU,EAAE,QAAQ,CAAC;IAErC,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,YAAY,CAAS;gBAG3B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAmB;IAkCrD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,+CAA+C;IAC/C,OAAO,CAAC,KAAK,GAAE,MAAY,GAAG,IAAI;IAKlC,4BAA4B;IAC5B,OAAO,IAAI,IAAI;IAIf,2DAA2D;IAC3D,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAKnD,OAAO,IAAI,IAAI;CAKhB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The "what do I land on" queue for one reel.
|
|
3
|
+
*
|
|
4
|
+
* When a reel enters its stop phase, the `SpinController` loads the
|
|
5
|
+
* target frame (the exact list of symbol ids that should appear on
|
|
6
|
+
* screen, top-to-bottom, including the off-screen buffers). As the reel
|
|
7
|
+
* keeps scrolling downward during deceleration, every `ReelMotion` wrap
|
|
8
|
+
* event asks this sequencer for the next symbol — and it hands them back
|
|
9
|
+
* from the END of the frame first, because new symbols arrive at the
|
|
10
|
+
* top of a reel scrolling downward.
|
|
11
|
+
*
|
|
12
|
+
* After the last symbol is consumed the reel lands, and what you see on
|
|
13
|
+
* screen matches the loaded frame exactly.
|
|
14
|
+
*/
|
|
15
|
+
export declare class StopSequencer {
|
|
16
|
+
private _frame;
|
|
17
|
+
private _remaining;
|
|
18
|
+
/** Load a target frame in top-to-bottom order. */
|
|
19
|
+
setFrame(frame: string[]): void;
|
|
20
|
+
/** Deliver the next symbol (consumed from the end of the frame). */
|
|
21
|
+
next(): string;
|
|
22
|
+
get hasRemaining(): boolean;
|
|
23
|
+
get remaining(): number;
|
|
24
|
+
reset(): void;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=StopSequencer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StopSequencer.d.ts","sourceRoot":"","sources":["../../src/core/StopSequencer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,UAAU,CAAa;IAE/B,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAK/B,oEAAoE;IACpE,IAAI,IAAI,MAAM;IAQd,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,KAAK,IAAI,IAAI;CAId"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ReelSet } from '../core/ReelSet.js';
|
|
2
|
+
/**
|
|
3
|
+
* Debug snapshot — plain JSON representation of the entire reel state.
|
|
4
|
+
*
|
|
5
|
+
* Designed for AI agents that cannot see the canvas.
|
|
6
|
+
* Returns no PixiJS display objects, only serializable data.
|
|
7
|
+
*/
|
|
8
|
+
export interface DebugSnapshot {
|
|
9
|
+
timestamp: number;
|
|
10
|
+
isSpinning: boolean;
|
|
11
|
+
currentSpeed: string;
|
|
12
|
+
availableSpeeds: string[];
|
|
13
|
+
spotlightActive: boolean;
|
|
14
|
+
reelCount: number;
|
|
15
|
+
visibleRows: number;
|
|
16
|
+
reels: DebugReelSnapshot[];
|
|
17
|
+
grid: string[][];
|
|
18
|
+
}
|
|
19
|
+
export interface DebugReelSnapshot {
|
|
20
|
+
index: number;
|
|
21
|
+
speed: number;
|
|
22
|
+
isStopping: boolean;
|
|
23
|
+
allSymbols: {
|
|
24
|
+
row: number;
|
|
25
|
+
symbolId: string;
|
|
26
|
+
y: number;
|
|
27
|
+
}[];
|
|
28
|
+
visibleSymbols: string[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Take a plain-JSON snapshot of the entire reel set state.
|
|
32
|
+
*
|
|
33
|
+
* This is the primary debugging tool for AI agents. The output is
|
|
34
|
+
* a serializable object with no circular references, no PixiJS types.
|
|
35
|
+
*
|
|
36
|
+
* ```ts
|
|
37
|
+
* const state = debugSnapshot(reelSet);
|
|
38
|
+
* console.log(JSON.stringify(state, null, 2));
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function debugSnapshot(reelSet: ReelSet): DebugSnapshot;
|
|
42
|
+
/**
|
|
43
|
+
* Pretty-print the grid as an ASCII table.
|
|
44
|
+
*
|
|
45
|
+
* ```
|
|
46
|
+
* ┌────────┬────────┬────────┬────────┬────────┐
|
|
47
|
+
* │ cherry │ lemon │ bar │ seven │ cherry │
|
|
48
|
+
* │ plum │ cherry │ wild │ lemon │ orange │
|
|
49
|
+
* │ orange │ bell │ cherry │ plum │ bell │
|
|
50
|
+
* └────────┴────────┴────────┴────────┴────────┘
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function debugGrid(reelSet: ReelSet): string;
|
|
54
|
+
/**
|
|
55
|
+
* Enable debug mode: attaches debug utilities to `window.__PIXI_REELS_DEBUG`.
|
|
56
|
+
*
|
|
57
|
+
* After calling this, an AI agent can run in the browser console:
|
|
58
|
+
* ```js
|
|
59
|
+
* __PIXI_REELS_DEBUG.snapshot() // full state JSON
|
|
60
|
+
* __PIXI_REELS_DEBUG.grid() // ASCII grid
|
|
61
|
+
* __PIXI_REELS_DEBUG.log() // console.log the grid
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare function enableDebug(reelSet: ReelSet): void;
|
|
65
|
+
//# sourceMappingURL=debug.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../src/debug/debug.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAGlD;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3D,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CA+B7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAqBlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgClD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight typed event emitter with zero dependencies.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* ```ts
|
|
6
|
+
* interface MyEvents {
|
|
7
|
+
* 'foo': [x: number, y: string];
|
|
8
|
+
* 'bar': [];
|
|
9
|
+
* }
|
|
10
|
+
* const emitter = new EventEmitter<MyEvents>();
|
|
11
|
+
* emitter.on('foo', (x, y) => console.log(x, y));
|
|
12
|
+
* emitter.emit('foo', 42, 'hello');
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare class EventEmitter<TEvents extends Record<string, unknown[]>> {
|
|
16
|
+
private _listeners;
|
|
17
|
+
on<K extends keyof TEvents>(event: K, fn: (...args: TEvents[K]) => void, context?: unknown): this;
|
|
18
|
+
once<K extends keyof TEvents>(event: K, fn: (...args: TEvents[K]) => void, context?: unknown): this;
|
|
19
|
+
off<K extends keyof TEvents>(event: K, fn?: (...args: TEvents[K]) => void, context?: unknown): this;
|
|
20
|
+
emit<K extends keyof TEvents>(event: K, ...args: TEvents[K]): boolean;
|
|
21
|
+
removeAllListeners(event?: keyof TEvents): this;
|
|
22
|
+
listenerCount(event: keyof TEvents): number;
|
|
23
|
+
private _add;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=EventEmitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventEmitter.d.ts","sourceRoot":"","sources":["../../src/events/EventEmitter.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;GAaG;AACH,qBAAa,YAAY,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IACjE,OAAO,CAAC,UAAU,CAA6C;IAE/D,EAAE,CAAC,CAAC,SAAS,MAAM,OAAO,EACxB,KAAK,EAAE,CAAC,EACR,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,EACjC,OAAO,CAAC,EAAE,OAAO,GAChB,IAAI;IAIP,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAC1B,KAAK,EAAE,CAAC,EACR,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,EACjC,OAAO,CAAC,EAAE,OAAO,GAChB,IAAI;IAIP,GAAG,CAAC,CAAC,SAAS,MAAM,OAAO,EACzB,KAAK,EAAE,CAAC,EACR,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,EAClC,OAAO,CAAC,EAAE,OAAO,GAChB,IAAI;IAoBP,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO;IAerE,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,OAAO,GAAG,IAAI;IAS/C,aAAa,CAAC,KAAK,EAAE,MAAM,OAAO,GAAG,MAAM;IAI3C,OAAO,CAAC,IAAI;CAcb"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { SpeedProfile } from '../config/types.js';
|
|
2
|
+
/** Position of a symbol on the reel grid. */
|
|
3
|
+
export interface SymbolPosition {
|
|
4
|
+
reelIndex: number;
|
|
5
|
+
rowIndex: number;
|
|
6
|
+
}
|
|
7
|
+
/** Result returned when a spin completes. */
|
|
8
|
+
export interface SpinResult {
|
|
9
|
+
/** Final symbol grid [reelIndex][rowIndex]. */
|
|
10
|
+
symbols: string[][];
|
|
11
|
+
/** Whether the spin was skipped/slam-stopped. */
|
|
12
|
+
wasSkipped: boolean;
|
|
13
|
+
/** Total spin duration in milliseconds. */
|
|
14
|
+
duration: number;
|
|
15
|
+
}
|
|
16
|
+
/** Events emitted by a ReelSet. */
|
|
17
|
+
export interface ReelSetEvents extends Record<string, unknown[]> {
|
|
18
|
+
'spin:start': [];
|
|
19
|
+
'spin:allStarted': [];
|
|
20
|
+
'spin:stopping': [reelIndex: number];
|
|
21
|
+
'spin:reelLanded': [reelIndex: number, symbols: string[]];
|
|
22
|
+
'spin:allLanded': [result: SpinResult];
|
|
23
|
+
'spin:complete': [result: SpinResult];
|
|
24
|
+
'skip:requested': [];
|
|
25
|
+
'skip:completed': [];
|
|
26
|
+
'speed:changed': [profile: SpeedProfile, previous: SpeedProfile];
|
|
27
|
+
'spotlight:start': [positions: SymbolPosition[]];
|
|
28
|
+
'spotlight:end': [];
|
|
29
|
+
'destroyed': [];
|
|
30
|
+
}
|
|
31
|
+
/** Events emitted by an individual Reel. */
|
|
32
|
+
export interface ReelEvents extends Record<string, unknown[]> {
|
|
33
|
+
'phase:enter': [phaseName: string];
|
|
34
|
+
'phase:exit': [phaseName: string];
|
|
35
|
+
'symbol:created': [symbolId: string, row: number];
|
|
36
|
+
'symbol:recycled': [symbolId: string, row: number];
|
|
37
|
+
'landed': [symbols: string[]];
|
|
38
|
+
'destroyed': [];
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=ReelEvents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReelEvents.d.ts","sourceRoot":"","sources":["../../src/events/ReelEvents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,6CAA6C;AAC7C,MAAM,WAAW,UAAU;IACzB,+CAA+C;IAC/C,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;IACpB,iDAAiD;IACjD,UAAU,EAAE,OAAO,CAAC;IACpB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,mCAAmC;AACnC,MAAM,WAAW,aAAc,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IAC9D,YAAY,EAAE,EAAE,CAAC;IACjB,iBAAiB,EAAE,EAAE,CAAC;IACtB,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACrC,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1D,gBAAgB,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvC,eAAe,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACtC,gBAAgB,EAAE,EAAE,CAAC;IACrB,gBAAgB,EAAE,EAAE,CAAC;IACrB,eAAe,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IACjE,iBAAiB,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC;IACjD,eAAe,EAAE,EAAE,CAAC;IACpB,WAAW,EAAE,EAAE,CAAC;CACjB;AAED,4CAA4C;AAC5C,MAAM,WAAW,UAAW,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IAC3D,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACnC,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAClC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAClD,iBAAiB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACnD,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9B,WAAW,EAAE,EAAE,CAAC;CACjB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { RandomSymbolProvider } from './RandomSymbolProvider.js';
|
|
2
|
+
/** Context passed through the middleware pipeline. */
|
|
3
|
+
export interface FrameContext {
|
|
4
|
+
/** Reel column index. */
|
|
5
|
+
readonly reelIndex: number;
|
|
6
|
+
/** Total visible rows. */
|
|
7
|
+
readonly visibleRows: number;
|
|
8
|
+
/** Buffer symbols above visible area. */
|
|
9
|
+
readonly bufferAbove: number;
|
|
10
|
+
/** Buffer symbols below visible area. */
|
|
11
|
+
readonly bufferBelow: number;
|
|
12
|
+
/** The symbol array being built (buffer + visible + buffer). Mutable by middleware. */
|
|
13
|
+
symbols: string[];
|
|
14
|
+
/** Target symbols from setResult() (visible rows only), if available. */
|
|
15
|
+
readonly targetSymbols?: string[];
|
|
16
|
+
/** Whether the reel is currently spinning. */
|
|
17
|
+
readonly isSpinning: boolean;
|
|
18
|
+
/** Arbitrary metadata middleware can use to communicate. */
|
|
19
|
+
metadata: Record<string, unknown>;
|
|
20
|
+
}
|
|
21
|
+
/** Middleware that participates in frame building. */
|
|
22
|
+
export interface FrameMiddleware {
|
|
23
|
+
readonly name: string;
|
|
24
|
+
/** Lower priority runs first. */
|
|
25
|
+
readonly priority: number;
|
|
26
|
+
process(context: FrameContext, next: () => void): void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Builds symbol frames using a middleware pipeline.
|
|
30
|
+
*
|
|
31
|
+
* Built-in middleware handles random fill and target placement.
|
|
32
|
+
* Users can inject custom middleware for features like multiplier encoding
|
|
33
|
+
* or triple-prevention.
|
|
34
|
+
*/
|
|
35
|
+
export declare class FrameBuilder {
|
|
36
|
+
private _randomProvider;
|
|
37
|
+
private _middlewares;
|
|
38
|
+
private _sorted;
|
|
39
|
+
constructor(_randomProvider: RandomSymbolProvider);
|
|
40
|
+
/** Add a middleware to the pipeline. */
|
|
41
|
+
use(middleware: FrameMiddleware): this;
|
|
42
|
+
/** Remove a middleware by name. */
|
|
43
|
+
remove(name: string): this;
|
|
44
|
+
/** Build a frame for a single reel. */
|
|
45
|
+
build(reelIndex: number, visibleRows: number, bufferAbove: number, bufferBelow: number, targetSymbols?: string[], isSpinning?: boolean): string[];
|
|
46
|
+
/** Build frames for all reels. */
|
|
47
|
+
buildAll(reelCount: number, visibleRows: number, bufferAbove: number, bufferBelow: number, targetSymbols?: string[][], isSpinning?: boolean): string[][];
|
|
48
|
+
get randomProvider(): RandomSymbolProvider;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=FrameBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FrameBuilder.d.ts","sourceRoot":"","sources":["../../src/frame/FrameBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,0BAA0B;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yCAAyC;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yCAAyC;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,uFAAuF;IACvF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,yEAAyE;IACzE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC,8CAA8C;IAC9C,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CACxD;AAED;;;;;;GAMG;AACH,qBAAa,YAAY;IAIX,OAAO,CAAC,eAAe;IAHnC,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,OAAO,CAAS;gBAEJ,eAAe,EAAE,oBAAoB;IAMzD,wCAAwC;IACxC,GAAG,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI;IAMtC,mCAAmC;IACnC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK1B,uCAAuC;IACvC,KAAK,CACH,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,EAAE,EACxB,UAAU,GAAE,OAAe,GAC1B,MAAM,EAAE;IA+BX,kCAAkC;IAClC,QAAQ,CACN,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,EAAE,EAAE,EAC1B,UAAU,GAAE,OAAe,GAC1B,MAAM,EAAE,EAAE;IAab,IAAI,cAAc,IAAI,oBAAoB,CAEzC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { OffsetConfig } from '../config/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Computes X-position offsets for symbols to create visual effects
|
|
4
|
+
* like trapezoid perspective.
|
|
5
|
+
*/
|
|
6
|
+
export declare class OffsetCalculator {
|
|
7
|
+
private _reelCount;
|
|
8
|
+
private _totalRows;
|
|
9
|
+
private _symbolWidth;
|
|
10
|
+
private _config;
|
|
11
|
+
private _offsets;
|
|
12
|
+
constructor(_reelCount: number, _totalRows: number, _symbolWidth: number, _config: OffsetConfig);
|
|
13
|
+
/** Get X offset for a specific reel and row. */
|
|
14
|
+
getOffset(reelIndex: number, rowIndex: number): number;
|
|
15
|
+
/** Get all offsets as a 2D array [reelIndex][rowIndex]. */
|
|
16
|
+
get offsets(): readonly (readonly number[])[];
|
|
17
|
+
private _compute;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=OffsetCalculator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OffsetCalculator.d.ts","sourceRoot":"","sources":["../../src/frame/OffsetCalculator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,oBAAoB,CAAC;AAExE;;;GAGG;AACH,qBAAa,gBAAgB;IAIzB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,OAAO;IANjB,OAAO,CAAC,QAAQ,CAAkB;gBAGxB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,YAAY;IAK/B,gDAAgD;IAChD,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAItD,2DAA2D;IAC3D,IAAI,OAAO,IAAI,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAE5C;IAED,OAAO,CAAC,QAAQ;CA8BjB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SymbolData } from '../config/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Weighted random symbol selector using binary search on cumulative weights.
|
|
4
|
+
*
|
|
5
|
+
* Supports exclusion lists for symbols that shouldn't appear during
|
|
6
|
+
* spinning or in buffer areas.
|
|
7
|
+
*/
|
|
8
|
+
export declare class RandomSymbolProvider {
|
|
9
|
+
private _symbols;
|
|
10
|
+
private _weights;
|
|
11
|
+
private _cumulativeWeights;
|
|
12
|
+
private _totalWeight;
|
|
13
|
+
private _excludeSpinning;
|
|
14
|
+
private _excludeBuffer;
|
|
15
|
+
constructor(symbolsData: Record<string, SymbolData>);
|
|
16
|
+
/** Get a random symbol, optionally excluding buffer-only symbols. */
|
|
17
|
+
next(useBufferExclusion?: boolean): string;
|
|
18
|
+
/** Set symbols to exclude during spinning. */
|
|
19
|
+
setExcludeSpinning(symbolIds: string[]): void;
|
|
20
|
+
/** Set symbols to exclude from buffer (above/below) areas. */
|
|
21
|
+
setExcludeBuffer(symbolIds: string[]): void;
|
|
22
|
+
/** Update weights at runtime (e.g., for different game modes). */
|
|
23
|
+
updateWeights(symbolsData: Record<string, SymbolData>): void;
|
|
24
|
+
private _rebuildWeights;
|
|
25
|
+
private _pickWeighted;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=RandomSymbolProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RandomSymbolProvider.d.ts","sourceRoot":"","sources":["../../src/frame/RandomSymbolProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;GAKG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,kBAAkB,CAAgB;IAC1C,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,cAAc,CAAqB;gBAE/B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC;IAMnD,qEAAqE;IACrE,IAAI,CAAC,kBAAkB,GAAE,OAAe,GAAG,MAAM;IAyCjD,8CAA8C;IAC9C,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAI7C,8DAA8D;IAC9D,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAI3C,kEAAkE;IAClE,aAAa,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,IAAI;IAM5D,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,aAAa;CActB"}
|