@rpgjs/client 5.0.0-alpha.20 → 5.0.0-alpha.22

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 (122) hide show
  1. package/dist/Game/Object.d.ts +109 -0
  2. package/dist/Gui/Gui.d.ts +42 -0
  3. package/dist/Resource.d.ts +97 -0
  4. package/dist/RpgClient.d.ts +42 -0
  5. package/dist/RpgClientEngine.d.ts +145 -0
  6. package/dist/index.d.ts +3 -0
  7. package/dist/index.js +4 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/index10.js +1 -1
  10. package/dist/index11.js +4 -3
  11. package/dist/index11.js.map +1 -1
  12. package/dist/index12.js +2 -2
  13. package/dist/index13.js +4 -4
  14. package/dist/index15.js +73 -4
  15. package/dist/index15.js.map +1 -1
  16. package/dist/index18.js +96 -348
  17. package/dist/index18.js.map +1 -1
  18. package/dist/index19.js +361 -45
  19. package/dist/index19.js.map +1 -1
  20. package/dist/index2.js +190 -7
  21. package/dist/index2.js.map +1 -1
  22. package/dist/index20.js +20 -6
  23. package/dist/index20.js.map +1 -1
  24. package/dist/index21.js +47 -395
  25. package/dist/index21.js.map +1 -1
  26. package/dist/index22.js +5 -42
  27. package/dist/index22.js.map +1 -1
  28. package/dist/index23.js +393 -18
  29. package/dist/index23.js.map +1 -1
  30. package/dist/index24.js +43 -2630
  31. package/dist/index24.js.map +1 -1
  32. package/dist/index25.js +19 -108
  33. package/dist/index25.js.map +1 -1
  34. package/dist/index26.js +2619 -57
  35. package/dist/index26.js.map +1 -1
  36. package/dist/index27.js +110 -17
  37. package/dist/index27.js.map +1 -1
  38. package/dist/index28.js +67 -23
  39. package/dist/index28.js.map +1 -1
  40. package/dist/index29.js +17 -91
  41. package/dist/index29.js.map +1 -1
  42. package/dist/index3.js +4 -2
  43. package/dist/index3.js.map +1 -1
  44. package/dist/index30.js +19 -33
  45. package/dist/index30.js.map +1 -1
  46. package/dist/index31.js +90 -19
  47. package/dist/index31.js.map +1 -1
  48. package/dist/index32.js +39 -3
  49. package/dist/index32.js.map +1 -1
  50. package/dist/index33.js +20 -331
  51. package/dist/index33.js.map +1 -1
  52. package/dist/index34.js +3 -25
  53. package/dist/index34.js.map +1 -1
  54. package/dist/index35.js +330 -6
  55. package/dist/index35.js.map +1 -1
  56. package/dist/index36.js +31 -8
  57. package/dist/index36.js.map +1 -1
  58. package/dist/index37.js +6 -182
  59. package/dist/index37.js.map +1 -1
  60. package/dist/index38.js +7 -500
  61. package/dist/index38.js.map +1 -1
  62. package/dist/index4.js +4 -2
  63. package/dist/index4.js.map +1 -1
  64. package/dist/index40.js +6 -6
  65. package/dist/index41.js +320 -3681
  66. package/dist/index41.js.map +1 -1
  67. package/dist/index42.js +3680 -67
  68. package/dist/index42.js.map +1 -1
  69. package/dist/index43.js +74 -3
  70. package/dist/index43.js.map +1 -1
  71. package/dist/index44.js +183 -16
  72. package/dist/index44.js.map +1 -1
  73. package/dist/index45.js +484 -126
  74. package/dist/index45.js.map +1 -1
  75. package/dist/index46.js +3 -9
  76. package/dist/index46.js.map +1 -1
  77. package/dist/index47.js +16 -109
  78. package/dist/index47.js.map +1 -1
  79. package/dist/index48.js +204 -130
  80. package/dist/index48.js.map +1 -1
  81. package/dist/index49.js +8 -133
  82. package/dist/index49.js.map +1 -1
  83. package/dist/index5.js +1 -1
  84. package/dist/index50.js +108 -107
  85. package/dist/index50.js.map +1 -1
  86. package/dist/index51.js +126 -131
  87. package/dist/index51.js.map +1 -1
  88. package/dist/index52.js +135 -7
  89. package/dist/index52.js.map +1 -1
  90. package/dist/index53.js +107 -49
  91. package/dist/index53.js.map +1 -1
  92. package/dist/index54.js +141 -0
  93. package/dist/index54.js.map +1 -0
  94. package/dist/index55.js +9 -0
  95. package/dist/index55.js.map +1 -0
  96. package/dist/index56.js +54 -0
  97. package/dist/index56.js.map +1 -0
  98. package/dist/index6.js +1 -1
  99. package/dist/index7.js +1 -1
  100. package/dist/index8.js +9 -1
  101. package/dist/index8.js.map +1 -1
  102. package/dist/index9.js +59 -11
  103. package/dist/index9.js.map +1 -1
  104. package/dist/module.d.ts +43 -4
  105. package/dist/services/keyboardControls.d.ts +16 -0
  106. package/dist/services/mmorpg.d.ts +3 -0
  107. package/dist/services/standalone.d.ts +3 -0
  108. package/package.json +11 -10
  109. package/src/Game/Object.ts +82 -8
  110. package/src/Gui/Gui.ts +64 -2
  111. package/src/Resource.ts +150 -0
  112. package/src/RpgClient.ts +42 -0
  113. package/src/RpgClientEngine.ts +216 -1
  114. package/src/components/character.ce +110 -18
  115. package/src/components/prebuilt/index.ts +2 -0
  116. package/src/components/scenes/canvas.ce +12 -10
  117. package/src/components/scenes/draw-map.ce +12 -3
  118. package/src/index.ts +4 -1
  119. package/src/module.ts +56 -2
  120. package/src/services/keyboardControls.ts +20 -0
  121. package/src/services/mmorpg.ts +2 -0
  122. package/src/services/standalone.ts +2 -0
