@rpgjs/client 5.0.0-alpha.2 → 5.0.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Game/AnimationManager.d.ts +8 -0
- package/dist/Game/Map.d.ts +7 -1
- package/dist/Gui/Gui.d.ts +170 -5
- package/dist/Resource.d.ts +97 -0
- package/dist/RpgClient.d.ts +259 -59
- package/dist/RpgClientEngine.d.ts +379 -6
- package/dist/Sound.d.ts +199 -0
- package/dist/components/animations/index.d.ts +4 -0
- package/dist/components/dynamics/parse-value.d.ts +1 -0
- package/dist/components/gui/index.d.ts +3 -3
- package/dist/components/index.d.ts +3 -1
- package/dist/components/prebuilt/index.d.ts +18 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/dist/index10.js +149 -4
- package/dist/index10.js.map +1 -1
- package/dist/index11.js +22 -7
- package/dist/index11.js.map +1 -1
- package/dist/index12.js +6 -4
- package/dist/index12.js.map +1 -1
- package/dist/index13.js +11 -14
- package/dist/index13.js.map +1 -1
- package/dist/index14.js +8 -40
- package/dist/index14.js.map +1 -1
- package/dist/index15.js +217 -180
- package/dist/index15.js.map +1 -1
- package/dist/index16.js +104 -7
- package/dist/index16.js.map +1 -1
- package/dist/index17.js +82 -372
- package/dist/index17.js.map +1 -1
- package/dist/index18.js +110 -27
- package/dist/index18.js.map +1 -1
- package/dist/index19.js +360 -18
- package/dist/index19.js.map +1 -1
- package/dist/index2.js +726 -32
- package/dist/index2.js.map +1 -1
- package/dist/index20.js +5 -2416
- package/dist/index20.js.map +1 -1
- package/dist/index21.js +47 -109
- package/dist/index21.js.map +1 -1
- package/dist/index22.js +7 -107
- package/dist/index22.js.map +1 -1
- package/dist/index23.js +394 -65
- package/dist/index23.js.map +1 -1
- package/dist/index24.js +40 -15
- package/dist/index24.js.map +1 -1
- package/dist/index25.js +20 -36
- package/dist/index25.js.map +1 -1
- package/dist/index26.js +2629 -1
- package/dist/index26.js.map +1 -1
- package/dist/index27.js +102 -310
- package/dist/index27.js.map +1 -1
- package/dist/index28.js +63 -17
- package/dist/index28.js.map +1 -1
- package/dist/index29.js +18 -8
- package/dist/index29.js.map +1 -1
- package/dist/index3.js +70 -8
- package/dist/index3.js.map +1 -1
- package/dist/index30.js +24 -8
- package/dist/index30.js.map +1 -1
- package/dist/index31.js +88 -167
- package/dist/index31.js.map +1 -1
- package/dist/index32.js +34 -494
- package/dist/index32.js.map +1 -1
- package/dist/index33.js +22 -10
- package/dist/index33.js.map +1 -1
- package/dist/index34.js +3 -4401
- package/dist/index34.js.map +1 -1
- package/dist/index35.js +20 -1
- package/dist/index35.js.map +1 -1
- package/dist/index36.js +18 -82
- package/dist/index36.js.map +1 -1
- package/dist/index37.js +8 -58
- package/dist/index37.js.map +1 -1
- package/dist/index38.js +4 -13
- package/dist/index38.js.map +1 -1
- package/dist/index39.js +10 -18
- package/dist/index39.js.map +1 -1
- package/dist/index4.js +25 -5
- package/dist/index4.js.map +1 -1
- package/dist/index40.js +7 -0
- package/dist/index40.js.map +1 -0
- package/dist/index41.js +3690 -0
- package/dist/index41.js.map +1 -0
- package/dist/index42.js +187 -0
- package/dist/index42.js.map +1 -0
- package/dist/index43.js +504 -0
- package/dist/index43.js.map +1 -0
- package/dist/index44.js +77 -0
- package/dist/index44.js.map +1 -0
- package/dist/index45.js +6 -0
- package/dist/index45.js.map +1 -0
- package/dist/index46.js +20 -0
- package/dist/index46.js.map +1 -0
- package/dist/index47.js +146 -0
- package/dist/index47.js.map +1 -0
- package/dist/index48.js +12 -0
- package/dist/index48.js.map +1 -0
- package/dist/index49.js +113 -0
- package/dist/index49.js.map +1 -0
- package/dist/index5.js +2 -1
- package/dist/index5.js.map +1 -1
- package/dist/index50.js +136 -0
- package/dist/index50.js.map +1 -0
- package/dist/index51.js +137 -0
- package/dist/index51.js.map +1 -0
- package/dist/index52.js +112 -0
- package/dist/index52.js.map +1 -0
- package/dist/index53.js +141 -0
- package/dist/index53.js.map +1 -0
- package/dist/index54.js +9 -0
- package/dist/index54.js.map +1 -0
- package/dist/index55.js +54 -0
- package/dist/index55.js.map +1 -0
- package/dist/index6.js +1 -1
- package/dist/index6.js.map +1 -1
- package/dist/index7.js +11 -3
- package/dist/index7.js.map +1 -1
- package/dist/index8.js +68 -7
- package/dist/index8.js.map +1 -1
- package/dist/index9.js +278 -15
- package/dist/index9.js.map +1 -1
- package/dist/presets/animation.d.ts +31 -0
- package/dist/presets/faceset.d.ts +30 -0
- package/dist/presets/index.d.ts +103 -0
- package/dist/presets/lpc.d.ts +89 -0
- package/dist/services/keyboardControls.d.ts +5 -0
- package/dist/services/loadMap.d.ts +123 -2
- package/dist/services/mmorpg.d.ts +12 -4
- package/dist/services/standalone.d.ts +54 -2
- package/package.json +22 -18
- package/src/Game/{EffectManager.ts → AnimationManager.ts} +3 -2
- package/src/Game/Map.ts +20 -2
- package/src/Game/Object.ts +163 -9
- package/src/Gui/Gui.ts +362 -17
- package/src/Resource.ts +150 -0
- package/src/RpgClient.ts +264 -58
- package/src/RpgClientEngine.ts +848 -36
- package/src/Sound.ts +253 -0
- package/src/components/{effects → animations}/animation.ce +3 -6
- package/src/components/{effects → animations}/index.ts +1 -1
- package/src/components/character.ce +193 -36
- package/src/components/dynamics/parse-value.ts +80 -0
- package/src/components/dynamics/text.ce +183 -0
- package/src/components/gui/box.ce +17 -0
- package/src/components/gui/dialogbox/index.ce +73 -35
- package/src/components/gui/dialogbox/selection.ce +16 -1
- package/src/components/gui/index.ts +3 -4
- package/src/components/index.ts +5 -1
- package/src/components/prebuilt/hp-bar.ce +255 -0
- package/src/components/prebuilt/index.ts +22 -0
- package/src/components/scenes/canvas.ce +12 -10
- package/src/components/scenes/draw-map.ce +6 -23
- package/src/components/scenes/event-layer.ce +9 -3
- package/src/core/setup.ts +2 -0
- package/src/index.ts +7 -2
- package/src/module.ts +72 -6
- package/src/presets/animation.ts +46 -0
- package/src/presets/faceset.ts +60 -0
- package/src/presets/index.ts +7 -1
- package/src/presets/lpc.ts +108 -0
- package/src/services/keyboardControls.ts +8 -0
- package/src/services/loadMap.ts +132 -3
- package/src/services/mmorpg.ts +29 -5
- package/src/services/standalone.ts +70 -6
- package/tsconfig.json +1 -1
- package/vite.config.ts +1 -1
- package/dist/Game/EffectManager.d.ts +0 -5
- package/dist/components/effects/index.d.ts +0 -4
- package/src/components/scenes/element-map.ce +0 -23
- /package/src/components/{effects → animations}/hit.ce +0 -0
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { Context } from '@signe/di';
|
|
2
|
-
import {
|
|
2
|
+
import { AbstractWebsocket } from './services/AbstractSocket';
|
|
3
|
+
import { Direction } from '@rpgjs/common';
|
|
4
|
+
import { RpgClientMap } from './Game/Map';
|
|
5
|
+
import { AnimationManager } from './Game/AnimationManager';
|
|
6
|
+
import { Observable } from 'rxjs';
|
|
7
|
+
import * as PIXI from "pixi.js";
|
|
3
8
|
export declare class RpgClientEngine<T = any> {
|
|
4
9
|
context: Context;
|
|
5
10
|
private guiService;
|
|
@@ -15,29 +20,397 @@ export declare class RpgClientEngine<T = any> {
|
|
|
15
20
|
height: import('canvasengine').WritableSignal<string>;
|
|
16
21
|
spritesheets: Map<string, any>;
|
|
17
22
|
sounds: Map<string, any>;
|
|
18
|
-
|
|
23
|
+
componentAnimations: any[];
|
|
24
|
+
private spritesheetResolver?;
|
|
25
|
+
private soundResolver?;
|
|
19
26
|
particleSettings: {
|
|
20
27
|
emitters: any[];
|
|
21
28
|
};
|
|
29
|
+
renderer: PIXI.Renderer;
|
|
30
|
+
tick: Observable<number>;
|
|
31
|
+
playerIdSignal: import('canvasengine').WritableSignal<string | null>;
|
|
32
|
+
spriteComponentsBehind: import('canvasengine').WritableArraySignal<any[]>;
|
|
33
|
+
spriteComponentsInFront: import('canvasengine').WritableArraySignal<any[]>;
|
|
34
|
+
private predictionEnabled;
|
|
35
|
+
private prediction?;
|
|
36
|
+
private readonly SERVER_CORRECTION_THRESHOLD;
|
|
37
|
+
private inputFrameCounter;
|
|
38
|
+
private frameOffset;
|
|
39
|
+
private rtt;
|
|
40
|
+
private pingInterval;
|
|
41
|
+
private readonly PING_INTERVAL_MS;
|
|
42
|
+
private lastInputTime;
|
|
22
43
|
constructor(context: Context);
|
|
44
|
+
/**
|
|
45
|
+
* Assigns a CanvasEngine KeyboardControls instance to the dependency injection context
|
|
46
|
+
*
|
|
47
|
+
* This method registers a KeyboardControls instance from CanvasEngine into the DI container,
|
|
48
|
+
* making it available for injection throughout the application. The particularity is that
|
|
49
|
+
* this method is automatically called when a sprite is displayed on the map, allowing the
|
|
50
|
+
* controls to be automatically associated with the active sprite.
|
|
51
|
+
*
|
|
52
|
+
* ## Design
|
|
53
|
+
*
|
|
54
|
+
* - The instance is stored in the DI context under the `KeyboardControls` token
|
|
55
|
+
* - It's automatically assigned when a sprite component mounts (in `character.ce`)
|
|
56
|
+
* - The controls instance comes from the CanvasEngine component's directives
|
|
57
|
+
* - Once registered, it can be retrieved using `inject(KeyboardControls)` from anywhere
|
|
58
|
+
*
|
|
59
|
+
* @param controlInstance - The CanvasEngine KeyboardControls instance to register
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* // The method is automatically called when a sprite is displayed:
|
|
64
|
+
* // client.setKeyboardControls(element.directives.controls)
|
|
65
|
+
*
|
|
66
|
+
* // Later, retrieve and use the controls instance:
|
|
67
|
+
* import { Input, inject, KeyboardControls } from '@rpgjs/client'
|
|
68
|
+
*
|
|
69
|
+
* const controls = inject(KeyboardControls)
|
|
70
|
+
* const control = controls.getControl(Input.Enter)
|
|
71
|
+
*
|
|
72
|
+
* if (control) {
|
|
73
|
+
* console.log(control.actionName) // 'action'
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
setKeyboardControls(controlInstance: any): void;
|
|
23
78
|
start(): Promise<void>;
|
|
24
79
|
private initListeners;
|
|
80
|
+
/**
|
|
81
|
+
* Start periodic ping/pong for client-server synchronization
|
|
82
|
+
*
|
|
83
|
+
* Sends ping requests to the server to measure round-trip time (RTT) and
|
|
84
|
+
* calculate the frame offset between client and server ticks.
|
|
85
|
+
*
|
|
86
|
+
* ## Design
|
|
87
|
+
*
|
|
88
|
+
* - Sends ping every 5 seconds
|
|
89
|
+
* - Measures RTT for latency compensation
|
|
90
|
+
* - Calculates frame offset to map client frames to server ticks
|
|
91
|
+
* - Used for accurate server reconciliation
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* // Called automatically when connection opens
|
|
96
|
+
* this.startPingPong();
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
private startPingPong;
|
|
100
|
+
/**
|
|
101
|
+
* Stop periodic ping/pong
|
|
102
|
+
*
|
|
103
|
+
* Stops the ping interval when disconnecting or changing maps.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* // Called automatically when connection closes
|
|
108
|
+
* this.stopPingPong();
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
private stopPingPong;
|
|
112
|
+
/**
|
|
113
|
+
* Send a ping request to the server
|
|
114
|
+
*
|
|
115
|
+
* Sends current client time and frame counter to the server,
|
|
116
|
+
* which will respond with its server tick for synchronization.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* // Send a ping to measure RTT
|
|
121
|
+
* this.sendPing();
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
private sendPing;
|
|
25
125
|
private loadScene;
|
|
26
126
|
addSpriteSheet<T = any>(spritesheetClass: any, id?: string): any;
|
|
127
|
+
/**
|
|
128
|
+
* Set a resolver function for spritesheets
|
|
129
|
+
*
|
|
130
|
+
* The resolver is called when a spritesheet is requested but not found in the cache.
|
|
131
|
+
* It can be synchronous (returns directly) or asynchronous (returns a Promise).
|
|
132
|
+
* The resolved spritesheet is automatically cached for future use.
|
|
133
|
+
*
|
|
134
|
+
* @param resolver - Function that takes a spritesheet ID and returns a spritesheet or Promise of spritesheet
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```ts
|
|
138
|
+
* // Synchronous resolver
|
|
139
|
+
* engine.setSpritesheetResolver((id) => {
|
|
140
|
+
* if (id === 'dynamic-sprite') {
|
|
141
|
+
* return { id: 'dynamic-sprite', image: 'path/to/image.png', framesWidth: 32, framesHeight: 32 };
|
|
142
|
+
* }
|
|
143
|
+
* return undefined;
|
|
144
|
+
* });
|
|
145
|
+
*
|
|
146
|
+
* // Asynchronous resolver (loading from API)
|
|
147
|
+
* engine.setSpritesheetResolver(async (id) => {
|
|
148
|
+
* const response = await fetch(`/api/spritesheets/${id}`);
|
|
149
|
+
* const data = await response.json();
|
|
150
|
+
* return data;
|
|
151
|
+
* });
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
setSpritesheetResolver(resolver: (id: string) => any | Promise<any>): void;
|
|
155
|
+
/**
|
|
156
|
+
* Get a spritesheet by ID, using resolver if not found in cache
|
|
157
|
+
*
|
|
158
|
+
* This method first checks if the spritesheet exists in the cache.
|
|
159
|
+
* If not found and a resolver is set, it calls the resolver to create the spritesheet.
|
|
160
|
+
* The resolved spritesheet is automatically cached for future use.
|
|
161
|
+
*
|
|
162
|
+
* @param id - The spritesheet ID to retrieve
|
|
163
|
+
* @returns The spritesheet if found or created, or undefined if not found and no resolver
|
|
164
|
+
* @returns Promise<any> if the resolver is asynchronous
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```ts
|
|
168
|
+
* // Synchronous usage
|
|
169
|
+
* const spritesheet = engine.getSpriteSheet('my-sprite');
|
|
170
|
+
*
|
|
171
|
+
* // Asynchronous usage (when resolver returns Promise)
|
|
172
|
+
* const spritesheet = await engine.getSpriteSheet('dynamic-sprite');
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
getSpriteSheet(id: string): any | Promise<any>;
|
|
176
|
+
/**
|
|
177
|
+
* Add a sound to the engine
|
|
178
|
+
*
|
|
179
|
+
* Adds a sound to the engine's sound cache. The sound can be:
|
|
180
|
+
* - A simple object with `id` and `src` properties
|
|
181
|
+
* - A Howler instance
|
|
182
|
+
* - An object with a `play()` method
|
|
183
|
+
*
|
|
184
|
+
* If the sound has a `src` property, a Howler instance will be created automatically.
|
|
185
|
+
*
|
|
186
|
+
* @param sound - The sound object or Howler instance
|
|
187
|
+
* @param id - Optional sound ID (if not provided, uses sound.id)
|
|
188
|
+
* @returns The added sound
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```ts
|
|
192
|
+
* // Simple sound object
|
|
193
|
+
* engine.addSound({ id: 'click', src: 'click.mp3' });
|
|
194
|
+
*
|
|
195
|
+
* // With explicit ID
|
|
196
|
+
* engine.addSound({ src: 'music.mp3' }, 'background-music');
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
27
199
|
addSound(sound: any, id?: string): any;
|
|
200
|
+
/**
|
|
201
|
+
* Set a resolver function for sounds
|
|
202
|
+
*
|
|
203
|
+
* The resolver is called when a sound is requested but not found in the cache.
|
|
204
|
+
* It can be synchronous (returns directly) or asynchronous (returns a Promise).
|
|
205
|
+
* The resolved sound is automatically cached for future use.
|
|
206
|
+
*
|
|
207
|
+
* @param resolver - Function that takes a sound ID and returns a sound or Promise of sound
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* ```ts
|
|
211
|
+
* // Synchronous resolver
|
|
212
|
+
* engine.setSoundResolver((id) => {
|
|
213
|
+
* if (id === 'dynamic-sound') {
|
|
214
|
+
* return { id: 'dynamic-sound', src: 'path/to/sound.mp3' };
|
|
215
|
+
* }
|
|
216
|
+
* return undefined;
|
|
217
|
+
* });
|
|
218
|
+
*
|
|
219
|
+
* // Asynchronous resolver (loading from API)
|
|
220
|
+
* engine.setSoundResolver(async (id) => {
|
|
221
|
+
* const response = await fetch(`/api/sounds/${id}`);
|
|
222
|
+
* const data = await response.json();
|
|
223
|
+
* return data;
|
|
224
|
+
* });
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
setSoundResolver(resolver: (id: string) => any | Promise<any>): void;
|
|
228
|
+
/**
|
|
229
|
+
* Get a sound by ID, using resolver if not found in cache
|
|
230
|
+
*
|
|
231
|
+
* This method first checks if the sound exists in the cache.
|
|
232
|
+
* If not found and a resolver is set, it calls the resolver to create the sound.
|
|
233
|
+
* The resolved sound is automatically cached for future use.
|
|
234
|
+
*
|
|
235
|
+
* @param id - The sound ID to retrieve
|
|
236
|
+
* @returns The sound if found or created, or undefined if not found and no resolver
|
|
237
|
+
* @returns Promise<any> if the resolver is asynchronous
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* ```ts
|
|
241
|
+
* // Synchronous usage
|
|
242
|
+
* const sound = engine.getSound('my-sound');
|
|
243
|
+
*
|
|
244
|
+
* // Asynchronous usage (when resolver returns Promise)
|
|
245
|
+
* const sound = await engine.getSound('dynamic-sound');
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
getSound(id: string): any | Promise<any>;
|
|
249
|
+
/**
|
|
250
|
+
* Play a sound by its ID
|
|
251
|
+
*
|
|
252
|
+
* This method retrieves a sound from the cache or resolver and plays it.
|
|
253
|
+
* If the sound is not found, it will attempt to resolve it using the soundResolver.
|
|
254
|
+
* Uses Howler.js for audio playback instead of native Audio elements.
|
|
255
|
+
*
|
|
256
|
+
* @param soundId - The sound ID to play
|
|
257
|
+
* @param options - Optional sound configuration
|
|
258
|
+
* @param options.volume - Volume level (0.0 to 1.0, overrides sound default)
|
|
259
|
+
* @param options.loop - Whether the sound should loop (overrides sound default)
|
|
260
|
+
*
|
|
261
|
+
* @example
|
|
262
|
+
* ```ts
|
|
263
|
+
* // Play a sound synchronously
|
|
264
|
+
* engine.playSound('item-pickup');
|
|
265
|
+
*
|
|
266
|
+
* // Play a sound with volume and loop
|
|
267
|
+
* engine.playSound('background-music', { volume: 0.5, loop: true });
|
|
268
|
+
*
|
|
269
|
+
* // Play a sound asynchronously (when resolver returns Promise)
|
|
270
|
+
* await engine.playSound('dynamic-sound', { volume: 0.8 });
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
playSound(soundId: string, options?: {
|
|
274
|
+
volume?: number;
|
|
275
|
+
loop?: boolean;
|
|
276
|
+
}): Promise<void>;
|
|
277
|
+
/**
|
|
278
|
+
* Stop a sound that is currently playing
|
|
279
|
+
*
|
|
280
|
+
* This method stops a sound that was previously started with `playSound()`.
|
|
281
|
+
*
|
|
282
|
+
* @param soundId - The sound ID to stop
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* ```ts
|
|
286
|
+
* // Start a looping sound
|
|
287
|
+
* engine.playSound('background-music', { loop: true });
|
|
288
|
+
*
|
|
289
|
+
* // Later, stop it
|
|
290
|
+
* engine.stopSound('background-music');
|
|
291
|
+
* ```
|
|
292
|
+
*/
|
|
293
|
+
stopSound(soundId: string): void;
|
|
28
294
|
addParticle(particle: any): any;
|
|
29
|
-
|
|
295
|
+
/**
|
|
296
|
+
* Add a component to render behind sprites
|
|
297
|
+
* Components added with this method will be displayed with a lower z-index than the sprite
|
|
298
|
+
*
|
|
299
|
+
* @param component - The component to add behind sprites
|
|
300
|
+
* @returns The added component
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* ```ts
|
|
304
|
+
* // Add a shadow component behind all sprites
|
|
305
|
+
* engine.addSpriteComponentBehind(ShadowComponent);
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
addSpriteComponentBehind(component: any): any;
|
|
309
|
+
/**
|
|
310
|
+
* Add a component to render in front of sprites
|
|
311
|
+
* Components added with this method will be displayed with a higher z-index than the sprite
|
|
312
|
+
*
|
|
313
|
+
* @param component - The component to add in front of sprites
|
|
314
|
+
* @returns The added component
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* ```ts
|
|
318
|
+
* // Add a health bar component in front of all sprites
|
|
319
|
+
* engine.addSpriteComponentInFront(HealthBarComponent);
|
|
320
|
+
* ```
|
|
321
|
+
*/
|
|
322
|
+
addSpriteComponentInFront(component: any): any;
|
|
323
|
+
/**
|
|
324
|
+
* Add a component animation to the engine
|
|
325
|
+
*
|
|
326
|
+
* Component animations are temporary visual effects that can be displayed
|
|
327
|
+
* on sprites or objects, such as hit indicators, spell effects, or status animations.
|
|
328
|
+
*
|
|
329
|
+
* @param componentAnimation - The component animation configuration
|
|
330
|
+
* @param componentAnimation.id - Unique identifier for the animation
|
|
331
|
+
* @param componentAnimation.component - The component function to render
|
|
332
|
+
* @returns The added component animation configuration
|
|
333
|
+
*
|
|
334
|
+
* @example
|
|
335
|
+
* ```ts
|
|
336
|
+
* // Add a hit animation component
|
|
337
|
+
* engine.addComponentAnimation({
|
|
338
|
+
* id: 'hit',
|
|
339
|
+
* component: HitComponent
|
|
340
|
+
* });
|
|
341
|
+
*
|
|
342
|
+
* // Add an explosion effect component
|
|
343
|
+
* engine.addComponentAnimation({
|
|
344
|
+
* id: 'explosion',
|
|
345
|
+
* component: ExplosionComponent
|
|
346
|
+
* });
|
|
347
|
+
* ```
|
|
348
|
+
*/
|
|
349
|
+
addComponentAnimation(componentAnimation: {
|
|
30
350
|
component: any;
|
|
31
351
|
id: string;
|
|
32
352
|
}): {
|
|
33
353
|
component: any;
|
|
34
354
|
id: string;
|
|
35
355
|
};
|
|
36
|
-
|
|
356
|
+
/**
|
|
357
|
+
* Get a component animation by its ID
|
|
358
|
+
*
|
|
359
|
+
* Retrieves the EffectManager instance for a specific component animation,
|
|
360
|
+
* which can be used to display the animation on sprites or objects.
|
|
361
|
+
*
|
|
362
|
+
* @param id - The unique identifier of the component animation
|
|
363
|
+
* @returns The EffectManager instance for the animation
|
|
364
|
+
* @throws Error if the component animation is not found
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* ```ts
|
|
368
|
+
* // Get the hit animation and display it
|
|
369
|
+
* const hitAnimation = engine.getComponentAnimation('hit');
|
|
370
|
+
* hitAnimation.displayEffect({ text: "Critical!" }, player);
|
|
371
|
+
* ```
|
|
372
|
+
*/
|
|
373
|
+
getComponentAnimation(id: string): AnimationManager;
|
|
37
374
|
processInput({ input }: {
|
|
38
|
-
input:
|
|
39
|
-
}): void
|
|
375
|
+
input: Direction;
|
|
376
|
+
}): Promise<void>;
|
|
40
377
|
processAction({ action }: {
|
|
41
378
|
action: number;
|
|
42
379
|
}): void;
|
|
380
|
+
get PIXI(): typeof PIXI;
|
|
381
|
+
get socket(): AbstractWebsocket;
|
|
382
|
+
get playerId(): string | null;
|
|
383
|
+
get scene(): RpgClientMap;
|
|
384
|
+
private getPhysicsTick;
|
|
385
|
+
private getLocalPlayerState;
|
|
386
|
+
private applyAuthoritativeState;
|
|
387
|
+
private initializePredictionController;
|
|
388
|
+
getCurrentPlayer(): import('./Game/Player').RpgClientPlayer;
|
|
389
|
+
/**
|
|
390
|
+
* Clear client prediction states for cleanup
|
|
391
|
+
*
|
|
392
|
+
* Removes old prediction states and input history to prevent memory leaks.
|
|
393
|
+
* Should be called when changing maps or disconnecting.
|
|
394
|
+
*
|
|
395
|
+
* @example
|
|
396
|
+
* ```ts
|
|
397
|
+
* // Clear prediction states when changing maps
|
|
398
|
+
* engine.clearClientPredictionStates();
|
|
399
|
+
* ```
|
|
400
|
+
*/
|
|
401
|
+
clearClientPredictionStates(): void;
|
|
402
|
+
private applyServerAck;
|
|
403
|
+
/**
|
|
404
|
+
* Replay unacknowledged inputs from a given frame to resimulate client prediction
|
|
405
|
+
* after applying server authority at a certain frame.
|
|
406
|
+
*
|
|
407
|
+
* @param startFrame - The last server-acknowledged frame
|
|
408
|
+
*
|
|
409
|
+
* @example
|
|
410
|
+
* ```ts
|
|
411
|
+
* // After applying a server correction at frame N
|
|
412
|
+
* this.replayUnackedInputsFromFrame(N);
|
|
413
|
+
* ```
|
|
414
|
+
*/
|
|
415
|
+
private replayUnackedInputsFromFrame;
|
|
43
416
|
}
|
package/dist/Sound.d.ts
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { Howler } from 'canvasengine';
|
|
2
|
+
import { RpgClientEngine } from './RpgClientEngine';
|
|
3
|
+
/**
|
|
4
|
+
* Sound decorator options
|
|
5
|
+
*
|
|
6
|
+
* Defines the configuration for a sound that can be played in the game.
|
|
7
|
+
* The sound can be a single file or multiple files (for different formats).
|
|
8
|
+
*
|
|
9
|
+
* @interface SoundOptions
|
|
10
|
+
*/
|
|
11
|
+
export interface SoundOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Sound identifier. Used to retrieve the sound later with RpgSound.get()
|
|
14
|
+
*
|
|
15
|
+
* @type {string}
|
|
16
|
+
*/
|
|
17
|
+
id?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Single sound file path. Use require() to wrap the path.
|
|
20
|
+
*
|
|
21
|
+
* @type {string}
|
|
22
|
+
* @example
|
|
23
|
+
* sound: require('./assets/sound.ogg')
|
|
24
|
+
*/
|
|
25
|
+
sound?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Multiple sounds with different IDs. The key is the sound ID and the value is the file path.
|
|
28
|
+
* Use require() to wrap each path.
|
|
29
|
+
*
|
|
30
|
+
* @type {{ [id: string]: string }}
|
|
31
|
+
* @example
|
|
32
|
+
* sounds: {
|
|
33
|
+
* hero: require('./assets/hero.ogg'),
|
|
34
|
+
* monster: require('./assets/monster.ogg')
|
|
35
|
+
* }
|
|
36
|
+
*/
|
|
37
|
+
sounds?: {
|
|
38
|
+
[id: string]: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Whether the sound should loop when it finishes playing.
|
|
42
|
+
*
|
|
43
|
+
* @type {boolean}
|
|
44
|
+
* @default false
|
|
45
|
+
*/
|
|
46
|
+
loop?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Volume level (0.0 to 1.0).
|
|
49
|
+
*
|
|
50
|
+
* @type {number}
|
|
51
|
+
* @default 1.0
|
|
52
|
+
*/
|
|
53
|
+
volume?: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Metadata stored on the class decorated with @Sound
|
|
57
|
+
*
|
|
58
|
+
* @interface SoundMetadata
|
|
59
|
+
*/
|
|
60
|
+
interface SoundMetadata {
|
|
61
|
+
id?: string;
|
|
62
|
+
sound?: string;
|
|
63
|
+
sounds?: {
|
|
64
|
+
[id: string]: string;
|
|
65
|
+
};
|
|
66
|
+
loop?: boolean;
|
|
67
|
+
volume?: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Sound decorator
|
|
71
|
+
*
|
|
72
|
+
* Decorates a class to define a sound configuration. The decorated class can be
|
|
73
|
+
* added to the RpgClient module configuration, and the sound will be automatically
|
|
74
|
+
* registered and available through RpgSound.get().
|
|
75
|
+
*
|
|
76
|
+
* ## Design
|
|
77
|
+
*
|
|
78
|
+
* The decorator stores metadata on the class that is later used by the module loader
|
|
79
|
+
* to register sounds with the engine. The sound is created using Howler.js for
|
|
80
|
+
* advanced audio features like looping, volume control, and cross-browser compatibility.
|
|
81
|
+
*
|
|
82
|
+
* @param options - Sound configuration options
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* import { Sound } from '@rpgjs/client'
|
|
87
|
+
*
|
|
88
|
+
* @Sound({
|
|
89
|
+
* id: 'town-music',
|
|
90
|
+
* sound: require('./sound/town.ogg'),
|
|
91
|
+
* loop: true,
|
|
92
|
+
* volume: 0.5
|
|
93
|
+
* })
|
|
94
|
+
* export class TownMusic {}
|
|
95
|
+
*
|
|
96
|
+
* // Multiple sounds in one class
|
|
97
|
+
* @Sound({
|
|
98
|
+
* sounds: {
|
|
99
|
+
* hero: require('./assets/hero.ogg'),
|
|
100
|
+
* monster: require('./assets/monster.ogg')
|
|
101
|
+
* },
|
|
102
|
+
* loop: true
|
|
103
|
+
* })
|
|
104
|
+
* export class CharacterSounds {}
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare function Sound(options: SoundOptions): <T extends {
|
|
108
|
+
new (...args: any[]): {};
|
|
109
|
+
}>(constructor: T) => T;
|
|
110
|
+
/**
|
|
111
|
+
* Get sound metadata from a decorated class
|
|
112
|
+
*
|
|
113
|
+
* @param soundClass - The class decorated with @Sound
|
|
114
|
+
* @returns The sound metadata or undefined
|
|
115
|
+
*/
|
|
116
|
+
export declare function getSoundMetadata(soundClass: any): SoundMetadata | undefined;
|
|
117
|
+
/**
|
|
118
|
+
* RpgSound class
|
|
119
|
+
*
|
|
120
|
+
* Provides a unified API to manage sounds in the game. Uses Howler.js internally
|
|
121
|
+
* for advanced audio features. Sounds can be retrieved by ID and controlled
|
|
122
|
+
* using Howler.js methods.
|
|
123
|
+
*
|
|
124
|
+
* ## Design
|
|
125
|
+
*
|
|
126
|
+
* RpgSound acts as a facade over Howler.js, providing easy access to sounds
|
|
127
|
+
* registered in the engine. It supports both individual sound control and
|
|
128
|
+
* global sound management (volume, mute, etc.).
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* import { RpgSound } from '@rpgjs/client'
|
|
133
|
+
*
|
|
134
|
+
* // Play a sound
|
|
135
|
+
* RpgSound.get('town-music').play()
|
|
136
|
+
*
|
|
137
|
+
* // Control volume
|
|
138
|
+
* RpgSound.get('town-music').volume(0.5)
|
|
139
|
+
*
|
|
140
|
+
* // Stop a sound
|
|
141
|
+
* RpgSound.get('town-music').stop()
|
|
142
|
+
*
|
|
143
|
+
* // Global volume control
|
|
144
|
+
* RpgSound.global.volume(0.2)
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
export declare class RpgSound {
|
|
148
|
+
private static engine;
|
|
149
|
+
/**
|
|
150
|
+
* Initialize RpgSound with the engine instance
|
|
151
|
+
*
|
|
152
|
+
* This is called automatically by the engine during initialization.
|
|
153
|
+
*
|
|
154
|
+
* @param engine - The RpgClientEngine instance
|
|
155
|
+
*/
|
|
156
|
+
static init(engine: RpgClientEngine): void;
|
|
157
|
+
/**
|
|
158
|
+
* Get a sound by its ID
|
|
159
|
+
*
|
|
160
|
+
* Retrieves a Howler sound instance from the engine's sound cache.
|
|
161
|
+
* The sound must be registered beforehand (via @Sound decorator or manually).
|
|
162
|
+
*
|
|
163
|
+
* @param id - The sound identifier
|
|
164
|
+
* @returns The Howler sound instance, or undefined if not found
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```ts
|
|
168
|
+
* // Get and play a sound
|
|
169
|
+
* const sound = RpgSound.get('town-music');
|
|
170
|
+
* if (sound) {
|
|
171
|
+
* sound.play();
|
|
172
|
+
* }
|
|
173
|
+
*
|
|
174
|
+
* // Chain methods
|
|
175
|
+
* RpgSound.get('battle-theme')?.volume(0.8).play();
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
static get(id: string): any;
|
|
179
|
+
/**
|
|
180
|
+
* Global Howler instance for managing all sounds
|
|
181
|
+
*
|
|
182
|
+
* Provides access to Howler.js global methods for controlling all sounds
|
|
183
|
+
* at once (volume, mute, etc.).
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```ts
|
|
187
|
+
* // Set global volume to 20%
|
|
188
|
+
* RpgSound.global.volume(0.2)
|
|
189
|
+
*
|
|
190
|
+
* // Mute all sounds
|
|
191
|
+
* RpgSound.global.mute(true)
|
|
192
|
+
*
|
|
193
|
+
* // Unmute all sounds
|
|
194
|
+
* RpgSound.global.mute(false)
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
static get global(): typeof Howler;
|
|
198
|
+
}
|
|
199
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const parseDynamicValue: (value: any, object?: any) => import('canvasengine').ComputedSignal<string>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
};
|
|
1
|
+
import { default as DialogboxComponent } from './dialogbox/index.ce';
|
|
2
|
+
import { default as BoxComponent } from './box.ce';
|
|
3
|
+
export { DialogboxComponent, BoxComponent };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prebuilt sprite components for common UI elements
|
|
3
|
+
*
|
|
4
|
+
* This module exports ready-to-use components that can be attached
|
|
5
|
+
* to sprites using componentsInFront or componentsBehind configuration.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { HpBar } from '@rpgjs/client/components/prebuilt';
|
|
10
|
+
*
|
|
11
|
+
* export default defineModule<RpgClient>({
|
|
12
|
+
* sprite: {
|
|
13
|
+
* componentsInFront: [HpBar]
|
|
14
|
+
* }
|
|
15
|
+
* })
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export { default as HpBar } from './hp-bar.ce';
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,11 @@ export * from './services/loadMap';
|
|
|
8
8
|
export * from './module';
|
|
9
9
|
export * from './Gui/Gui';
|
|
10
10
|
export * from './components/gui';
|
|
11
|
-
export * from './components/
|
|
11
|
+
export * from './components/animations';
|
|
12
12
|
export * from './presets';
|
|
13
13
|
export * from './components';
|
|
14
|
+
export * from './components/gui';
|
|
15
|
+
export * from './Sound';
|
|
16
|
+
export * from './Resource';
|
|
17
|
+
export { Context } from '@signe/di';
|
|
18
|
+
export * from './services/keyboardControls';
|
package/dist/index.js
CHANGED
|
@@ -6,8 +6,15 @@ export { clearInject, context, inject, setInject } from './index6.js';
|
|
|
6
6
|
export { LoadMapService, LoadMapToken, provideLoadMap } from './index7.js';
|
|
7
7
|
export { GlobalConfigToken, provideClientGlobalConfig, provideClientModules, provideGlobalConfig } from './index8.js';
|
|
8
8
|
export { RpgGui } from './index9.js';
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
12
|
-
export {
|
|
9
|
+
export { default as DialogboxComponent } from './index10.js';
|
|
10
|
+
export { default as BoxComponent } from './index11.js';
|
|
11
|
+
export { PrebuiltComponentAnimations } from './index12.js';
|
|
12
|
+
export { Presets } from './index13.js';
|
|
13
|
+
export { default as EventLayerComponent } from './index14.js';
|
|
14
|
+
export { default as CharacterComponent } from './index15.js';
|
|
15
|
+
export { default as HpBar } from './index16.js';
|
|
16
|
+
export { RpgSound, Sound, getSoundMetadata } from './index17.js';
|
|
17
|
+
export { RpgResource } from './index18.js';
|
|
18
|
+
export { Context } from './index19.js';
|
|
19
|
+
export { KeyboardControls, provideKeyboardControls } from './index20.js';
|
|
13
20
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;"}
|