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

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/EffectManager.d.ts +5 -0
  2. package/dist/RpgClient.d.ts +68 -99
  3. package/dist/RpgClientEngine.d.ts +4 -86
  4. package/dist/components/effects/index.d.ts +4 -0
  5. package/dist/components/index.d.ts +1 -2
  6. package/dist/index.d.ts +1 -1
  7. package/dist/index.js +1 -2
  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 +2 -6
  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 +35 -95
  17. package/dist/index14.js.map +1 -1
  18. package/dist/index15.js +186 -45
  19. package/dist/index15.js.map +1 -1
  20. package/dist/index16.js +5 -187
  21. package/dist/index16.js.map +1 -1
  22. package/dist/index17.js +383 -5
  23. package/dist/index17.js.map +1 -1
  24. package/dist/index18.js +28 -384
  25. package/dist/index18.js.map +1 -1
  26. package/dist/index19.js +17 -24
  27. package/dist/index19.js.map +1 -1
  28. package/dist/index2.js +25 -147
  29. package/dist/index2.js.map +1 -1
  30. package/dist/index20.js +2413 -16
  31. package/dist/index20.js.map +1 -1
  32. package/dist/index21.js +88 -2395
  33. package/dist/index21.js.map +1 -1
  34. package/dist/index22.js +103 -108
  35. package/dist/index22.js.map +1 -1
  36. package/dist/index23.js +57 -95
  37. package/dist/index23.js.map +1 -1
  38. package/dist/index24.js +12 -62
  39. package/dist/index24.js.map +1 -1
  40. package/dist/index25.js +37 -18
  41. package/dist/index25.js.map +1 -1
  42. package/dist/index26.js +3 -25
  43. package/dist/index26.js.map +1 -1
  44. package/dist/index27.js +314 -87
  45. package/dist/index27.js.map +1 -1
  46. package/dist/index28.js +21 -37
  47. package/dist/index28.js.map +1 -1
  48. package/dist/index29.js +9 -3
  49. package/dist/index29.js.map +1 -1
  50. package/dist/index3.js +2 -2
  51. package/dist/index30.js +6 -317
  52. package/dist/index30.js.map +1 -1
  53. package/dist/index31.js +171 -24
  54. package/dist/index31.js.map +1 -1
  55. package/dist/index32.js +497 -7
  56. package/dist/index32.js.map +1 -1
  57. package/dist/index33.js +9 -8
  58. package/dist/index33.js.map +1 -1
  59. package/dist/index34.js +4400 -9
  60. package/dist/index34.js.map +1 -1
  61. package/dist/index35.js +307 -4394
  62. package/dist/index35.js.map +1 -1
  63. package/dist/index36.js +85 -310
  64. package/dist/index36.js.map +1 -1
  65. package/dist/index37.js +56 -169
  66. package/dist/index37.js.map +1 -1
  67. package/dist/index38.js +16 -497
  68. package/dist/index38.js.map +1 -1
  69. package/dist/index39.js +10 -51
  70. package/dist/index39.js.map +1 -1
  71. package/dist/index4.js +5 -18
  72. package/dist/index4.js.map +1 -1
  73. package/dist/index5.js +1 -2
  74. package/dist/index5.js.map +1 -1
  75. package/dist/index6.js +1 -1
  76. package/dist/index7.js +2 -10
  77. package/dist/index7.js.map +1 -1
  78. package/dist/index8.js +6 -24
  79. package/dist/index8.js.map +1 -1
  80. package/dist/index9.js +2 -2
  81. package/dist/presets/index.d.ts +0 -102
  82. package/dist/services/loadMap.d.ts +2 -123
  83. package/dist/services/mmorpg.d.ts +3 -7
  84. package/package.json +12 -14
  85. package/src/Game/{AnimationManager.ts → EffectManager.ts} +2 -2
  86. package/src/Game/Object.ts +0 -69
  87. package/src/RpgClient.ts +67 -101
  88. package/src/RpgClientEngine.ts +24 -159
  89. package/src/components/character.ce +33 -74
  90. package/src/components/{animations → effects}/animation.ce +5 -3
  91. package/src/components/{animations → effects}/index.ts +1 -1
  92. package/src/components/index.ts +1 -2
  93. package/src/components/scenes/draw-map.ce +23 -6
  94. package/src/components/scenes/element-map.ce +23 -0
  95. package/src/components/scenes/event-layer.ce +3 -3
  96. package/src/core/setup.ts +0 -2
  97. package/src/index.ts +1 -1
  98. package/src/module.ts +5 -23
  99. package/src/presets/index.ts +1 -5
  100. package/src/services/loadMap.ts +2 -131
  101. package/src/services/mmorpg.ts +4 -20
  102. package/tsconfig.json +1 -1
  103. package/vite.config.ts +1 -1
  104. package/dist/Game/AnimationManager.d.ts +0 -8
  105. package/dist/components/animations/index.d.ts +0 -4
  106. package/dist/index40.js +0 -20
  107. package/dist/index40.js.map +0 -1
  108. package/dist/index41.js +0 -82
  109. package/dist/index41.js.map +0 -1
  110. package/dist/presets/animation.d.ts +0 -31
  111. package/dist/presets/lpc.d.ts +0 -89
  112. package/src/presets/animation.ts +0 -46
  113. package/src/presets/lpc.ts +0 -108
  114. /package/src/components/{animations → effects}/hit.ce +0 -0