@@ -0,0 +1,109 @@
1
+ import { Hooks, RpgCommonPlayer } from '@rpgjs/common';
2
+ import { RpgClientEngine } from '../RpgClientEngine';
3
+ export declare abstract class RpgClientObject extends RpgCommonPlayer {
4
+ abstract type: string;
5
+ emitParticleTrigger: import('canvasengine').Trigger<any>;
6
+ particleName: import('canvasengine').WritableSignal<string>;
7
+ animationCurrentIndex: import('canvasengine').WritableSignal<number>;
8
+ animationIsPlaying: import('canvasengine').WritableSignal<boolean>;
9
+ _param: import('canvasengine').WritableObjectSignal<{}>;
10
+ frames: {
11
+ x: number;
12
+ y: number;
13
+ ts: number;
14
+ }[];
15
+ graphicsSignals: import('canvasengine').WritableArraySignal<any[]>;
16
+ _component: {};
17
+ flashTrigger: import('canvasengine').Trigger<any>;
18
+ constructor();
19
+ get hooks(): Hooks;
20
+ get engine(): RpgClientEngine<unknown>;
21
+ private animationSubscription?;
22
+ /**
23
+ * Trigger a flash animation on this sprite
24
+ *
25
+ * This method triggers a flash effect using CanvasEngine's flash directive.
26
+ * The flash can be configured with various options including type (alpha, tint, or both),
27
+ * duration, cycles, and color.
28
+ *
29
+ * ## Design
30
+ *
31
+ * The flash uses a trigger system that is connected to the flash directive in the
32
+ * character component. This allows for flexible configuration and can be triggered
33
+ * from both server events and client-side code.
34
+ *
35
+ * @param options - Flash configuration options
36
+ * @param options.type - Type of flash effect: 'alpha' (opacity), 'tint' (color), or 'both' (default: 'alpha')
37
+ * @param options.duration - Duration of the flash animation in milliseconds (default: 300)
38
+ * @param options.cycles - Number of flash cycles (flash on/off) (default: 1)
39
+ * @param options.alpha - Alpha value when flashing, from 0 to 1 (default: 0.3)
40
+ * @param options.tint - Tint color when flashing as hex value or color name (default: 0xffffff - white)
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * // Simple flash with default settings (alpha flash)
45
+ * player.flash();
46
+ *
47
+ * // Flash with red tint
48
+ * player.flash({ type: 'tint', tint: 0xff0000 });
49
+ *
50
+ * // Flash with both alpha and tint
51
+ * player.flash({
52
+ * type: 'both',
53
+ * alpha: 0.5,
54
+ * tint: 0xff0000,
55
+ * duration: 200,
56
+ * cycles: 2
57
+ * });
58
+ *
59
+ * // Quick damage flash
60
+ * player.flash({
61
+ * type: 'tint',
62
+ * tint: 0xff0000,
63
+ * duration: 150,
64
+ * cycles: 1
65
+ * });
66
+ * ```
67
+ */
68
+ flash(options?: {
69
+ type?: 'alpha' | 'tint' | 'both';
70
+ duration?: number;
71
+ cycles?: number;
72
+ alpha?: number;
73
+ tint?: number | string;
74
+ }): void;
75
+ /**
76
+ * Reset animation state when animation changes externally
77
+ *
78
+ * This method should be called when the animation changes due to movement
79
+ * or other external factors to ensure the animation system doesn't get stuck
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * // Reset when player starts moving
84
+ * player.resetAnimationState();
85
+ * ```
86
+ */
87
+ resetAnimationState(): void;
88
+ /**
89
+ * Set a custom animation for a specific number of times
90
+ *
91
+ * Plays a custom animation for the specified number of repetitions.
92
+ * The animation system prevents overlapping animations and automatically
93
+ * returns to the previous animation when complete.
94
+ *
95
+ * @param animationName - Name of the animation to play
96
+ * @param nbTimes - Number of times to repeat the animation (default: Infinity for continuous)
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * // Play attack animation 3 times
101
+ * player.setAnimation('attack', 3);
102
+ *
103
+ * // Play continuous spell animation
104
+ * player.setAnimation('spell');
105
+ * ```
106
+ */
107
+ setAnimation(animationName: string, nbTimes?: number): void;
108
+ showComponentAnimation(id: string, params: any): void;
109
+ }
package/dist/Gui/Gui.d.ts CHANGED
@@ -18,6 +18,12 @@ interface GuiOptions {
18
18
  * @returns Array of Signal dependencies
19
19
  */
20
20
  dependencies?: () => Signal[];
21
+ /**
22
+ * Attach the GUI to sprites instead of displaying globally
23
+ * When true, the GUI will be rendered in character.ce for each sprite
24
+ * @default false
25
+ */
26
+ attachToSprite?: boolean;
21
27
  }
