@rpgjs/client 5.0.0-alpha.0 → 5.0.0-alpha.10

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 (114) hide show
  1. package/dist/Game/AnimationManager.d.ts +8 -0
  2. package/dist/RpgClient.d.ts +99 -68
  3. package/dist/RpgClientEngine.d.ts +86 -4
  4. package/dist/components/animations/index.d.ts +4 -0
  5. package/dist/components/index.d.ts +2 -1
  6. package/dist/index.d.ts +1 -1
  7. package/dist/index.js +2 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/index10.js +1 -1
  10. package/dist/index11.js +4 -4
  11. package/dist/index11.js.map +1 -1
  12. package/dist/index12.js +6 -2
  13. package/dist/index12.js.map +1 -1
  14. package/dist/index13.js +2 -2
  15. package/dist/index13.js.map +1 -1
  16. package/dist/index14.js +95 -35
  17. package/dist/index14.js.map +1 -1
  18. package/dist/index15.js +45 -186
  19. package/dist/index15.js.map +1 -1
  20. package/dist/index16.js +187 -5
  21. package/dist/index16.js.map +1 -1
  22. package/dist/index17.js +5 -383
  23. package/dist/index17.js.map +1 -1
  24. package/dist/index18.js +384 -28
  25. package/dist/index18.js.map +1 -1
  26. package/dist/index19.js +24 -17
  27. package/dist/index19.js.map +1 -1
  28. package/dist/index2.js +147 -25
  29. package/dist/index2.js.map +1 -1
  30. package/dist/index20.js +16 -2413
  31. package/dist/index20.js.map +1 -1
  32. package/dist/index21.js +2395 -88
  33. package/dist/index21.js.map +1 -1
  34. package/dist/index22.js +108 -103
  35. package/dist/index22.js.map +1 -1
  36. package/dist/index23.js +95 -57
  37. package/dist/index23.js.map +1 -1
  38. package/dist/index24.js +62 -12
  39. package/dist/index24.js.map +1 -1
  40. package/dist/index25.js +18 -37
  41. package/dist/index25.js.map +1 -1
  42. package/dist/index26.js +25 -3
  43. package/dist/index26.js.map +1 -1
  44. package/dist/index27.js +87 -314
  45. package/dist/index27.js.map +1 -1
  46. package/dist/index28.js +37 -21
  47. package/dist/index28.js.map +1 -1
  48. package/dist/index29.js +3 -9
  49. package/dist/index29.js.map +1 -1
  50. package/dist/index3.js +2 -2
  51. package/dist/index30.js +317 -6
  52. package/dist/index30.js.map +1 -1
  53. package/dist/index31.js +24 -171
  54. package/dist/index31.js.map +1 -1
  55. package/dist/index32.js +7 -497
  56. package/dist/index32.js.map +1 -1
  57. package/dist/index33.js +8 -9
  58. package/dist/index33.js.map +1 -1
  59. package/dist/index34.js +9 -4400
  60. package/dist/index34.js.map +1 -1
  61. package/dist/index35.js +4397 -85
  62. package/dist/index35.js.map +1 -1
  63. package/dist/index36.js +310 -55
  64. package/dist/index36.js.map +1 -1
  65. package/dist/index37.js +169 -15
  66. package/dist/index37.js.map +1 -1
  67. package/dist/index38.js +496 -15
  68. package/dist/index38.js.map +1 -1
  69. package/dist/index39.js +61 -0
  70. package/dist/index39.js.map +1 -0
  71. package/dist/index4.js +18 -5
  72. package/dist/index4.js.map +1 -1
  73. package/dist/index40.js +20 -0
  74. package/dist/index40.js.map +1 -0
  75. package/dist/index41.js +82 -0
  76. package/dist/index41.js.map +1 -0
  77. package/dist/index5.js +2 -1
  78. package/dist/index5.js.map +1 -1
  79. package/dist/index6.js +1 -1
  80. package/dist/index7.js +10 -2
  81. package/dist/index7.js.map +1 -1
  82. package/dist/index8.js +24 -6
  83. package/dist/index8.js.map +1 -1
  84. package/dist/index9.js +2 -2
  85. package/dist/presets/animation.d.ts +31 -0
  86. package/dist/presets/index.d.ts +102 -0
  87. package/dist/presets/lpc.d.ts +89 -0
  88. package/dist/services/loadMap.d.ts +123 -2
  89. package/dist/services/mmorpg.d.ts +7 -3
  90. package/package.json +14 -12
  91. package/src/Game/{EffectManager.ts → AnimationManager.ts} +2 -2
  92. package/src/Game/Object.ts +69 -0
  93. package/src/RpgClient.ts +101 -67
  94. package/src/RpgClientEngine.ts +159 -24
  95. package/src/components/{effects → animations}/animation.ce +3 -5
  96. package/src/components/{effects → animations}/index.ts +1 -1
  97. package/src/components/character.ce +74 -33
  98. package/src/components/index.ts +2 -1
  99. package/src/components/scenes/draw-map.ce +6 -23
  100. package/src/components/scenes/event-layer.ce +3 -3
  101. package/src/core/setup.ts +2 -0
  102. package/src/index.ts +1 -1
  103. package/src/module.ts +23 -5
  104. package/src/presets/animation.ts +46 -0
  105. package/src/presets/index.ts +5 -1
  106. package/src/presets/lpc.ts +108 -0
  107. package/src/services/loadMap.ts +131 -2
  108. package/src/services/mmorpg.ts +20 -4
  109. package/tsconfig.json +1 -1
  110. package/vite.config.ts +1 -1
  111. package/dist/Game/EffectManager.d.ts +0 -5
  112. package/dist/components/effects/index.d.ts +0 -4
  113. package/src/components/scenes/element-map.ce +0 -23
  114. /package/src/components/{effects → animations}/hit.ce +0 -0