package/src/RpgClient.ts CHANGED
@@ -1,10 +1,9 @@
1
- import { ComponentFunction } from 'canvasengine'
2
1
  import { RpgClientEngine } from './RpgClientEngine'
3
- import { Loader, Container } from 'pixi.js'
2
+ import { Loader } from 'pixi.js'
4
3
 
5
4
  type RpgClass<T = any> = new (...args: any[]) => T
6
- type RpgComponent = Container
7
- type SceneMap = Container
5
+ type RpgComponent = any
6
+ type SceneMap = any
8
7
 
9
8
  export interface RpgClientEngineHooks {
10
9
  /**
@@ -13,7 +12,7 @@ export interface RpgClientEngineHooks {
13
12
  * @prop { (engine: RpgClientEngine) => boolean | any } [onStart]
14
13
  * @memberof RpgEngineHooks
15
14
  */
16
- onStart?: (engine: RpgClientEngine) => boolean | void | Promise<boolean | void>
15
+ onStart?: (engine: RpgClientEngine) => boolean | void
17
16
 
18
17
  /**
19
18
  * Each frame
@@ -66,36 +65,6 @@ export interface RpgClientEngineHooks {
66
65
  }
67
66
 
68
67
  export interface RpgSpriteHooks {
69
- /**
70
- * Array of components to render behind the sprite
71
- * These components will be displayed with a lower z-index than the sprite itself
72
- *
73
- * @prop { ComponentFunction[] } [componentsBehind]
74
- * @memberof RpgSpriteHooks
75
- * @example
76
- * ```ts
77
- * const sprite: RpgSpriteHooks = {
78
- * componentsBehind: [ShadowComponent, AuraComponent]
79
- * }
80
- * ```
81
- */
82
- componentsBehind?: ComponentFunction[]
83
-
84
- /**
85
- * Array of components to render in front of the sprite
86
- * These components will be displayed with a higher z-index than the sprite itself
87
- *
88
- * @prop { ComponentFunction[] } [componentsInFront]
89
- * @memberof RpgSpriteHooks
90
- * @example
91
- * ```ts
92
- * const sprite: RpgSpriteHooks = {
93
- * componentsInFront: [HealthBarComponent, StatusEffectComponent]
94
- * }
95
- * ```
96
- */
97
- componentsInFront?: ComponentFunction[]
98
-
99
68
  /**
100
69
  * As soon as the sprite is initialized
101
70
  *
@@ -209,13 +178,14 @@ export interface RpgClient {
209
178
  * @example
210
179
  *
211
180
  * ```ts
212
- * import { RpgClient, defineModule } from '@rpgjs/client'
181
+ * import { RpgClient, RpgModule } from '@rpgjs/client'
213
182
  *
214
- * defineModule<RpgClient>({
183
+ * @RpgModule<RpgClient>({
215
184
  * hooks: {
216
185
  * player: ['onAuth']
217
186
  * }
218
187
  * })
188
+ * class RpgClientEngine { }
219
189
  * ```
220
190
  *
221
191
  * Emit the hook:
@@ -254,7 +224,7 @@ export interface RpgClient {
254
224
  * Object containing the hooks concerning the engine
255
225
  *
256
226
  * ```ts
257
- * import { RpgClientEngine, RpgClientEngineHooks, defineModule, RpgClient } from '@rpgjs/client'
227
+ * import { RpgClientEngine, RpgClientEngineHooks, RpgModule, RpgClient } from '@rpgjs/client'
258
228
  *
259
229
  * const engine: RpgClientEngineHooks = {
260
230
  * onConnected(engine: RpgClientEngine) {
@@ -262,9 +232,10 @@ export interface RpgClient {
262
232
  * }
263
233
  * }
264
234
  *
265
- * defineModule<RpgClient>({
235
+ * @RpgModule<RpgClient>({
266
236
  * engine
267
237
  * })
238
+ * class RpgClientModule {}
268
239
  * ```
269
240
  *
270
241
  * @prop {RpgClientEngineHooks} [engine]
@@ -274,32 +245,29 @@ export interface RpgClient {
274
245
 
275
246
  /**
276
247
  * Array containing the list of spritesheets
277
- * Each element is a simple object containing spritesheet definitions
248
+ * An element contains a class with the `@Spritesheet` decorator
278
249
  *
279
250
  * ```ts
280
- * import { defineModule, RpgClient } from '@rpgjs/client'
251
+ * import { Spritesheet, Animation, Direction, RpgClient, RpgModule } from '@rpgjs/client'
252
+ *
253
+ * @Spritesheet({
254
+ * id: 'chest',
255
+ * image: require('./assets/chest.png'),
256
+ * // other options
257
+ * })
258
+ * class Chest { }
281
259
  *
282
- * defineModule<RpgClient>({
260
+ * @RpgModule<RpgClient>({
283
261
  * spritesheets: [
284
- * {
285
- * id: 'chest',
286
- * image: require('./assets/chest.png'),
287
- * framesWidth: 32,
288
- * framesHeight: 32,
289
- * animations: {
290
- * default: {
291
- * frames: [0, 1, 2],
292
- * duration: 1000
293
- * }
294
- * }
295
- * }
262
+ * Chest
296
263
  * ]
297
264
  * })
265
+ * class RpgClientEngine {}
298
266
  * ```
299
267
  *
300
268
  * [Guide: Create Sprite](/guide/create-sprite.html)
301
269
  *
302
- * @prop {Array<Object>} [spritesheets]
270
+ * @prop {Array<Class>} [spritesheets]
303
271
  * @memberof RpgClient
304
272
  * */
305
273
  spritesheets?: any[],
@@ -307,49 +275,72 @@ export interface RpgClient {
307
275
  /**
308
276
  * Array containing the list of VueJS components
309
277
  *
278
+ * ```ts
279
+ * import { RpgClient, RpgModule } from '@rpgjs/client'
280
+ *
281
+ * const component = {
282
+ * name: 'my-gui',
283
+ * template: `
284
+ * <div>
285
+ * Component
286
+ * </div>
287
+ * `
288
+ * }
289
+ *
290
+ * @RpgModule<RpgClient>({
291
+ * gui: [
292
+ * component
293
+ * ]
294
+ * })
295
+ * class RpgClientEngine {}
296
+ * ```
310
297
  *
311
298
  * [Guide: Create GUI](/guide/create-gui.html)
312
299
  *
313
- * @prop {Array<Component of CanvasEngine>} [gui]
300
+ * @prop {Array<Component of VueJS>} [gui]
314
301
  * @memberof RpgClient
315
302
  * */
316
- gui?: ComponentFunction[],
303
+ gui?: any[],
317
304
 
318
305
  /**
319
306
  * Array containing the list of sounds
320
- * Each element is a simple object containing sound definitions
307
+ * An element contains a class with the `@Sound` decorator
321
308
  *
322
309
  * ```ts
323
- * import { defineModule, RpgClient } from '@rpgjs/client'
324
- *
325
- * defineModule<RpgClient>({
326
- * sounds: [
327
- * {
328
- * town: require('./assets/Town_Theme.ogg'),
329
- * battle: require('./assets/Battle_Theme.ogg')
330
- * }
331
- * ]
310
+ * import { Sound, RpgModule, RpgClient } from '@rpgjs/client'
311
+ *
312
+ * @Sound({
313
+ * sounds: {
314
+ * town: require('./assets/Town_Theme.ogg')
315
+ * }
316
+ * })
317
+ * class Sounds {}
318
+ *
319
+ * @RpgModule<RpgClient>({
320
+ * sounds: [ Sounds ]
332
321
  * })
322
+ * class RpgClientEngine {}
333
323
  * ```
334
324
  *
335
- * @prop {Array<Object>} [sounds]
325
+ * @prop {Array<Class>} [sounds]
336
326
  * @memberof RpgClient
337
327
  * */
338
- sounds?: any[],
328
+ sounds?: RpgClass[],
339
329
 
340
330
  /**
341
331
  * Give the `RpgSprite` class. A Sprite represents a player or an event
342
332
  *
343
333
  * ```ts
344
- * import { RpgSprite, RpgSpriteHooks, RpgClient, defineModule } from '@rpgjs/client'
334
+ * import { RpgSprite, RpgSpriteHooks, RpgClient, RpgModule } from '@rpgjs/client'
345
335
  *
346
336
  * export const sprite: RpgSpriteHooks = {
347
337
  * onInit(sprite: RpgSprite) {}
348
338
  * }
349
339
  *
350
- * defineModule<RpgClient>({
340
+ * @RpgModule<RpgClient>({
351
341
  * sprite
352
342
  * })
343
+ * class RpgClientEngine {}
353
344
  * ```
354
345
  *
355
346
  * @prop {RpgSpriteHooks} [sprite]
@@ -361,18 +352,19 @@ export interface RpgClient {
361
352
  * Reference the scenes of the game. Here you can put your own class that inherits RpgSceneMap
362
353
  *
363
354
  * ```ts
364
- * import { RpgSceneMapHooks, RpgClient, defineModule } from '@rpgjs/client'
355
+ * import { RpgSceneMapHooks, RpgClient, RpgModule } from '@rpgjs/client'
365
356
  *
366
357
  * export const sceneMap: RpgSceneMapHooks = {
367
358
  *
368
359
  * }
369
360
  *
370
- * defineModule<RpgClient>({
361
+ * @RpgModule<RpgClient>({
371
362
  * scenes: {
372
363
  * // If you put the RpgSceneMap scene, Thhe key is called mandatory `map`
373
364
  * map: sceneMap
374
365
  * }
375
366
  * })
367
+ * class RpgClientEngine {}
376
368
  * ```
377
369
  *
378
370
  * @prop { [sceneName: string]: RpgSceneMapHooks } [scenes]
@@ -382,34 +374,8 @@ export interface RpgClient {
382
374
  map: RpgSceneMapHooks
383
375
  }
384
376
 
385
- /**
386
- * Array containing the list of component animations
387
- * Each element defines a temporary component to display for animations like hits, effects, etc.
388
- *
389
- * ```ts
390
- * import { defineModule, RpgClient } from '@rpgjs/client'
391
- * import HitComponent from './hit.ce'
392
- * import ExplosionComponent from './explosion.ce'
393
- *
394
- * defineModule<RpgClient>({
395
- * componentAnimations: [
396
- * {
397
- * id: 'hit',
398
- * component: HitComponent
399
- * },
400
- * {
401
- * id: 'explosion',
402
- * component: ExplosionComponent
403
- * }
404
- * ]
405
- * })
406
- * ```
407
- *
408
- * @prop {Array<{id: string, component: ComponentFunction}>} [componentAnimations]
409
- * @memberof RpgClient
410
- * */
411
- componentAnimations?: {
377
+ effects?: {
412
378
  id: string,
413
- component: ComponentFunction
379
+ component: any
414
380
  }[]
415
381
  }
@@ -7,11 +7,10 @@ import { Hooks, ModulesToken } from "@rpgjs/common";
7
7
  import { load } from "@signe/sync";
8
8
  import { RpgClientMap } from "./Game/Map"
9
9
  import { RpgGui } from "./Gui/Gui";
10
- import { AnimationManager } from "./Game/AnimationManager";
11
- import { lastValueFrom, Observable } from "rxjs";
10
+ import { EffectManager } from "./Game/EffectManager";
11
+ import { lastValueFrom } from "rxjs";
12
12
  import { GlobalConfigToken } from "./module";
13
- import * as PIXI from "pixi.js";
14
- import { PrebuiltComponentAnimations } from "./components/animations";
13
+ import { ClientIo } from "@signe/room";
15
14
 
16
15
  export class RpgClientEngine<T = any> {
17
16
  private guiService: RpgGui;
@@ -23,21 +22,17 @@ export class RpgClientEngine<T = any> {
23
22
  public globalConfig: T;
24
23
  public sceneComponent: any;
25
24
  stopProcessingInput = false;
25
+
26
26
  width = signal("100%");
27
27
  height = signal("100%");
28
28
  spritesheets: Map<string, any> = new Map();
29
29
  sounds: Map<string, any> = new Map();
30
- componentAnimations: any[] = [];
30
+ effects: any[] = [];
31
31
  particleSettings: {
32
32
  emitters: any[]
33
33
  } = {
34
34
  emitters: []
35
35
  }
36
- renderer: PIXI.Renderer;
37
- tick: Observable<number>;
38
- playerIdSignal = signal<string | null>(null);
39
- spriteComponentsBehind = signal<any[]>([]);
40
- spriteComponentsInFront = signal<any[]>([]);
41
36
 
42
37
  constructor(public context: Context) {
43
38
  this.webSocket = inject(context, WebSocketToken);
@@ -45,37 +40,20 @@ export class RpgClientEngine<T = any> {
45
40
  this.loadMapService = inject(context, LoadMapToken);
46
41
  this.hooks = inject<Hooks>(context, ModulesToken);
47
42
  this.globalConfig = inject(context, GlobalConfigToken)
48
-
49
- this.addComponentAnimation({
50
- id: "animation",
51
- component: PrebuiltComponentAnimations.Animation
52
- })
53
43
  }
54
44
 
55
45
  async start() {
56
46
  this.selector = document.body.querySelector("#rpg") as HTMLElement;
57
47
 
58
- const { app, canvasElement } = await bootstrapCanvas(this.selector, Canvas);
59
- this.renderer = app.renderer as PIXI.Renderer;
60
- this.tick = canvasElement?.propObservables?.context['tick'].observable
48
+ await bootstrapCanvas(this.selector, Canvas);
61
49
 
62
50
  await lastValueFrom(this.hooks.callHooks("client-engine-onStart", this));
63
51
 
64
- // wondow is resize
65
- window.addEventListener('resize', () => {
66
- this.hooks.callHooks("client-engine-onWindowResize", this).subscribe();
67
- })
68
-
69
- this.tick.subscribe((tick) => {
70
- this.hooks.callHooks("client-engine-onStep", this, tick).subscribe();
71
- })
72
-
73
52
  this.hooks.callHooks("client-spritesheets-load", this).subscribe();
74
53
  this.hooks.callHooks("client-sounds-load", this).subscribe();
75
54
  this.hooks.callHooks("client-gui-load", this).subscribe();
76
55
  this.hooks.callHooks("client-particles-load", this).subscribe();
77
- this.hooks.callHooks("client-componentAnimations-load", this).subscribe();
78
- this.hooks.callHooks("client-sprite-load", this).subscribe();
56
+ this.hooks.callHooks("client-effects-load", this).subscribe();
79
57
 
80
58
 
81
59
  await this.webSocket.connection(() => {
@@ -86,8 +64,6 @@ export class RpgClientEngine<T = any> {
86
64
 
87
65
  private initListeners() {
88
66
  this.webSocket.on("sync", (data) => {
89
- if (data.pId) this.playerIdSignal.set(data.pId)
90
- this.hooks.callHooks("client-sceneMap-onChanges", this.sceneMap, { partial: data }).subscribe();
91
67
  load(this.sceneMap, data, true);
92
68
  });
93
69
 
@@ -95,32 +71,14 @@ export class RpgClientEngine<T = any> {
95
71
  this.loadScene(data.mapId);
96
72
  });
97
73
 
98
- this.webSocket.on("showComponentAnimation", (data) => {
99
- const { params, object, position, id } = data;
100
- if (!object && position === undefined) {
101
- throw new Error("Please provide an object or x and y coordinates");
74
+ this.webSocket.on("showEffect", (data) => {
75
+ const { params, object, id } = data;
76
+ if (!object) {
77
+ throw new Error("Object not found");
102
78
  }
103
- const player = object ? this.sceneMap.getObjectById(object) : undefined;
104
- this.getComponentAnimation(id).displayEffect(params, player || position)
105
- });
106
-
107
- this.webSocket.on("setAnimation", (data) => {
108
- const { animationName, nbTimes, object } = data;
109
79
  const player = this.sceneMap.getObjectById(object);
110
- player.setAnimation(animationName, nbTimes)
111
- })
112
-
113
- this.webSocket.on('open', () => {
114
- this.hooks.callHooks("client-engine-onConnected", this, this.socket).subscribe();
115
- })
116
-
117
- this.webSocket.on('close', () => {
118
- this.hooks.callHooks("client-engine-onDisconnected", this, this.socket).subscribe();
119
- })
120
-
121
- this.webSocket.on('error', (error) => {
122
- this.hooks.callHooks("client-engine-onConnectError", this, error, this.socket).subscribe();
123
- })
80
+ this.getEffect(id).displayEffect(params, player)
81
+ });
124
82
  }
125
83
 
126
84
  private async loadScene(mapId: string) {
@@ -150,127 +108,34 @@ export class RpgClientEngine<T = any> {
150
108
  return particle;
151
109
  }
152
110
 
153
- /**
154
- * Add a component to render behind sprites
155
- * Components added with this method will be displayed with a lower z-index than the sprite
156
- *
157
- * @param component - The component to add behind sprites
158
- * @returns The added component
159
- *
160
- * @example
161
- * ```ts
162
- * // Add a shadow component behind all sprites
163
- * engine.addSpriteComponentBehind(ShadowComponent);
164
- * ```
165
- */
166
- addSpriteComponentBehind(component: any) {
167
- this.spriteComponentsBehind.update((components: any[]) => [...components, component])
168
- return component
169
- }
170
-
171
- /**
172
- * Add a component to render in front of sprites
173
- * Components added with this method will be displayed with a higher z-index than the sprite
174
- *
175
- * @param component - The component to add in front of sprites
176
- * @returns The added component
177
- *
178
- * @example
179
- * ```ts
180
- * // Add a health bar component in front of all sprites
181
- * engine.addSpriteComponentInFront(HealthBarComponent);
182
- * ```
183
- */
184
- addSpriteComponentInFront(component: any) {
185
- this.spriteComponentsInFront.update((components: any[]) => [...components, component])
186
- return component
187
- }
188
-
189
- /**
190
- * Add a component animation to the engine
191
- *
192
- * Component animations are temporary visual effects that can be displayed
193
- * on sprites or objects, such as hit indicators, spell effects, or status animations.
194
- *
195
- * @param componentAnimation - The component animation configuration
196
- * @param componentAnimation.id - Unique identifier for the animation
197
- * @param componentAnimation.component - The component function to render
198
- * @returns The added component animation configuration
199
- *
200
- * @example
201
- * ```ts
202
- * // Add a hit animation component
203
- * engine.addComponentAnimation({
204
- * id: 'hit',
205
- * component: HitComponent
206
- * });
207
- *
208
- * // Add an explosion effect component
209
- * engine.addComponentAnimation({
210
- * id: 'explosion',
211
- * component: ExplosionComponent
212
- * });
213
- * ```
214
- */
215
- addComponentAnimation(componentAnimation: {
111
+ addEffect(effect: {
216
112
  component: any,
217
113
  id: string
218
114
  }) {
219
- const instance = new AnimationManager()
220
- this.componentAnimations.push({
221
- id: componentAnimation.id,
222
- component: componentAnimation.component,
115
+ const instance = new EffectManager()
116
+ this.effects.push({
117
+ id: effect.id,
118
+ component: effect.component,
223
119
  instance: instance,
224
120
  current: instance.current
225
121
  })
226
- return componentAnimation;
122
+ return effect;
227
123
  }
228
124
 
229
- /**
230
- * Get a component animation by its ID
231
- *
232
- * Retrieves the EffectManager instance for a specific component animation,
233
- * which can be used to display the animation on sprites or objects.
234
- *
235
- * @param id - The unique identifier of the component animation
236
- * @returns The EffectManager instance for the animation
237
- * @throws Error if the component animation is not found
238
- *
239
- * @example
240
- * ```ts
241
- * // Get the hit animation and display it
242
- * const hitAnimation = engine.getComponentAnimation('hit');
243
- * hitAnimation.displayEffect({ text: "Critical!" }, player);
244
- * ```
245
- */
246
- getComponentAnimation(id: string): AnimationManager {
247
- const componentAnimation = this.componentAnimations.find((componentAnimation) => componentAnimation.id === id)
248
- if (!componentAnimation) {
249
- throw new Error(`Component animation with id ${id} not found`)
125
+ getEffect(id: string): EffectManager {
126
+ const effect = this.effects.find((effect) => effect.id === id)
127
+ if (!effect) {
128
+ throw new Error(`Effect with id ${id} not found`)
250
129
  }
251
- return componentAnimation.instance
130
+ return effect.instance
252
131
  }
253
132
 
254
133
  processInput({ input }: { input: number }) {
255
- this.hooks.callHooks("client-engine-onInput", this, { input, playerId: this.playerId }).subscribe();
256
134
  this.webSocket.emit('move', { input })
257
135
  }
258
136
 
259
137
  processAction({ action }: { action: number }) {
260
138
  if (this.stopProcessingInput) return;
261
- this.hooks.callHooks("client-engine-onInput", this, { input: 'action', playerId: this.playerId }).subscribe();
262
139
  this.webSocket.emit('action', { action })
263
140
  }
264
-
265
- get PIXI() {
266
- return PIXI
267
- }
268
-
269
- get socket() {
270
- return this.webSocket
271
- }
272
-
273
- get playerId() {
274
- return this.playerIdSignal()
275
- }
276
141
  }
@@ -1,57 +1,52 @@
1
1
  <Container x y zIndex={y} viewportFollow={isMe} controls>
2
- @for (component of componentsBehind) {
3
- <Container>
4
- <component object />
5
- </Container>
6
- }
7
2
  <Particle emit={@emitParticleTrigger} settings={@particleSettings} zIndex={1000} name={particleName} />
8
- <Container>
9
- @for (graphicId of graphics) {
10
- <Sprite sheet={@sheet(@graphicId)} direction tint hitbox />
11
- }
12
- </Container>
13
- @for (component of componentsInFront) {
14
- <Container>
15
- <component object />
16
- </Container>
17
- }
3
+ @for (graphicId of graphics) {
4
+ <Sprite sheet={@sheet(@graphicId)} direction tint />
5
+ }
6
+ <!-- <Ellipse
7
+ x={shadow.@x}
8
+ y={shadow.@y}
9
+ width={shadow.@width}
10
+ height={shadow.@height}
11
+ color="black"
12
+ blur={10}
13
+ alpha={0.5}
14
+ /> -->
18
15
  </Container>
19
16
 
20
17
  <script>
21
- import { signal, effect, mount, computed, tick } from "canvasengine";
18
+ import { signal, effect, mount, computed } from "canvasengine";
22
19
  import { Particle } from "@canvasengine/presets";
23
- import { GameEngineToken, ModulesToken } from "@rpgjs/common";
20
+ import { GameEngineToken } from "@rpgjs/common";
24
21
  import { RpgClientEngine } from "../RpgClientEngine";
25
22
  import { inject } from "../core/inject";
26
23
  import { Direction } from "@rpgjs/common";
27
24
  import Hit from "./effects/hit.ce";
28
25
 
29
- const { object, id } = defineProps();
30
-
26
+ const { object, id, isMe } = defineProps();
27
+
31
28
  const client = inject(RpgClientEngine);
32
- const hooks = inject(ModulesToken);
33
29
 
34
30
  const spritesheets = client.spritesheets;
35
- const playerId = client.playerId;
36
- const componentsBehind = client.spriteComponentsBehind;
37
- const componentsInFront = client.spriteComponentsInFront;
38
- const isMe = computed(() => id() === playerId);
39
-
40
- const {
41
- x,
42
- y,
43
- tint,
44
- direction,
45
- animationName,
46
- animationCurrentIndex,
47
- emitParticleTrigger,
48
- particleName,
49
- graphics,
50
- hitbox
51
- } = object;
52
31
 
32
+ const x = object.x;
33
+ const y = object.y;
34
+ const tint = object.tint;
35
+ const direction = object.direction;
36
+ const animationName = object.animationName;
37
+ const emitParticleTrigger = object.emitParticleTrigger;
53
38
  const particleSettings = client.particleSettings;
39
+ const particleName = object.particleName;
40
+ const graphics = object.graphics;
54
41
 
42
+ const hitbox = object.hitbox;
43
+ const widthShadow = 10;
44
+ const shadow = computed(() => ({
45
+ x: hitbox().w / 2,
46
+ y: hitbox().h - (hitbox().h / 2),
47
+ width: hitbox().w + widthShadow,
48
+ height: hitbox().h,
49
+ }))
55
50
  const canControls = () => isMe() && object.canMove()
56
51
  const keyboardControls = client.globalConfig.keyboardControls;
57
52
 
@@ -89,7 +84,7 @@
89
84
  keyDown() {
90
85
  if (canControls()) {
91
86
  client.processAction({ action: 'action' })
92
- // particleName.set('hit')
87
+ // particleName.set('hit')
93
88
  // emitParticleTrigger.start()
94
89
  // object.flash('red')
95
90
  }
@@ -104,42 +99,6 @@
104
99
  params: {
105
100
  direction
106
101
  },
107
- onFinish() {
108
- animationCurrentIndex.update(index => index + 1)
109
- }
110
102
  };
111
103
  }
112
-
113
- // Track animation changes to reset animation state when needed
114
- let previousAnimationName = animationName();
115
- effect(() => {
116
- const currentAnimationName = animationName();
117
-
118
- // If animation changed externally (not through setAnimation), reset the state
119
- if (currentAnimationName !== previousAnimationName && object.animationIsPlaying && object.animationIsPlaying()) {
120
- // Check if this is a movement animation (walk, stand) that should interrupt custom animations
121
- const movementAnimations = ['walk', 'stand'];
122
- if (movementAnimations.includes(currentAnimationName)) {
123
- if (typeof object.resetAnimationState === 'function') {
124
- object.resetAnimationState();
125
- }
126
- }
127
- }
128
-
129
- previousAnimationName = currentAnimationName;
130
- });
131
-
132
- mount((element) => {
133
- hooks.callHooks("client-sprite-onInit", element.componentInstance)
134
- hooks.callHooks("client-sceneMap-onAddSprite", client.sceneMap, element.componentInstance)
135
-
136
- return () => {
137
- hooks.callHooks("client-sprite-onDestroy", element.componentInstance)
138
- hooks.callHooks("client-sceneMap-onRemoveSprite", client.sceneMap, element.componentInstance)
139
- }
140
- })
141
-
142
- tick(() => {
143
- hooks.callHooks("client-sprite-onUpdate")
144
- })
145
104
  </script>