22
28
  interface GuiInstance {
23
29
  name: string;
@@ -27,6 +33,7 @@ interface GuiInstance {
27
33
  autoDisplay: boolean;
28
34
  dependencies?: () => Signal[];
29
35
  subscription?: Subscription;
36
+ attachToSprite?: boolean;
30
37
  }
31
38
  export declare class RpgGui {
32
39
  private context;
@@ -34,6 +41,11 @@ export declare class RpgGui {
34
41
  gui: import('canvasengine').WritableObjectSignal<Record<string, GuiInstance>>;
35
42
  extraGuis: GuiInstance[];
36
43
  private vueGuiInstance;
44
+ /**
45
+ * Signal tracking which player IDs should display attached GUIs
46
+ * Key: player ID, Value: boolean (true = show, false = hide)
47
+ */
48
+ attachedGuiDisplayState: import('canvasengine').WritableObjectSignal<Record<string, boolean>>;
37
49
  constructor(context: Context);
38
50
  _initialize(): Promise<void>;
39
51
  /**
@@ -73,6 +85,7 @@ export declare class RpgGui {
73
85
  * @param gui.data - Initial data for the component
74
86
  * @param gui.autoDisplay - Auto display when added (default: false)
75
87
  * @param gui.dependencies - Function returning Signal dependencies
88
+ * @param gui.attachToSprite - Attach GUI to sprites instead of global display (default: false)
76
89
  *
77
90
  * @example
78
91
  * ```ts
@@ -82,9 +95,38 @@ export declare class RpgGui {
82
95
  * autoDisplay: true,
83
96
  * dependencies: () => [playerSignal, inventorySignal]
84
97
  * });
98
+ *
99
+ * // Attach to sprites
100
+ * gui.add({
101
+ * name: 'tooltip',
102
+ * component: TooltipComponent,
103
+ * attachToSprite: true
104
+ * });
85
105
  * ```
86
106
  */
87
107
  add(gui: GuiOptions): void;
108
+ /**
109
+ * Get all attached GUI components (attachToSprite: true)
110
+ *
111
+ * Returns all GUI instances that are configured to be attached to sprites.
112
+ * These GUIs should be rendered in character.ce instead of canvas.ce.
113
+ *
114
+ * @returns Array of GUI instances with attachToSprite: true
115
+ *
116
+ * @example
117
+ * ```ts
118
+ * const attachedGuis = gui.getAttachedGuis();
119
+ * // Use in character.ce to render tooltips
120
+ * ```
121
+ */
122
+ getAttachedGuis(): GuiInstance[];
123
+ /**
124
+ * Check if a player should display attached GUIs
125
+ *
126
+ * @param playerId - The player ID to check
127
+ * @returns true if attached GUIs should be displayed for this player
128
+ */
129
+ shouldDisplayAttachedGui(playerId: string): boolean;
88
130
  get(id: string): GuiInstance | undefined;
89
131
  exists(id: string): boolean;
90
132
  getAll(): Record<string, GuiInstance>;
@@ -0,0 +1,97 @@
1
+ import { RpgClientEngine } from './RpgClientEngine';
2
+ /**
3
+ * RpgResource class
4
+ *
5
+ * Provides a unified API to access resource file links (images and sounds) in the game.
6
+ * Resources are stored as Maps of resource IDs to file paths/URLs.
7
+ *
8
+ * ## Design
9
+ *
10
+ * RpgResource acts as a facade over the engine's resource storage, providing
11
+ * easy access to resource file links. It maintains Maps that are synchronized
12
+ * with the engine's internal storage, but only stores the file paths/URLs,
13
+ * not the full resource objects.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { RpgResource } from '@rpgjs/client'
18
+ *
19
+ * // Get spritesheet image link
20
+ * const imageLink = RpgResource.spritesheets.get('hero')
21
+ *
22
+ * // Get sound file link
23
+ * const soundLink = RpgResource.sounds.get('town-music')
24
+ *
25
+ * // Set a new resource link
26
+ * RpgResource.spritesheets.set('new-sprite', './assets/new-sprite.png')
27
+ * ```
28
+ */
29
+ export declare class RpgResource {
30
+ private static engine;
31
+ private static _spritesheets;
32
+ private static _sounds;
33
+ /**
34
+ * Initialize RpgResource with the engine instance
35
+ *
36
+ * This is called automatically by the engine during initialization.
37
+ * It synchronizes the resource Maps with the engine's internal storage.
38
+ *
39
+ * @param engine - The RpgClientEngine instance
40
+ */
41
+ static init(engine: RpgClientEngine): void;
42
+ /**
43
+ * Synchronize resource Maps with the engine's internal storage
44
+ *
45
+ * Extracts file links from spritesheets and sounds stored in the engine
46
+ * and updates the Maps accordingly.
47
+ *
48
+ * @private
49
+ */
50
+ private static syncResources;
51
+ /**
52
+ * Get/Set image links for spritesheets
53
+ *
54
+ * Map of spritesheet IDs to their image file paths/URLs.
55
+ * This Map is synchronized with the engine's spritesheet storage.
56
+ *
57
+ * @type {Map<string, string>}
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * // Get an image link
62
+ * const imageLink = RpgResource.spritesheets.get('hero')
63
+ *
64
+ * // Set a new image link
65
+ * RpgResource.spritesheets.set('new-sprite', './assets/new-sprite.png')
66
+ *
67
+ * // Check if a spritesheet exists
68
+ * if (RpgResource.spritesheets.has('monster')) {
69
+ * const link = RpgResource.spritesheets.get('monster')
70
+ * }
71
+ * ```
72
+ */
73
+ static get spritesheets(): Map<string, string>;
74
+ /**
75
+ * Get/Set sound file links
76
+ *
77
+ * Map of sound IDs to their audio file paths/URLs.
78
+ * This Map is synchronized with the engine's sound storage.
79
+ *
80
+ * @type {Map<string, string>}
81
+ *
82
+ * @example
83
+ * ```ts
84
+ * // Get a sound link
85
+ * const soundLink = RpgResource.sounds.get('town-music')
86
+ *
87
+ * // Set a new sound link
88
+ * RpgResource.sounds.set('new-sound', './assets/new-sound.ogg')
89
+ *
90
+ * // Iterate over all sounds
91
+ * RpgResource.sounds.forEach((link, id) => {
92
+ * console.log(`Sound ${id}: ${link}`)
93
+ * })
94
+ * ```
95
+ */
96
+ static get sounds(): Map<string, string>;
97
+ }
@@ -383,6 +383,48 @@ export interface RpgClient {
383
383
  * The GUI will only display when all dependencies are resolved (!= undefined)
384
384
  */
385
385
  dependencies?: () => Signal[];
386
+ /**
387
+ * Attach the GUI to sprites instead of displaying globally
388
+ *
389
+ * When set to `true`, the GUI component will be rendered directly on each sprite
390
+ * in the game world, rather than being displayed as a fixed overlay on the screen.
391
+ * This is useful for tooltips, health bars, name tags, or any UI element that
392
+ * should follow a specific sprite.
393
+ *
394
+ * The GUI will be rendered in the `character.ce` component for each sprite.
395
+ * You can control the display state of attached GUIs from the server side using
396
+ * `player.showAttachedGui()` and `player.hideAttachedGui()` methods.
397
+ *
398
+ * @default false
399
+ * @example
400
+ * ```ts
401
+ * import { defineModule, RpgClient } from '@rpgjs/client'
402
+ * import TooltipComponent from './tooltip.ce'
403
+ *
404
+ * defineModule<RpgClient>({
405
+ * gui: [
406
+ * {
407
+ * id: "my-tooltip",
408
+ * component: TooltipComponent,
409
+ * attachToSprite: true
410
+ * }
411
+ * ]
412
+ * })
413
+ * ```
414
+ *
415
+ * On the server side, control the display:
416
+ * ```ts
417
+ * // Show the tooltip for this player
418
+ * player.showAttachedGui()
419
+ *
420
+ * // Hide the tooltip for this player
421
+ * player.hideAttachedGui()
422
+ *
423
+ * // Show tooltip for other players
424
+ * player.showAttachedGui([otherPlayer1, otherPlayer2])
425
+ * ```
426
+ */
427
+ attachToSprite?: boolean;
386
428
  } | any)[];
387
429
  /**
388
430
  * Array containing the list of sounds
@@ -31,6 +31,10 @@ export declare class RpgClientEngine<T = any> {
31
31
  playerIdSignal: import('canvasengine').WritableSignal<string | null>;
32
32
  spriteComponentsBehind: import('canvasengine').WritableArraySignal<any[]>;
33
33
  spriteComponentsInFront: import('canvasengine').WritableArraySignal<any[]>;
34
+ /** ID of the sprite that the camera should follow. null means follow the current player */
35
+ cameraFollowTargetId: import('canvasengine').WritableSignal<string | null>;
36
+ /** Trigger for map shake animation */
37
+ mapShakeTrigger: import('canvasengine').Trigger<any>;
34
38
  private predictionEnabled;
35
39
  private prediction?;
36
40
  private readonly SERVER_CORRECTION_THRESHOLD;
@@ -41,6 +45,40 @@ export declare class RpgClientEngine<T = any> {
41
45
  private readonly PING_INTERVAL_MS;
42
46
  private lastInputTime;
43
47
  constructor(context: Context);
48
+ /**
49
+ * Assigns a CanvasEngine KeyboardControls instance to the dependency injection context
50
+ *
51
+ * This method registers a KeyboardControls instance from CanvasEngine into the DI container,
52
+ * making it available for injection throughout the application. The particularity is that
53
+ * this method is automatically called when a sprite is displayed on the map, allowing the
54
+ * controls to be automatically associated with the active sprite.
55
+ *
56
+ * ## Design
57
+ *
58
+ * - The instance is stored in the DI context under the `KeyboardControls` token
59
+ * - It's automatically assigned when a sprite component mounts (in `character.ce`)
60
+ * - The controls instance comes from the CanvasEngine component's directives
61
+ * - Once registered, it can be retrieved using `inject(KeyboardControls)` from anywhere
62
+ *
63
+ * @param controlInstance - The CanvasEngine KeyboardControls instance to register
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * // The method is automatically called when a sprite is displayed:
68
+ * // client.setKeyboardControls(element.directives.controls)
69
+ *
70
+ * // Later, retrieve and use the controls instance:
71
+ * import { Input, inject, KeyboardControls } from '@rpgjs/client'
72
+ *
73
+ * const controls = inject(KeyboardControls)
74
+ * const control = controls.getControl(Input.Enter)
75
+ *
76
+ * if (control) {
77
+ * console.log(control.actionName) // 'action'
78
+ * }
79
+ * ```
80
+ */
81
+ setKeyboardControls(controlInstance: any): void;
44
82
  start(): Promise<void>;
45
83
  private initListeners;
46
84
  /**
@@ -257,6 +295,59 @@ export declare class RpgClientEngine<T = any> {
257
295
  * ```
258
296
  */
259
297
  stopSound(soundId: string): void;
298
+ /**
299
+ * Stop all currently playing sounds
300
+ *
301
+ * This method stops all sounds that are currently playing.
302
+ * Useful when changing maps to prevent sound overlap.
303
+ *
304
+ * @example
305
+ * ```ts
306
+ * // Stop all sounds
307
+ * engine.stopAllSounds();
308
+ * ```
309
+ */
310
+ stopAllSounds(): void;
311
+ /**
312
+ * Set the camera to follow a specific sprite
313
+ *
314
+ * This method changes which sprite the camera viewport should follow.
315
+ * The camera will smoothly animate to the target sprite if smoothMove options are provided.
316
+ *
317
+ * ## Design
318
+ *
319
+ * The camera follow target is stored in a signal that is read by sprite components.
320
+ * Each sprite checks if it should be followed by comparing its ID with the target ID.
321
+ * When smoothMove options are provided, the viewport animation is handled by CanvasEngine's
322
+ * viewport system.
323
+ *
324
+ * @param targetId - The ID of the sprite to follow. Set to null to follow the current player
325
+ * @param smoothMove - Animation options. Can be a boolean (default: true) or an object with time and ease
326
+ * @param smoothMove.time - Duration of the animation in milliseconds (optional)
327
+ * @param smoothMove.ease - Easing function name from https://easings.net (optional)
328
+ *
329
+ * @example
330
+ * ```ts
331
+ * // Follow another player with default smooth animation
332
+ * engine.setCameraFollow(otherPlayerId, true);
333
+ *
334
+ * // Follow an event with custom smooth animation
335
+ * engine.setCameraFollow(eventId, {
336
+ * time: 1000,
337
+ * ease: "easeInOutQuad"
338
+ * });
339
+ *
340
+ * // Follow without animation (instant)
341
+ * engine.setCameraFollow(targetId, false);
342
+ *
343
+ * // Return to following current player
344
+ * engine.setCameraFollow(null);
345
+ * ```
346
+ */
347
+ setCameraFollow(targetId: string | null, smoothMove?: boolean | {
348
+ time?: number;
349
+ ease?: string;
350
+ }): void;
260
351
  addParticle(particle: any): any;
261
352
  /**
262
353
  * Add a component to render behind sprites
@@ -365,6 +456,60 @@ export declare class RpgClientEngine<T = any> {
365
456
  * ```
366
457
  */
367
458
  clearClientPredictionStates(): void;
459
+ /**
460
+ * Trigger a flash animation on a sprite
461
+ *
462
+ * This method allows you to trigger a flash effect on any sprite from client-side code.
463
+ * The flash can be configured with various options including type (alpha, tint, or both),
464
+ * duration, cycles, and color.
465
+ *
466
+ * ## Design
467
+ *
468
+ * The flash is applied directly to the sprite object using its flash trigger.
469
+ * This is useful for client-side visual feedback, UI interactions, or local effects
470
+ * that don't need to be synchronized with the server.
471
+ *
472
+ * @param spriteId - The ID of the sprite to flash. If not provided, flashes the current player
473
+ * @param options - Flash configuration options
474
+ * @param options.type - Type of flash effect: 'alpha' (opacity), 'tint' (color), or 'both' (default: 'alpha')
475
+ * @param options.duration - Duration of the flash animation in milliseconds (default: 300)
476
+ * @param options.cycles - Number of flash cycles (flash on/off) (default: 1)
477
+ * @param options.alpha - Alpha value when flashing, from 0 to 1 (default: 0.3)
478
+ * @param options.tint - Tint color when flashing as hex value or color name (default: 0xffffff - white)
479
+ *
480
+ * @example
481
+ * ```ts
482
+ * // Flash the current player with default settings
483
+ * engine.flash();
484
+ *
485
+ * // Flash a specific sprite with red tint
486
+ * engine.flash('sprite-id', { type: 'tint', tint: 0xff0000 });
487
+ *
488
+ * // Flash with both alpha and tint for dramatic effect
489
+ * engine.flash(undefined, {
490
+ * type: 'both',
491
+ * alpha: 0.5,
492
+ * tint: 0xff0000,
493
+ * duration: 200,
494
+ * cycles: 2
495
+ * });
496
+ *
497
+ * // Quick damage flash on current player
498
+ * engine.flash(undefined, {
499
+ * type: 'tint',
500
+ * tint: 'red',
501
+ * duration: 150,
502
+ * cycles: 1
503
+ * });
504
+ * ```
505
+ */
506
+ flash(spriteId?: string, options?: {
507
+ type?: 'alpha' | 'tint' | 'both';
508
+ duration?: number;
509
+ cycles?: number;
510
+ alpha?: number;
511
+ tint?: number | string;
512
+ }): void;
368
513
  private applyServerAck;
369
514
  /**
370
515
  * Replay unacknowledged inputs from a given frame to resimulate client prediction
package/dist/index.d.ts CHANGED
@@ -13,4 +13,7 @@ export * from './presets';
13
13
  export * from './components';
14
14
  export * from './components/gui';
15
15
  export * from './Sound';
16
+ export * from './Resource';
16
17
  export { Context } from '@signe/di';
18
+ export { KeyboardControls, Input } from 'canvasengine';
19
+ export { Control } from './services/keyboardControls';
package/dist/index.js CHANGED
@@ -14,5 +14,8 @@ export { default as EventLayerComponent } from './index14.js';
14
14
  export { default as CharacterComponent } from './index15.js';
15
15
  export { default as HpBar } from './index16.js';
16
16
  export { RpgSound, Sound, getSoundMetadata } from './index17.js';
17
- export { Context } from './index18.js';
17
+ export { RpgResource } from './index18.js';
18
+ export { Context } from './index19.js';
19
+ export { Input, KeyboardControls } from 'canvasengine';
20
+ export { Control } from './index20.js';
18
21
  //# 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":";;;;;;;;;;;;;;;;;;;"}
package/dist/index10.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { useProps, useDefineProps, signal, animatedSignal, computed, trigger, mount, effect, h, Container, Rect, cond, Text, Sprite } from 'canvasengine';
2
- import component$1 from './index42.js';
2
+ import component$1 from './index43.js';
3
3
  import { inject } from './index6.js';
4
4
  import { RpgClientEngine } from './index2.js';
5
5
 
package/dist/index11.js CHANGED
@@ -1,13 +1,14 @@
1
1
  import { useProps, useDefineProps, computed, h, Container, Rect } from 'canvasengine';
2
2
  import { RpgClientEngine } from './index2.js';
3
- import './index24.js';
3
+ import './index26.js';
4
4
  import '@rpgjs/common';
5
- import './index18.js';
5
+ import './index19.js';
6
6
  import { inject } from './index6.js';
7
7
  import 'rxjs';
8
- import './index25.js';
8
+ import './index27.js';
9
9
  import './index17.js';
10
10
  import '@canvasengine/presets';
11
+ import './index18.js';
11
12
 
12
13
  function component($$props) {
13
14
  useProps($$props);
@@ -1 +1 @@
1
- {"version":3,"file":"index11.js","sources":["../src/components/gui/box.ce"],"sourcesContent":["<Container positionType=\"absolute\" top={top} left={left}>\n <Container\n anchor={[0.5, 0.5]}\n >\n <Rect width height color={_color} />\n <Container attach={child}></Container>\n </Container> \n</Container>\n\n<script>\n import { RpgClientEngine, inject } from \"../../index\";\n\n const { width, height, children, color, top, left } = defineProps();\n const engine = inject(RpgClientEngine)\n const child = children[0]\n const _color = computed(() => engine.globalConfig.gui?.windowColor || color?.() || \"#1a1a2e\")\n</script>"],"names":[],"mappings":";;;;;;;;;;;AAOqB,SAAS,SAAS,CAAC,OAAO,EAAE;AACjD,QAAuB,QAAQ,CAAC,OAAO;AACvC,QAAQ,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO;AAClD,QAAQ,IAAI,EAAE,GAAG,WAAW,EAAE,EAAE,KAAK,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,EAAE,CAAC,QAAQ,EAAE,KAAK,GAAG,EAAE,CAAC,KAAK,EAAE,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,IAAI,GAAG,EAAE,CAAC,IAAI;AAC5I,IAAI,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC;AACpC,IAAI,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC;AACvB,IAAI,MAAM,GAAG,QAAQ,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,KAAK,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC,WAAW,MAAM,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC;AAClN,QAAQ,IAAI,KAAK,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AACvM,QAAQ,OAAO;AACf,MAAM;;;;"}
1
+ {"version":3,"file":"index11.js","sources":["../src/components/gui/box.ce"],"sourcesContent":["<Container positionType=\"absolute\" top={top} left={left}>\n <Container\n anchor={[0.5, 0.5]}\n >\n <Rect width height color={_color} />\n <Container attach={child}></Container>\n </Container> \n</Container>\n\n<script>\n import { RpgClientEngine, inject } from \"../../index\";\n\n const { width, height, children, color, top, left } = defineProps();\n const engine = inject(RpgClientEngine)\n const child = children[0]\n const _color = computed(() => engine.globalConfig.gui?.windowColor || color?.() || \"#1a1a2e\")\n</script>"],"names":[],"mappings":";;;;;;;;;;;;AAOqB,SAAS,SAAS,CAAC,OAAO,EAAE;AACjD,QAAuB,QAAQ,CAAC,OAAO;AACvC,QAAQ,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO;AAClD,QAAQ,IAAI,EAAE,GAAG,WAAW,EAAE,EAAE,KAAK,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,EAAE,CAAC,QAAQ,EAAE,KAAK,GAAG,EAAE,CAAC,KAAK,EAAE,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,IAAI,GAAG,EAAE,CAAC,IAAI;AAC5I,IAAI,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC;AACpC,IAAI,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC;AACvB,IAAI,MAAM,GAAG,QAAQ,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,KAAK,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC,WAAW,MAAM,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC;AAClN,QAAQ,IAAI,KAAK,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AACvM,QAAQ,OAAO;AACf,MAAM;;;;"}
package/dist/index12.js CHANGED
@@ -1,5 +1,5 @@
1
- import component$1 from './index26.js';
2
- import component from './index27.js';
1
+ import component$1 from './index28.js';
2
+ import component from './index29.js';
3
3
 
4
4
  const PrebuiltComponentAnimations = {
5
5
  Hit: component$1,
package/dist/index13.js CHANGED
@@ -1,7 +1,7 @@
1
- import { AnimationSpritesheetPreset } from './index28.js';
2
- import { LPCSpritesheetPreset } from './index29.js';
3
- import { RMSpritesheet } from './index30.js';
4
- import { FacesetPreset } from './index31.js';
1
+ import { AnimationSpritesheetPreset } from './index30.js';
2
+ import { LPCSpritesheetPreset } from './index31.js';
3
+ import { RMSpritesheet } from './index32.js';
4
+ import { FacesetPreset } from './index33.js';
5
5
 
6
6
  const Presets = {
7
7
  RMSpritesheet,