package/dist/index2.js CHANGED
@@ -1,15 +1,17 @@
1
- import component from './index14.js';
2
- import { inject } from './index15.js';
1
+ import component from './index15.js';
2
+ import { inject } from './index16.js';
3
3
  import { signal, bootstrapCanvas } from 'canvasengine';
4
- import { WebSocketToken } from './index16.js';
4
+ import { WebSocketToken } from './index17.js';
5
5
  import { LoadMapToken } from './index7.js';
6
6
  import { ModulesToken } from '@rpgjs/common';
7
- import { load } from './index17.js';
8
- import { RpgClientMap } from './index18.js';
7
+ import { load } from './index18.js';
8
+ import { RpgClientMap } from './index19.js';
9
9
  import { RpgGui } from './index9.js';
10
- import { EffectManager } from './index19.js';
10
+ import { AnimationManager } from './index20.js';
11
11
  import { lastValueFrom } from 'rxjs';
12
12
  import { GlobalConfigToken } from './index8.js';
13
+ import * as PIXI from 'pixi.js';
14
+ import { PrebuiltComponentAnimations } from './index11.js';
13
15
 
14
16
  class RpgClientEngine {
15
17
  constructor(context) {
@@ -20,25 +22,41 @@ class RpgClientEngine {
20
22
  this.height = signal("100%");
21
23
  this.spritesheets = /* @__PURE__ */ new Map();
22
24
  this.sounds = /* @__PURE__ */ new Map();
23
- this.effects = [];
25
+ this.componentAnimations = [];
24
26
  this.particleSettings = {
25
27
  emitters: []
26
28
  };
29
+ this.playerIdSignal = signal(null);
30
+ this.spriteComponentsBehind = signal([]);
31
+ this.spriteComponentsInFront = signal([]);
27
32
  this.webSocket = inject(context, WebSocketToken);
28
33
  this.guiService = inject(context, RpgGui);
29
34
  this.loadMapService = inject(context, LoadMapToken);
30
35
  this.hooks = inject(context, ModulesToken);
31
36
  this.globalConfig = inject(context, GlobalConfigToken);
37
+ this.addComponentAnimation({
38
+ id: "animation",
39
+ component: PrebuiltComponentAnimations.Animation
40
+ });
32
41
  }
33
42
  async start() {
34
43
  this.selector = document.body.querySelector("#rpg");
35
- await bootstrapCanvas(this.selector, component);
44
+ const { app, canvasElement } = await bootstrapCanvas(this.selector, component);
45
+ this.renderer = app.renderer;
46
+ this.tick = canvasElement?.propObservables?.context["tick"].observable;
36
47
  await lastValueFrom(this.hooks.callHooks("client-engine-onStart", this));
48
+ window.addEventListener("resize", () => {
49
+ this.hooks.callHooks("client-engine-onWindowResize", this).subscribe();
50
+ });
51
+ this.tick.subscribe((tick) => {
52
+ this.hooks.callHooks("client-engine-onStep", this, tick).subscribe();
53
+ });
37
54
  this.hooks.callHooks("client-spritesheets-load", this).subscribe();
38
55
  this.hooks.callHooks("client-sounds-load", this).subscribe();
39
56
  this.hooks.callHooks("client-gui-load", this).subscribe();
40
57
  this.hooks.callHooks("client-particles-load", this).subscribe();
41
- this.hooks.callHooks("client-effects-load", this).subscribe();
58
+ this.hooks.callHooks("client-componentAnimations-load", this).subscribe();
59
+ this.hooks.callHooks("client-sprite-load", this).subscribe();
42
60
  await this.webSocket.connection(() => {
43
61
  this.initListeners();
44
62
  this.guiService._initialize();
@@ -46,18 +64,34 @@ class RpgClientEngine {
46
64
  }
47
65
  initListeners() {
48
66
  this.webSocket.on("sync", (data) => {
67
+ if (data.pId) this.playerIdSignal.set(data.pId);
68
+ this.hooks.callHooks("client-sceneMap-onChanges", this.sceneMap, { partial: data }).subscribe();
49
69
  load(this.sceneMap, data, true);
50
70
  });
51
71
  this.webSocket.on("changeMap", (data) => {
52
72
  this.loadScene(data.mapId);
53
73
  });
54
- this.webSocket.on("showEffect", (data) => {
55
- const { params, object, id } = data;
56
- if (!object) {
57
- throw new Error("Object not found");
74
+ this.webSocket.on("showComponentAnimation", (data) => {
75
+ const { params, object, position, id } = data;
76
+ if (!object && position === void 0) {
77
+ throw new Error("Please provide an object or x and y coordinates");
58
78
  }
79
+ const player = object ? this.sceneMap.getObjectById(object) : void 0;
80
+ this.getComponentAnimation(id).displayEffect(params, player || position);
81
+ });
82
+ this.webSocket.on("setAnimation", (data) => {
83
+ const { animationName, nbTimes, object } = data;
59
84
  const player = this.sceneMap.getObjectById(object);
60
- this.getEffect(id).displayEffect(params, player);
85
+ player.setAnimation(animationName, nbTimes);
86
+ });
87
+ this.webSocket.on("open", () => {
88
+ this.hooks.callHooks("client-engine-onConnected", this, this.socket).subscribe();
89
+ });
90
+ this.webSocket.on("close", () => {
91
+ this.hooks.callHooks("client-engine-onDisconnected", this, this.socket).subscribe();
92
+ });
93
+ this.webSocket.on("error", (error) => {
94
+ this.hooks.callHooks("client-engine-onConnectError", this, error, this.socket).subscribe();
61
95
  });
62
96
  }
63
97
  async loadScene(mapId) {
@@ -82,30 +116,118 @@ class RpgClientEngine {
82
116
  this.particleSettings.emitters.push(particle);
83
117
  return particle;
84
118
  }
85
- addEffect(effect) {
86
- const instance = new EffectManager();
87
- this.effects.push({
88
- id: effect.id,
89
- component: effect.component,
119
+ /**
120
+ * Add a component to render behind sprites
121
+ * Components added with this method will be displayed with a lower z-index than the sprite
122
+ *
123
+ * @param component - The component to add behind sprites
124
+ * @returns The added component
125
+ *
126
+ * @example
127
+ * ```ts
128
+ * // Add a shadow component behind all sprites
129
+ * engine.addSpriteComponentBehind(ShadowComponent);
130
+ * ```
131
+ */
132
+ addSpriteComponentBehind(component) {
133
+ this.spriteComponentsBehind.update((components) => [...components, component]);
134
+ return component;
135
+ }
136
+ /**
137
+ * Add a component to render in front of sprites
138
+ * Components added with this method will be displayed with a higher z-index than the sprite
139
+ *
140
+ * @param component - The component to add in front of sprites
141
+ * @returns The added component
142
+ *
143
+ * @example
144
+ * ```ts
145
+ * // Add a health bar component in front of all sprites
146
+ * engine.addSpriteComponentInFront(HealthBarComponent);
147
+ * ```
148
+ */
149
+ addSpriteComponentInFront(component) {
150
+ this.spriteComponentsInFront.update((components) => [...components, component]);
151
+ return component;
152
+ }
153
+ /**
154
+ * Add a component animation to the engine
155
+ *
156
+ * Component animations are temporary visual effects that can be displayed
157
+ * on sprites or objects, such as hit indicators, spell effects, or status animations.
158
+ *
159
+ * @param componentAnimation - The component animation configuration
160
+ * @param componentAnimation.id - Unique identifier for the animation
161
+ * @param componentAnimation.component - The component function to render
162
+ * @returns The added component animation configuration
163
+ *
164
+ * @example
165
+ * ```ts
166
+ * // Add a hit animation component
167
+ * engine.addComponentAnimation({
168
+ * id: 'hit',
169
+ * component: HitComponent
170
+ * });
171
+ *
172
+ * // Add an explosion effect component
173
+ * engine.addComponentAnimation({
174
+ * id: 'explosion',
175
+ * component: ExplosionComponent
176
+ * });
177
+ * ```
178
+ */
179
+ addComponentAnimation(componentAnimation) {
180
+ const instance = new AnimationManager();
181
+ this.componentAnimations.push({
182
+ id: componentAnimation.id,
183
+ component: componentAnimation.component,
90
184
  instance,
91
185
  current: instance.current
92
186
  });
93
- return effect;
187
+ return componentAnimation;
94
188
  }
95
- getEffect(id) {
96
- const effect = this.effects.find((effect2) => effect2.id === id);
97
- if (!effect) {
98
- throw new Error(`Effect with id ${id} not found`);
189
+ /**
190
+ * Get a component animation by its ID
191
+ *
192
+ * Retrieves the EffectManager instance for a specific component animation,
193
+ * which can be used to display the animation on sprites or objects.
194
+ *
195
+ * @param id - The unique identifier of the component animation
196
+ * @returns The EffectManager instance for the animation
197
+ * @throws Error if the component animation is not found
198
+ *
199
+ * @example
200
+ * ```ts
201
+ * // Get the hit animation and display it
202
+ * const hitAnimation = engine.getComponentAnimation('hit');
203
+ * hitAnimation.displayEffect({ text: "Critical!" }, player);
204
+ * ```
205
+ */
206
+ getComponentAnimation(id) {
207
+ const componentAnimation = this.componentAnimations.find((componentAnimation2) => componentAnimation2.id === id);
208
+ if (!componentAnimation) {
209
+ throw new Error(`Component animation with id ${id} not found`);
99
210
  }
100
- return effect.instance;
211
+ return componentAnimation.instance;
101
212
  }
102
213
  processInput({ input }) {
214
+ this.hooks.callHooks("client-engine-onInput", this, { input, playerId: this.playerId }).subscribe();
103
215
  this.webSocket.emit("move", { input });
104
216
  }
105
217
  processAction({ action }) {
106
218
  if (this.stopProcessingInput) return;
219
+ this.hooks.callHooks("client-engine-onInput", this, { input: "action", playerId: this.playerId }).subscribe();
107
220
  this.webSocket.emit("action", { action });
108
221
  }
222
+ get PIXI() {
223
+ return PIXI;
224
+ }
225
+ get socket() {
226
+ return this.webSocket;
227
+ }
228
+ get playerId() {
229
+ return this.playerIdSignal();
230
+ }
109
231
  }
110
232
 
111
233
  export { RpgClientEngine };
@@ -1 +1 @@
1
- {"version":3,"file":"index2.js","sources":["../src/RpgClientEngine.ts"],"sourcesContent":["import Canvas from \"./components/scenes/canvas.ce\";\nimport { Context, inject } from \"@signe/di\";\nimport { signal, bootstrapCanvas } from \"canvasengine\";\nimport { AbstractWebsocket, WebSocketToken } from \"./services/AbstractSocket\";\nimport { LoadMapService, LoadMapToken } from \"./services/loadMap\";\nimport { Hooks, ModulesToken } from \"@rpgjs/common\";\nimport { load } from \"@signe/sync\";\nimport { RpgClientMap } from \"./Game/Map\"\nimport { RpgGui } from \"./Gui/Gui\";\nimport { EffectManager } from \"./Game/EffectManager\";\nimport { lastValueFrom } from \"rxjs\";\nimport { GlobalConfigToken } from \"./module\";\nimport { ClientIo } from \"@signe/room\";\n\nexport class RpgClientEngine<T = any> {\n private guiService: RpgGui;\n private webSocket: AbstractWebsocket;\n private loadMapService: LoadMapService;\n private hooks: Hooks;\n private sceneMap: RpgClientMap = new RpgClientMap();\n private selector: HTMLElement;\n public globalConfig: T;\n public sceneComponent: any;\n stopProcessingInput = false;\n\n width = signal(\"100%\");\n height = signal(\"100%\");\n spritesheets: Map<string, any> = new Map();\n sounds: Map<string, any> = new Map();\n effects: any[] = [];\n particleSettings: {\n emitters: any[]\n } = {\n emitters: []\n }\n\n constructor(public context: Context) {\n this.webSocket = inject(context, WebSocketToken);\n this.guiService = inject(context, RpgGui);\n this.loadMapService = inject(context, LoadMapToken);\n this.hooks = inject<Hooks>(context, ModulesToken);\n this.globalConfig = inject(context, GlobalConfigToken)\n }\n\n async start() {\n this.selector = document.body.querySelector(\"#rpg\") as HTMLElement;\n\n await bootstrapCanvas(this.selector, Canvas);\n\n await lastValueFrom(this.hooks.callHooks(\"client-engine-onStart\", this));\n\n this.hooks.callHooks(\"client-spritesheets-load\", this).subscribe();\n this.hooks.callHooks(\"client-sounds-load\", this).subscribe();\n this.hooks.callHooks(\"client-gui-load\", this).subscribe();\n this.hooks.callHooks(\"client-particles-load\", this).subscribe();\n this.hooks.callHooks(\"client-effects-load\", this).subscribe();\n\n \n await this.webSocket.connection(() => {\n this.initListeners()\n this.guiService._initialize()\n });\n }\n\n private initListeners() {\n this.webSocket.on(\"sync\", (data) => {\n load(this.sceneMap, data, true);\n });\n\n this.webSocket.on(\"changeMap\", (data) => {\n this.loadScene(data.mapId);\n });\n\n this.webSocket.on(\"showEffect\", (data) => {\n const { params, object, id } = data;\n if (!object) {\n throw new Error(\"Object not found\");\n }\n const player = this.sceneMap.getObjectById(object);\n this.getEffect(id).displayEffect(params, player)\n });\n }\n \n private async loadScene(mapId: string) {\n this.webSocket.updateProperties({ room: mapId })\n await this.webSocket.reconnect(() => {\n this.initListeners()\n this.guiService._initialize()\n })\n const res = await this.loadMapService.load(mapId)\n this.sceneMap.data.set(res)\n this.hooks.callHooks(\"client-sceneMap-onAfterLoading\", this.sceneMap).subscribe();\n //this.sceneMap.loadPhysic()\n }\n\n addSpriteSheet<T = any>(spritesheetClass: any, id?: string): any {\n this.spritesheets.set(id || spritesheetClass.id, spritesheetClass);\n return spritesheetClass as any;\n }\n\n addSound(sound: any, id?: string) {\n this.sounds.set(id || sound.id, sound);\n return sound;\n }\n\n addParticle(particle: any) {\n this.particleSettings.emitters.push(particle)\n return particle;\n }\n\n addEffect(effect: {\n component: any,\n id: string\n }) {\n const instance = new EffectManager()\n this.effects.push({\n id: effect.id,\n component: effect.component,\n instance: instance,\n current: instance.current\n })\n return effect;\n }\n\n getEffect(id: string): EffectManager {\n const effect = this.effects.find((effect) => effect.id === id)\n if (!effect) {\n throw new Error(`Effect with id ${id} not found`)\n }\n return effect.instance\n }\n\n processInput({ input }: { input: number }) {\n this.webSocket.emit('move', { input })\n }\n\n processAction({ action }: { action: number }) {\n if (this.stopProcessingInput) return;\n this.webSocket.emit('action', { action })\n }\n}\n"],"names":["Canvas","effect"],"mappings":"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"}
1
+ {"version":3,"file":"index2.js","sources":["../src/RpgClientEngine.ts"],"sourcesContent":["import Canvas from \"./components/scenes/canvas.ce\";\nimport { Context, inject } from \"@signe/di\";\nimport { signal, bootstrapCanvas } from \"canvasengine\";\nimport { AbstractWebsocket, WebSocketToken } from \"./services/AbstractSocket\";\nimport { LoadMapService, LoadMapToken } from \"./services/loadMap\";\nimport { Hooks, ModulesToken } from \"@rpgjs/common\";\nimport { load } from \"@signe/sync\";\nimport { RpgClientMap } from \"./Game/Map\"\nimport { RpgGui } from \"./Gui/Gui\";\nimport { AnimationManager } from \"./Game/AnimationManager\";\nimport { lastValueFrom, Observable } from \"rxjs\";\nimport { GlobalConfigToken } from \"./module\";\nimport * as PIXI from \"pixi.js\";\nimport { PrebuiltComponentAnimations } from \"./components/animations\";\n\nexport class RpgClientEngine<T = any> {\n private guiService: RpgGui;\n private webSocket: AbstractWebsocket;\n private loadMapService: LoadMapService;\n private hooks: Hooks;\n private sceneMap: RpgClientMap = new RpgClientMap();\n private selector: HTMLElement;\n public globalConfig: T;\n public sceneComponent: any;\n stopProcessingInput = false;\n width = signal(\"100%\");\n height = signal(\"100%\");\n spritesheets: Map<string, any> = new Map();\n sounds: Map<string, any> = new Map();\n componentAnimations: any[] = [];\n particleSettings: {\n emitters: any[]\n } = {\n emitters: []\n }\n renderer: PIXI.Renderer;\n tick: Observable<number>;\n playerIdSignal = signal<string | null>(null);\n spriteComponentsBehind = signal<any[]>([]);\n spriteComponentsInFront = signal<any[]>([]);\n\n constructor(public context: Context) {\n this.webSocket = inject(context, WebSocketToken);\n this.guiService = inject(context, RpgGui);\n this.loadMapService = inject(context, LoadMapToken);\n this.hooks = inject<Hooks>(context, ModulesToken);\n this.globalConfig = inject(context, GlobalConfigToken)\n\n this.addComponentAnimation({\n id: \"animation\",\n component: PrebuiltComponentAnimations.Animation\n })\n }\n\n async start() {\n this.selector = document.body.querySelector(\"#rpg\") as HTMLElement;\n\n const { app, canvasElement } = await bootstrapCanvas(this.selector, Canvas);\n this.renderer = app.renderer as PIXI.Renderer;\n this.tick = canvasElement?.propObservables?.context['tick'].observable\n\n await lastValueFrom(this.hooks.callHooks(\"client-engine-onStart\", this));\n\n // wondow is resize\n window.addEventListener('resize', () => {\n this.hooks.callHooks(\"client-engine-onWindowResize\", this).subscribe();\n })\n\n this.tick.subscribe((tick) => {\n this.hooks.callHooks(\"client-engine-onStep\", this, tick).subscribe();\n })\n\n this.hooks.callHooks(\"client-spritesheets-load\", this).subscribe();\n this.hooks.callHooks(\"client-sounds-load\", this).subscribe();\n this.hooks.callHooks(\"client-gui-load\", this).subscribe();\n this.hooks.callHooks(\"client-particles-load\", this).subscribe();\n this.hooks.callHooks(\"client-componentAnimations-load\", this).subscribe();\n this.hooks.callHooks(\"client-sprite-load\", this).subscribe();\n\n \n await this.webSocket.connection(() => {\n this.initListeners()\n this.guiService._initialize()\n });\n }\n\n private initListeners() {\n this.webSocket.on(\"sync\", (data) => {\n if (data.pId) this.playerIdSignal.set(data.pId)\n this.hooks.callHooks(\"client-sceneMap-onChanges\", this.sceneMap, { partial: data }).subscribe();\n load(this.sceneMap, data, true);\n });\n\n this.webSocket.on(\"changeMap\", (data) => {\n this.loadScene(data.mapId);\n });\n\n this.webSocket.on(\"showComponentAnimation\", (data) => {\n const { params, object, position, id } = data;\n if (!object && position === undefined) {\n throw new Error(\"Please provide an object or x and y coordinates\");\n }\n const player = object ? this.sceneMap.getObjectById(object) : undefined;\n this.getComponentAnimation(id).displayEffect(params, player || position)\n });\n\n this.webSocket.on(\"setAnimation\", (data) => {\n const { animationName, nbTimes, object } = data;\n const player = this.sceneMap.getObjectById(object);\n player.setAnimation(animationName, nbTimes)\n })\n\n this.webSocket.on('open', () => {\n this.hooks.callHooks(\"client-engine-onConnected\", this, this.socket).subscribe();\n })\n\n this.webSocket.on('close', () => {\n this.hooks.callHooks(\"client-engine-onDisconnected\", this, this.socket).subscribe();\n })\n\n this.webSocket.on('error', (error) => {\n this.hooks.callHooks(\"client-engine-onConnectError\", this, error, this.socket).subscribe();\n })\n }\n \n private async loadScene(mapId: string) {\n this.webSocket.updateProperties({ room: mapId })\n await this.webSocket.reconnect(() => {\n this.initListeners()\n this.guiService._initialize()\n })\n const res = await this.loadMapService.load(mapId)\n this.sceneMap.data.set(res)\n this.hooks.callHooks(\"client-sceneMap-onAfterLoading\", this.sceneMap).subscribe();\n //this.sceneMap.loadPhysic()\n }\n\n addSpriteSheet<T = any>(spritesheetClass: any, id?: string): any {\n this.spritesheets.set(id || spritesheetClass.id, spritesheetClass);\n return spritesheetClass as any;\n }\n\n addSound(sound: any, id?: string) {\n this.sounds.set(id || sound.id, sound);\n return sound;\n }\n\n addParticle(particle: any) {\n this.particleSettings.emitters.push(particle)\n return particle;\n }\n\n /**\n * Add a component to render behind sprites\n * Components added with this method will be displayed with a lower z-index than the sprite\n * \n * @param component - The component to add behind sprites\n * @returns The added component\n * \n * @example\n * ```ts\n * // Add a shadow component behind all sprites\n * engine.addSpriteComponentBehind(ShadowComponent);\n * ```\n */\n addSpriteComponentBehind(component: any) {\n this.spriteComponentsBehind.update((components: any[]) => [...components, component])\n return component\n }\n\n /**\n * Add a component to render in front of sprites\n * Components added with this method will be displayed with a higher z-index than the sprite\n * \n * @param component - The component to add in front of sprites\n * @returns The added component\n * \n * @example\n * ```ts\n * // Add a health bar component in front of all sprites\n * engine.addSpriteComponentInFront(HealthBarComponent);\n * ```\n */\n addSpriteComponentInFront(component: any) {\n this.spriteComponentsInFront.update((components: any[]) => [...components, component])\n return component\n }\n\n /**\n * Add a component animation to the engine\n * \n * Component animations are temporary visual effects that can be displayed\n * on sprites or objects, such as hit indicators, spell effects, or status animations.\n * \n * @param componentAnimation - The component animation configuration\n * @param componentAnimation.id - Unique identifier for the animation\n * @param componentAnimation.component - The component function to render\n * @returns The added component animation configuration\n * \n * @example\n * ```ts\n * // Add a hit animation component\n * engine.addComponentAnimation({\n * id: 'hit',\n * component: HitComponent\n * });\n * \n * // Add an explosion effect component\n * engine.addComponentAnimation({\n * id: 'explosion',\n * component: ExplosionComponent\n * });\n * ```\n */\n addComponentAnimation(componentAnimation: {\n component: any,\n id: string\n }) {\n const instance = new AnimationManager()\n this.componentAnimations.push({\n id: componentAnimation.id,\n component: componentAnimation.component,\n instance: instance,\n current: instance.current\n })\n return componentAnimation;\n }\n\n /**\n * Get a component animation by its ID\n * \n * Retrieves the EffectManager instance for a specific component animation,\n * which can be used to display the animation on sprites or objects.\n * \n * @param id - The unique identifier of the component animation\n * @returns The EffectManager instance for the animation\n * @throws Error if the component animation is not found\n * \n * @example\n * ```ts\n * // Get the hit animation and display it\n * const hitAnimation = engine.getComponentAnimation('hit');\n * hitAnimation.displayEffect({ text: \"Critical!\" }, player);\n * ```\n */\n getComponentAnimation(id: string): AnimationManager {\n const componentAnimation = this.componentAnimations.find((componentAnimation) => componentAnimation.id === id)\n if (!componentAnimation) {\n throw new Error(`Component animation with id ${id} not found`)\n }\n return componentAnimation.instance\n }\n\n processInput({ input }: { input: number }) {\n this.hooks.callHooks(\"client-engine-onInput\", this, { input, playerId: this.playerId }).subscribe();\n this.webSocket.emit('move', { input })\n }\n\n processAction({ action }: { action: number }) {\n if (this.stopProcessingInput) return;\n this.hooks.callHooks(\"client-engine-onInput\", this, { input: 'action', playerId: this.playerId }).subscribe();\n this.webSocket.emit('action', { action })\n }\n\n get PIXI() {\n return PIXI\n }\n\n get socket() {\n return this.webSocket\n }\n \n get playerId() {\n return this.playerIdSignal()\n }\n}\n"],"names":["Canvas","componentAnimation"],"mappings":"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"}