@rpgjs/client 4.0.2 → 4.0.3

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 (45) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/browser/React-e57feed9.js +31136 -0
  3. package/browser/manifest.json +5 -0
  4. package/browser/rpg.client.js +435 -362
  5. package/browser/rpg.client.umd.cjs +31582 -373
  6. package/lib/Components/Component.js +6 -0
  7. package/lib/Components/Component.js.map +1 -1
  8. package/lib/GameEngine.d.ts +1 -0
  9. package/lib/GameEngine.js +6 -2
  10. package/lib/GameEngine.js.map +1 -1
  11. package/lib/{RpgGui.d.ts → Gui/Gui.d.ts} +27 -20
  12. package/lib/Gui/Gui.js +497 -0
  13. package/lib/Gui/Gui.js.map +1 -0
  14. package/lib/Gui/React.d.ts +14 -0
  15. package/lib/Gui/React.js +89 -0
  16. package/lib/Gui/React.js.map +1 -0
  17. package/lib/Gui/Vue.d.ts +13 -0
  18. package/lib/{RpgGuiCompiled.js → Gui/Vue.js} +64 -11
  19. package/lib/Gui/Vue.js.map +1 -0
  20. package/lib/Renderer.js +6 -4
  21. package/lib/Renderer.js.map +1 -1
  22. package/lib/RpgClientEngine.js +1 -1
  23. package/lib/RpgClientEngine.js.map +1 -1
  24. package/lib/Scene/Scene.d.ts +26 -1
  25. package/lib/Scene/Scene.js +32 -3
  26. package/lib/Scene/Scene.js.map +1 -1
  27. package/lib/index.d.ts +2 -1
  28. package/lib/index.js +2 -1
  29. package/lib/index.js.map +1 -1
  30. package/package.json +21 -6
  31. package/src/Components/Component.ts +6 -0
  32. package/src/GameEngine.ts +7 -3
  33. package/src/Gui/Gui.ts +556 -0
  34. package/src/Gui/React.ts +116 -0
  35. package/src/Gui/Vue.ts +137 -0
  36. package/src/Renderer.ts +8 -4
  37. package/src/RpgClientEngine.ts +1 -1
  38. package/src/Scene/Scene.ts +35 -4
  39. package/src/index.ts +2 -1
  40. package/lib/RpgGui.js +0 -499
  41. package/lib/RpgGui.js.map +0 -1
  42. package/lib/RpgGuiCompiled.d.ts +0 -3
  43. package/lib/RpgGuiCompiled.js.map +0 -1
  44. package/src/RpgGui.ts +0 -553
  45. package/src/RpgGuiCompiled.ts +0 -43
@@ -1,7 +1,7 @@
1
- import { RpgCommonGame, GameSide, RpgCommonPlayer, Direction as Direction$1, DefaultInput, Utils, RpgPlugin, HookClient, transitionColor, RpgShape, RpgCommonMap, Scheduler, PrebuiltGui, loadModules } from "@rpgjs/common";
1
+ import { RpgCommonGame, GameSide, RpgCommonPlayer, RpgShape, Direction as Direction$1, DefaultInput, Utils, RpgPlugin, HookClient, transitionColor, RpgCommonMap, Scheduler, PrebuiltGui, loadModules } from "@rpgjs/common";
2
2
  import { Control, Direction, HookClient as HookClient2, HookServer, Input, PrebuiltGui as PrebuiltGui2, RpgModule, RpgPlugin as RpgPlugin2, RpgCommonPlayer as RpgCommonPlayer2 } from "@rpgjs/common";
3
- import { BehaviorSubject, combineLatest, map as map$6, Subject, takeUntil, filter as filter$1, tap, finalize, distinctUntilChanged, forkJoin, lastValueFrom } from "rxjs";
4
- import { openBlock, createElementBlock, Fragment, renderList, createBlock, resolveDynamicComponent, normalizeProps, mergeProps, createCommentVNode, createElementVNode, normalizeStyle, createApp } from "vue";
3
+ import { BehaviorSubject, combineLatest, map as map$6, Subject, filter as filter$1, takeUntil, tap, finalize, distinctUntilChanged, forkJoin, lastValueFrom } from "rxjs";
4
+ import { createApp, openBlock, createElementBlock, Fragment, renderList, createBlock, resolveDynamicComponent, normalizeProps, mergeProps, createCommentVNode, createElementVNode, normalizeStyle } from "vue";
5
5
  class GameEngineClient extends RpgCommonGame {
6
6
  constructor() {
7
7
  super(GameSide.Client);
@@ -176,13 +176,11 @@ class GameEngineClient extends RpgCommonGame {
176
176
  GameEngineClient.toArray(params, "polygon");
177
177
  const isMe = () => id == this.playerId;
178
178
  let logic;
179
- let propName = "_objects";
180
179
  const createObsForObject = (data) => {
181
180
  this._obsObjectsDeleteNotifier$[id] = new Subject();
182
181
  this._obsObjects[id] = new BehaviorSubject(data);
183
182
  };
184
183
  if (isShape) {
185
- propName = "_shapes";
186
184
  logic = this.world.getShape(id);
187
185
  if (!logic) {
188
186
  logic = this.addShape(params);
@@ -240,6 +238,11 @@ class GameEngineClient extends RpgCommonGame {
240
238
  object: logic,
241
239
  paramsChanged
242
240
  };
241
+ this.setObject(id, newObject);
242
+ return newObject;
243
+ }
244
+ setObject(id, newObject) {
245
+ const propName = newObject.object instanceof RpgShape ? "_shapes" : "_objects";
243
246
  this[propName].next({
244
247
  ...this[propName].value,
245
248
  ...{
@@ -247,7 +250,6 @@ class GameEngineClient extends RpgCommonGame {
247
250
  }
248
251
  });
249
252
  this._obsObjects[id].next(newObject);
250
- return newObject;
251
253
  }
252
254
  }
253
255
  const keyCodeTable = {
@@ -36158,14 +36160,7 @@ const _hoisted_1 = {
36158
36160
  function render(_ctx, _cache) {
36159
36161
  return openBlock(), createElementBlock(
36160
36162
  "div",
36161
- {
36162
- onPointerdown: _cache[0] || (_cache[0] = ($event) => _ctx.propagate("pointerdown", $event)),
36163
- onPointermove: _cache[1] || (_cache[1] = ($event) => _ctx.propagate("pointermove", $event)),
36164
- onPointerleave: _cache[2] || (_cache[2] = ($event) => _ctx.propagate("pointerleave", $event)),
36165
- onPointerover: _cache[3] || (_cache[3] = ($event) => _ctx.propagate("pointerover", $event)),
36166
- onPointercancel: _cache[4] || (_cache[4] = ($event) => _ctx.propagate("pointercancel", $event)),
36167
- onPointerup: _cache[5] || (_cache[5] = ($event) => _ctx.propagate("pointerup", $event))
36168
- },
36163
+ {},
36169
36164
  [(openBlock(true), createElementBlock(
36170
36165
  Fragment,
36171
36166
  null,
@@ -36237,317 +36232,25 @@ function render(_ctx, _cache) {
36237
36232
  /* HYDRATE_EVENTS */
36238
36233
  );
36239
36234
  }
36240
- class Gui {
36241
- constructor() {
36242
- this.gui = {};
36243
- }
36244
- /** @internal */
36245
- _initalize(clientEngine) {
36246
- this.clientEngine = clientEngine;
36247
- this.renderer = clientEngine.renderer;
36248
- this.gameEngine = clientEngine.gameEngine;
36249
- const self2 = this;
36235
+ class VueGui {
36236
+ constructor(rootEl, parentGui) {
36237
+ this.parentGui = parentGui;
36238
+ this.clientEngine = parentGui.clientEngine;
36239
+ this.renderer = this.clientEngine.renderer;
36240
+ this.gameEngine = this.clientEngine.gameEngine;
36250
36241
  const {
36251
36242
  gui
36252
- } = this.renderer.options;
36253
- const selectorGui = this.renderer.guiEl;
36243
+ } = parentGui;
36254
36244
  const obj = {
36255
- /* template: `
36256
- <div
36257
- @pointerdown="propagate('pointerdown', $event)"
36258
- @pointermove="propagate('pointermove', $event)"
36259
- @pointerleave="propagate('pointerleave', $event)"
36260
- @pointerover="propagate('pointerover', $event)"
36261
- @pointercancel="propagate('pointercancel', $event)"
36262
- @pointerup="propagate('pointerup', $event)"
36263
- >
36264
- <template v-for="ui in fixedGui">
36265
- <component :is="ui.name" v-bind="ui.data" v-if="ui.display"></component>
36266
- </template>
36267
- <div id="tooltips" style="position: absolute; top: 0; left: 0;">
36268
- <template v-for="ui in attachedGui">
36269
- <template v-if="ui.display">
36270
- <div v-for="tooltip of tooltipFilter(tooltips, ui)" :style="tooltipPosition(tooltip.position)">
36271
- <component :is="ui.name" v-bind="{ ...ui.data, spriteData: tooltip }" :ref="ui.name"></component>
36272
- </div>
36273
- </template>
36274
- </template>
36275
- </div>
36276
- </div>
36277
- `,*/
36278
36245
  render,
36279
36246
  data() {
36280
36247
  return {
36281
- gui,
36248
+ gui: {},
36282
36249
  tooltips: []
36283
36250
  };
36284
36251
  },
36285
36252
  provide: () => {
36286
- return {
36287
- /**
36288
- * Recovery of the current scene
36289
- *
36290
- * ```js
36291
- * export default {
36292
- * inject: ['rpgScene'],
36293
- * mounted() {
36294
- * const scene = this.rpgScene()
36295
- * scene.stopInputs()
36296
- * }
36297
- * }
36298
- * ```
36299
- *
36300
- * @prop {Function returns RpgScene} [rpgScene]
36301
- * @memberof VueInject
36302
- * */
36303
- rpgScene: this.renderer.getScene.bind(this.renderer),
36304
- /**
36305
- * Retrieve the main container of the game
36306
- *
36307
- * ```js
36308
- * export default {
36309
- * inject: ['rpgStage'],
36310
- * mounted() {
36311
- * const blur = new PIXI.BlurFilter()
36312
- this.rpgStage.filters = [blur]
36313
- * }
36314
- * }
36315
- * ```
36316
- *
36317
- * @prop {PIXI.Container} [rpgStage]
36318
- * @memberof VueInject
36319
- * */
36320
- rpgStage: this.renderer.stage,
36321
- /**
36322
- * Listen to all the objects present in the room (events and players)
36323
- *
36324
- * ```js
36325
- * export default {
36326
- * inject: ['rpgObjects'],
36327
- * mounted() {
36328
- * this.obs = this.rpgObjects.subscribe((objects) => {
36329
- * for (let id in objects) {
36330
- * const obj = objects[id]
36331
- * console.log(obj.object, obj.paramsChanged)
36332
- * }
36333
- * })
36334
- * },
36335
- * unmounted() {
36336
- * this.obs.unsubscribe()
36337
- * }
36338
- * }
36339
- * ```
36340
- *
36341
- * > remember to unsubscribe for memory leaks
36342
- *
36343
- * It is an observable that returns an object:
36344
- *
36345
- * * the key is the object identifier
36346
- * * The value is an object comprising:
36347
- * * `object`: The entire object
36348
- * * `paramsChanged`: Only the representation of the properties that have been changed on this object
36349
- *
36350
- * @prop {Observable<{ [objectId]: { object: object, paramsChanged: object } }>} [rpgObjects]
36351
- * @memberof VueInject
36352
- * */
36353
- rpgObjects: this.clientEngine.objects,
36354
- /**
36355
- * Recovers and listens to the current player
36356
- *
36357
- * ```js
36358
- * export default {
36359
- * inject: ['rpgCurrentPlayer'],
36360
- * mounted() {
36361
- * this.obs = this.rpgCurrentPlayer.subscribe((obj) => {
36362
- * console.log(obj.object, obj.paramsChanged)
36363
- * })
36364
- * },
36365
- * unmounted() {
36366
- * this.obs.unsubscribe()
36367
- * }
36368
- * }
36369
- * ```
36370
- *
36371
- * * `object`: The whole player
36372
- * * `paramsChanged`: Only the representation of the properties that have been changed on this player
36373
- *
36374
- * @prop {Observable<{ object: object, paramsChanged: object }>} [rpgCurrentPlayer]
36375
- * @memberof VueInject
36376
- * */
36377
- rpgCurrentPlayer: this.clientEngine.objects.pipe(map$6((objects) => objects[this.gameEngine.playerId])),
36378
- rpgGameEngine: this.gameEngine,
36379
- /**
36380
- * Tell the server to close the GUI.
36381
- *
36382
- * It is a function with 2 parameters:
36383
- * * `name`: The name of the component
36384
- * * `data`: The data you want to pass to the server
36385
- *
36386
- * ```js
36387
- * export default {
36388
- * inject: ['rpgGuiClose'],
36389
- * methods: {
36390
- * close() {
36391
- * this.rpgGuiClose('gui-name', {
36392
- * amount: 1000
36393
- * })
36394
- * }
36395
- * }
36396
- * }
36397
- * ```
36398
- *
36399
- * @prop {Function(name, data)} [rpgGuiClose]
36400
- * @memberof VueInject
36401
- * */
36402
- rpgGuiClose(name, data) {
36403
- const guiId = name || this.$options.name;
36404
- self2.socket.emit("gui.exit", {
36405
- guiId,
36406
- data
36407
- });
36408
- },
36409
- /**
36410
- * Perform an interaction with the open GUI
36411
- *
36412
- * It is a function with 2 parameters:
36413
- * * `guiId`: The name of the component/Gui
36414
- * * `name`: The name of the interaction (defined on the server side)
36415
- * * `data`: Data to be sent
36416
- *
36417
- * ```js
36418
- * export default {
36419
- * inject: ['rpgGuiInteraction'],
36420
- * methods: {
36421
- * changeGold() {
36422
- * this.rpgGuiInteraction('gui-name', 'change-gold', {
36423
- * amount: 100
36424
- * })
36425
- * }
36426
- * }
36427
- * }
36428
- * ```
36429
- *
36430
- * @prop {Function(guiId, name, data = {})} [rpgGuiInteraction]
36431
- * @memberof VueInject
36432
- * */
36433
- rpgGuiInteraction: (guiId, name, data = {}) => {
36434
- this.socket.emit("gui.interaction", {
36435
- guiId,
36436
- name,
36437
- data
36438
- });
36439
- },
36440
- /**
36441
- * Listen to the keys that are pressed on the keyboard
36442
- *
36443
- * ```js
36444
- * export default {
36445
- * inject: ['rpgKeypress'],
36446
- * mounted() {
36447
- * this.obs = this.rpgKeypress.subscribe(({ inputName, control }) => {
36448
- * console.log(inputName) // "escape"
36449
- * console.log(control.actionName) // "back"
36450
- * })
36451
- * },
36452
- * unmounted() {
36453
- * this.obs.unsubscribe()
36454
- * }
36455
- * }
36456
- * ```
36457
- *
36458
- * @prop {Observable<{ inputName: string, control: { actionName: string, options: any } }>} [rpgKeypress]
36459
- * @memberof VueInject
36460
- * */
36461
- rpgKeypress: this.clientEngine.keyChange.pipe(map$6((name) => {
36462
- const control = this.clientEngine.controls.getControl(name);
36463
- return {
36464
- inputName: name,
36465
- control
36466
- };
36467
- })),
36468
- /**
36469
- * Recovers the socket.
36470
- *
36471
- * ```js
36472
- * export default {
36473
- * inject: ['rpgSocket'],
36474
- * mounted() {
36475
- * const socket = this.rpgSocket()
36476
- * socket.emit('foo', 'bar')
36477
- * }
36478
- * }
36479
- * ```
36480
- *
36481
- * @prop {Function returns RpgScene} [rpgSocket]
36482
- * @memberof VueInject
36483
- * */
36484
- rpgSocket: () => this.socket,
36485
- /**
36486
- * The RpgGui object to control GUIs
36487
- *
36488
- * ```js
36489
- * export default {
36490
- * inject: ['rpgGui'],
36491
- * mounted() {
36492
- * const guis = this.rpgGui.getAll()
36493
- * }
36494
- * }
36495
- * ```
36496
- *
36497
- * @prop {RpgGui} [rpgGui]
36498
- * @memberof VueInject
36499
- * */
36500
- rpgGui: this,
36501
- /**
36502
- * Equivalent to RpgSound
36503
- *
36504
- * ```js
36505
- * export default {
36506
- * inject: ['rpgSound'],
36507
- * mounted() {
36508
- * this.rpgSound.get('my-sound-id').play()
36509
- * }
36510
- * }
36511
- * ```
36512
- *
36513
- * @prop {RpgSound} [rpgSound]
36514
- * @memberof VueInject
36515
- * */
36516
- rpgSound: RpgSound,
36517
- /**
36518
- * Find the game's image and sound library
36519
- *
36520
- * ```js
36521
- * export default {
36522
- * inject: ['rpgResource'],
36523
- * mounted() {
36524
- * const resourceImage = this.rpgResource.spritesheets.get('image_id')
36525
- * const resourceSound = this.rpgResource.sounds.get('sound_id')
36526
- * }
36527
- * }
36528
- * ```
36529
- *
36530
- * @prop { { spritesheets: Map, sounds: Map } } [rpgResource]
36531
- * @memberof VueInject
36532
- * */
36533
- rpgResource: RpgResource,
36534
- /**
36535
- * Get RpgClientEngine instance
36536
- *
36537
- * ```js
36538
- * export default {
36539
- * inject: ['rpgEngine'],
36540
- * mounted() {
36541
- * const vueInstance = this.rpgEngine.vueInstance
36542
- * }
36543
- * }
36544
- * ```
36545
- *
36546
- * @prop {RpgClientEngine} [rpgEngine]
36547
- * @memberof VueInject
36548
- * */
36549
- rpgEngine: this.clientEngine
36550
- };
36253
+ return parentGui.getInjectObject();
36551
36254
  },
36552
36255
  computed: {
36553
36256
  fixedGui() {
@@ -36558,43 +36261,366 @@ class Gui {
36558
36261
  }
36559
36262
  },
36560
36263
  methods: {
36561
- propagate: (type, event) => {
36562
- this.renderer.canvas.dispatchEvent(new MouseEvent(type, event));
36563
- },
36564
- tooltipPosition: (position) => {
36565
- const scene = this.renderer.getScene();
36566
- const viewport = scene == null ? void 0 : scene.viewport;
36567
- if (viewport) {
36568
- const left = position.x - viewport.left;
36569
- const top = position.y - viewport.top;
36570
- return {
36571
- transform: `translate(${left}px,${top}px)`
36572
- };
36573
- }
36574
- },
36575
- tooltipFilter(sprites, ui) {
36576
- return sprites.filter((tooltip) => tooltip.guiDisplay);
36577
- }
36264
+ tooltipPosition: parentGui.tooltipPosition.bind(parentGui),
36265
+ tooltipFilter: parentGui.tooltipFilter.bind(parentGui)
36266
+ },
36267
+ mounted() {
36578
36268
  }
36579
36269
  };
36580
36270
  this.app = createApp(obj);
36271
+ const guiVue = Object.values(gui).filter((ui) => !Utils.isFunction(ui));
36272
+ for (let ui of guiVue) {
36273
+ this.app.component(ui.name, ui.gui);
36274
+ }
36275
+ this.vm = this.app.mount(rootEl);
36276
+ this.renderer.app = this.app;
36277
+ this.renderer.vm = this.vm;
36278
+ }
36279
+ _setSceneReady() {
36280
+ var _a;
36281
+ this.parentGui.listenTooltipObjects.subscribe((tooltips) => {
36282
+ this.vm.tooltips = [...tooltips];
36283
+ });
36284
+ (_a = this.parentGui.currentScene) == null ? void 0 : _a.objectsMoving.next({});
36285
+ }
36286
+ set gui(val) {
36287
+ for (let key in val) {
36288
+ if (val[key].isFunction)
36289
+ continue;
36290
+ this.vm.gui[key] = val[key];
36291
+ }
36292
+ this.vm.gui = Object.assign({}, this.vm.gui);
36293
+ }
36294
+ }
36295
+ const {
36296
+ elementToPositionAbsolute: elementToPositionAbsolute$1
36297
+ } = Utils;
36298
+ const COMPONENT_LIBRARIES = [VueGui];
36299
+ class Gui {
36300
+ constructor() {
36301
+ this.gui = {};
36302
+ this.currentScene = null;
36303
+ this.librariesInstances = [];
36304
+ }
36305
+ async _initialize(clientEngine, guiEl) {
36306
+ var _a;
36307
+ this.clientEngine = clientEngine;
36308
+ this.renderer = clientEngine.renderer;
36309
+ this.gameEngine = clientEngine.gameEngine;
36310
+ const {
36311
+ gui
36312
+ } = this.renderer.options;
36581
36313
  for (let ui of gui) {
36582
- this.app.component(ui.name, ui);
36583
- this.gui[ui.name] = {
36314
+ let name = ui.name;
36315
+ if (Utils.isFunction(ui)) {
36316
+ name = Utils.camelToKebab(name);
36317
+ }
36318
+ this.gui[name] = {
36584
36319
  data: ui.data,
36585
36320
  attachToSprite: ui.rpgAttachToSprite,
36586
36321
  display: false,
36587
- name: ui.name
36322
+ name,
36323
+ isFunction: Utils.isFunction(ui),
36324
+ gui: ui
36588
36325
  };
36589
36326
  }
36590
- this.vm = this.app.mount(selectorGui);
36591
- this.vm.gui = this.gui;
36592
- this.renderer.app = this.app;
36593
- this.renderer.vm = this.vm;
36327
+ if ((_a = this.clientEngine.envs) == null ? void 0 : _a["VITE_REACT"]) {
36328
+ console.warn("[RPGJS] React GUI is experimental feature. So, its use may change over time. Not yet in production");
36329
+ COMPONENT_LIBRARIES.push(await import("./React-e57feed9.js").then((m2) => m2.ReactGui));
36330
+ }
36331
+ const propagateEvents = (el) => {
36332
+ const events = ["click", "mousedown", "mouseup", "mousemove", "mouseenter", "mouseleave", "mouseover", "mouseout", "contextmenu", "pointerdown", "pointerup", "pointermove", "pointerenter", "pointerleave", "pointerover", "pointerout", "pointerupoutside", "pointercancel", "touchstart", "touchend", "touchmove", "touchcancel", "wheel", "keydown", "keyup", "keypress", "keydownoutside", "keyupoutside", "keypressoutside"];
36333
+ for (let type of events) {
36334
+ el.addEventListener(type, (e2) => {
36335
+ this.renderer.canvas.dispatchEvent(new MouseEvent(type, e2));
36336
+ });
36337
+ }
36338
+ };
36339
+ for (let componentClass of COMPONENT_LIBRARIES) {
36340
+ const el = document.createElement("div");
36341
+ elementToPositionAbsolute$1(el);
36342
+ el.style["pointer-events"] = "auto";
36343
+ propagateEvents(el);
36344
+ guiEl.appendChild(el);
36345
+ this.librariesInstances.push(new componentClass(el, this));
36346
+ }
36347
+ guiEl.style["pointer-events"] = "none";
36348
+ }
36349
+ _setSceneReady(scene) {
36350
+ this.currentScene = scene;
36351
+ this.librariesInstances.forEach((instance) => {
36352
+ if (instance._setSceneReady)
36353
+ instance._setSceneReady(scene);
36354
+ });
36594
36355
  }
36595
- /** @internal */
36596
- update(logicObjects) {
36597
- this.vm.tooltips = Object.values(logicObjects).map((object) => object.object);
36356
+ getInjectObject() {
36357
+ const self2 = this;
36358
+ return {
36359
+ /**
36360
+ * Recovery of the current scene
36361
+ *
36362
+ * ```js
36363
+ * export default {
36364
+ * inject: ['rpgScene'],
36365
+ * mounted() {
36366
+ * const scene = this.rpgScene()
36367
+ * scene.stopInputs()
36368
+ * }
36369
+ * }
36370
+ * ```
36371
+ *
36372
+ * @prop {Function returns RpgScene} [rpgScene]
36373
+ * @memberof VueInject
36374
+ * */
36375
+ rpgScene: this.renderer.getScene.bind(this.renderer),
36376
+ /**
36377
+ * Retrieve the main container of the game
36378
+ *
36379
+ * ```js
36380
+ * export default {
36381
+ * inject: ['rpgStage'],
36382
+ * mounted() {
36383
+ * const blur = new PIXI.BlurFilter()
36384
+ this.rpgStage.filters = [blur]
36385
+ * }
36386
+ * }
36387
+ * ```
36388
+ *
36389
+ * @prop {PIXI.Container} [rpgStage]
36390
+ * @memberof VueInject
36391
+ * */
36392
+ rpgStage: this.renderer.stage,
36393
+ /**
36394
+ * Listen to all the objects present in the room (events and players)
36395
+ *
36396
+ * ```js
36397
+ * export default {
36398
+ * inject: ['rpgObjects'],
36399
+ * mounted() {
36400
+ * this.obs = this.rpgObjects.subscribe((objects) => {
36401
+ * for (let id in objects) {
36402
+ * const obj = objects[id]
36403
+ * console.log(obj.object, obj.paramsChanged)
36404
+ * }
36405
+ * })
36406
+ * },
36407
+ * unmounted() {
36408
+ * this.obs.unsubscribe()
36409
+ * }
36410
+ * }
36411
+ * ```
36412
+ *
36413
+ * > remember to unsubscribe for memory leaks
36414
+ *
36415
+ * It is an observable that returns an object:
36416
+ *
36417
+ * * the key is the object identifier
36418
+ * * The value is an object comprising:
36419
+ * * `object`: The entire object
36420
+ * * `paramsChanged`: Only the representation of the properties that have been changed on this object
36421
+ *
36422
+ * @prop {Observable<{ [objectId]: { object: object, paramsChanged: object } }>} [rpgObjects]
36423
+ * @memberof VueInject
36424
+ * */
36425
+ rpgObjects: this.clientEngine.objects,
36426
+ /**
36427
+ * Recovers and listens to the current player
36428
+ *
36429
+ * ```js
36430
+ * export default {
36431
+ * inject: ['rpgCurrentPlayer'],
36432
+ * mounted() {
36433
+ * this.obs = this.rpgCurrentPlayer.subscribe((obj) => {
36434
+ * console.log(obj.object, obj.paramsChanged)
36435
+ * })
36436
+ * },
36437
+ * unmounted() {
36438
+ * this.obs.unsubscribe()
36439
+ * }
36440
+ * }
36441
+ * ```
36442
+ *
36443
+ * * `object`: The whole player
36444
+ * * `paramsChanged`: Only the representation of the properties that have been changed on this player
36445
+ *
36446
+ * @prop {Observable<{ object: object, paramsChanged: object }>} [rpgCurrentPlayer]
36447
+ * @memberof VueInject
36448
+ * */
36449
+ rpgCurrentPlayer: this.clientEngine.objects.pipe(map$6((objects) => objects[this.gameEngine.playerId]), filter$1((player) => !!player)),
36450
+ rpgGameEngine: this.gameEngine,
36451
+ /**
36452
+ * Tell the server to close the GUI.
36453
+ *
36454
+ * It is a function with 2 parameters:
36455
+ * * `name`: The name of the component
36456
+ * * `data`: The data you want to pass to the server
36457
+ *
36458
+ * ```js
36459
+ * export default {
36460
+ * inject: ['rpgGuiClose'],
36461
+ * methods: {
36462
+ * close() {
36463
+ * this.rpgGuiClose('gui-name', {
36464
+ * amount: 1000
36465
+ * })
36466
+ * }
36467
+ * }
36468
+ * }
36469
+ * ```
36470
+ *
36471
+ * @prop {Function(name, data)} [rpgGuiClose]
36472
+ * @memberof VueInject
36473
+ * */
36474
+ rpgGuiClose(name, data) {
36475
+ var _a;
36476
+ const guiId = name || ((_a = this.$options) == null ? void 0 : _a.name);
36477
+ self2.socket.emit("gui.exit", {
36478
+ guiId,
36479
+ data
36480
+ });
36481
+ },
36482
+ /**
36483
+ * Perform an interaction with the open GUI
36484
+ *
36485
+ * It is a function with 2 parameters:
36486
+ * * `guiId`: The name of the component/Gui
36487
+ * * `name`: The name of the interaction (defined on the server side)
36488
+ * * `data`: Data to be sent
36489
+ *
36490
+ * ```js
36491
+ * export default {
36492
+ * inject: ['rpgGuiInteraction'],
36493
+ * methods: {
36494
+ * changeGold() {
36495
+ * this.rpgGuiInteraction('gui-name', 'change-gold', {
36496
+ * amount: 100
36497
+ * })
36498
+ * }
36499
+ * }
36500
+ * }
36501
+ * ```
36502
+ *
36503
+ * @prop {Function(guiId, name, data = {})} [rpgGuiInteraction]
36504
+ * @memberof VueInject
36505
+ * */
36506
+ rpgGuiInteraction: (guiId, name, data = {}) => {
36507
+ this.socket.emit("gui.interaction", {
36508
+ guiId,
36509
+ name,
36510
+ data
36511
+ });
36512
+ },
36513
+ /**
36514
+ * Listen to the keys that are pressed on the keyboard
36515
+ *
36516
+ * ```js
36517
+ * export default {
36518
+ * inject: ['rpgKeypress'],
36519
+ * mounted() {
36520
+ * this.obs = this.rpgKeypress.subscribe(({ inputName, control }) => {
36521
+ * console.log(inputName) // "escape"
36522
+ * console.log(control.actionName) // "back"
36523
+ * })
36524
+ * },
36525
+ * unmounted() {
36526
+ * this.obs.unsubscribe()
36527
+ * }
36528
+ * }
36529
+ * ```
36530
+ *
36531
+ * @prop {Observable<{ inputName: string, control: { actionName: string, options: any } }>} [rpgKeypress]
36532
+ * @memberof VueInject
36533
+ * */
36534
+ rpgKeypress: this.clientEngine.keyChange.pipe(map$6((name) => {
36535
+ const control = this.clientEngine.controls.getControl(name);
36536
+ return {
36537
+ inputName: name,
36538
+ control
36539
+ };
36540
+ })),
36541
+ /**
36542
+ * Recovers the socket.
36543
+ *
36544
+ * ```js
36545
+ * export default {
36546
+ * inject: ['rpgSocket'],
36547
+ * mounted() {
36548
+ * const socket = this.rpgSocket()
36549
+ * socket.emit('foo', 'bar')
36550
+ * }
36551
+ * }
36552
+ * ```
36553
+ *
36554
+ * @prop {Function returns RpgScene} [rpgSocket]
36555
+ * @memberof VueInject
36556
+ * */
36557
+ rpgSocket: () => this.socket,
36558
+ /**
36559
+ * The RpgGui object to control GUIs
36560
+ *
36561
+ * ```js
36562
+ * export default {
36563
+ * inject: ['rpgGui'],
36564
+ * mounted() {
36565
+ * const guis = this.rpgGui.getAll()
36566
+ * }
36567
+ * }
36568
+ * ```
36569
+ *
36570
+ * @prop {RpgGui} [rpgGui]
36571
+ * @memberof VueInject
36572
+ * */
36573
+ rpgGui: this,
36574
+ /**
36575
+ * Equivalent to RpgSound
36576
+ *
36577
+ * ```js
36578
+ * export default {
36579
+ * inject: ['rpgSound'],
36580
+ * mounted() {
36581
+ * this.rpgSound.get('my-sound-id').play()
36582
+ * }
36583
+ * }
36584
+ * ```
36585
+ *
36586
+ * @prop {RpgSound} [rpgSound]
36587
+ * @memberof VueInject
36588
+ * */
36589
+ rpgSound: RpgSound,
36590
+ /**
36591
+ * Find the game's image and sound library
36592
+ *
36593
+ * ```js
36594
+ * export default {
36595
+ * inject: ['rpgResource'],
36596
+ * mounted() {
36597
+ * const resourceImage = this.rpgResource.spritesheets.get('image_id')
36598
+ * const resourceSound = this.rpgResource.sounds.get('sound_id')
36599
+ * }
36600
+ * }
36601
+ * ```
36602
+ *
36603
+ * @prop { { spritesheets: Map, sounds: Map } } [rpgResource]
36604
+ * @memberof VueInject
36605
+ * */
36606
+ rpgResource: RpgResource,
36607
+ /**
36608
+ * Get RpgClientEngine instance
36609
+ *
36610
+ * ```js
36611
+ * export default {
36612
+ * inject: ['rpgEngine'],
36613
+ * mounted() {
36614
+ * const vueInstance = this.rpgEngine.vueInstance
36615
+ * }
36616
+ * }
36617
+ * ```
36618
+ *
36619
+ * @prop {RpgClientEngine} [rpgEngine]
36620
+ * @memberof VueInject
36621
+ * */
36622
+ rpgEngine: this.clientEngine
36623
+ };
36598
36624
  }
36599
36625
  /** @internal */
36600
36626
  _setSocket(socket) {
@@ -36629,24 +36655,26 @@ class Gui {
36629
36655
  for (let key in obj) {
36630
36656
  guiObj[key] = obj[key];
36631
36657
  }
36632
- this.vm.gui = Object.assign({}, this.vm.gui);
36658
+ this.librariesInstances.forEach((instance) => {
36659
+ instance.gui = Object.assign({}, this.gui);
36660
+ });
36633
36661
  }
36634
36662
  /**
36635
- * Get a GUI. You retrieve GUI data and information whether it is displayed or not
36636
- *
36637
- * ```ts
36638
- * import { RpgGui } from '@rpgjs/client'
36639
- *
36640
- * const gui = RpgGui.get('my-gui')
36641
- * console.log(gui.display) // false
36642
- * ```
36643
- *
36644
- * @title Get a GUI
36645
- * @method RpgGui.get(id)
36646
- * @param {string} id
36647
- * @returns { { data: any, display: boolean } }
36648
- * @memberof RpgGui
36649
- */
36663
+ * Get a GUI. You retrieve GUI data and information whether it is displayed or not
36664
+ *
36665
+ * ```ts
36666
+ * import { RpgGui } from '@rpgjs/client'
36667
+ *
36668
+ * const gui = RpgGui.get('my-gui')
36669
+ * console.log(gui.display) // false
36670
+ * ```
36671
+ *
36672
+ * @title Get a GUI
36673
+ * @method RpgGui.get(id)
36674
+ * @param {string} id
36675
+ * @returns { { data: any, display: boolean } }
36676
+ * @memberof RpgGui
36677
+ */
36650
36678
  get(id) {
36651
36679
  if (typeof id != "string") {
36652
36680
  id = id.name;
@@ -36735,6 +36763,31 @@ class Gui {
36735
36763
  clear() {
36736
36764
  this.gui = {};
36737
36765
  }
36766
+ /** @internal */
36767
+ tooltipPosition(position) {
36768
+ const scene = this.renderer.getScene();
36769
+ const viewport = scene == null ? void 0 : scene.viewport;
36770
+ if (viewport) {
36771
+ const currentZoom = viewport.scale.x;
36772
+ const left = (position.x - viewport.left) * currentZoom;
36773
+ const top = (position.y - viewport.top) * currentZoom;
36774
+ return {
36775
+ transform: `translate(${left}px,${top}px)`
36776
+ };
36777
+ }
36778
+ return {};
36779
+ }
36780
+ /** @internal */
36781
+ tooltipFilter(sprites) {
36782
+ return sprites.filter((tooltip) => tooltip.guiDisplay);
36783
+ }
36784
+ /** @internal */
36785
+ get listenTooltipObjects() {
36786
+ var _a;
36787
+ return combineLatest([this.clientEngine.gameEngine.all, (_a = this.currentScene) == null ? void 0 : _a.objectsMoving]).pipe(map$6(([objects]) => {
36788
+ return Object.values(objects).map((obj) => obj.object);
36789
+ }));
36790
+ }
36738
36791
  }
36739
36792
  const RpgGui = new Gui();
36740
36793
  let Scene$1 = class Scene {
@@ -36747,6 +36800,7 @@ let Scene$1 = class Scene {
36747
36800
  data: {},
36748
36801
  partial: {}
36749
36802
  });
36803
+ this.objectsMoving = new Subject();
36750
36804
  const {
36751
36805
  globalConfig
36752
36806
  } = this.game.clientEngine;
@@ -36756,6 +36810,7 @@ let Scene$1 = class Scene {
36756
36810
  ...globalConfig.inputs || {}
36757
36811
  };
36758
36812
  this.controls.setInputs(this.inputs || mergeInputs);
36813
+ RpgGui._setSceneReady(this);
36759
36814
  }
36760
36815
  /**
36761
36816
  * Listen to all the synchronized values of the scene with the server
@@ -36814,6 +36869,7 @@ let Scene$1 = class Scene {
36814
36869
  };
36815
36870
  const renderObjects = this.objects;
36816
36871
  const sizeLogic = Object.values(logicObjects).length;
36872
+ const objectMoving = {};
36817
36873
  for (let key in logicObjects) {
36818
36874
  const val = logicObjects[key].object;
36819
36875
  const valueChanged = logicObjects[key].paramsChanged;
@@ -36826,6 +36882,8 @@ let Scene$1 = class Scene {
36826
36882
  return;
36827
36883
  const ret = object.update(val, valueChanged, time, deltaRatio);
36828
36884
  this.triggerSpriteChanges(val, object, ret.moving);
36885
+ if (ret.moving)
36886
+ objectMoving[val.id] = val;
36829
36887
  }
36830
36888
  }
36831
36889
  if (sizeLogic < renderObjects.size) {
@@ -36839,7 +36897,9 @@ let Scene$1 = class Scene {
36839
36897
  animation.update(deltaRatio);
36840
36898
  }
36841
36899
  this.onDraw(time);
36842
- RpgGui.update(logicObjects);
36900
+ if (Object.values(objectMoving).length) {
36901
+ this.objectsMoving.next(objectMoving);
36902
+ }
36843
36903
  RpgPlugin.emit(HookClient.SceneDraw, this);
36844
36904
  }
36845
36905
  /**
@@ -38151,7 +38211,14 @@ class RpgComponent extends Container {
38151
38211
  return this.logic.guiDisplay;
38152
38212
  }
38153
38213
  set guiDisplay(val) {
38214
+ var _a;
38154
38215
  this.logic.guiDisplay = val;
38216
+ this.game.setObject((_a = this.logic) == null ? void 0 : _a.id, {
38217
+ object: this.logic,
38218
+ paramsChanged: {
38219
+ guiDisplay: val
38220
+ }
38221
+ });
38155
38222
  }
38156
38223
  setPosition(smooth = true) {
38157
38224
  if (this.isShape) {
@@ -39192,6 +39259,9 @@ class SpinnerGraphic extends Graphics {
39192
39259
  this.clear().lineStyle(4, 16777215, 1).moveTo(40, 0).arc(0, 0, 40, 0, Math.PI * 2 * percent, false);
39193
39260
  }
39194
39261
  }
39262
+ const {
39263
+ elementToPositionAbsolute
39264
+ } = Utils;
39195
39265
  class RpgRenderer {
39196
39266
  constructor(clientEngine) {
39197
39267
  this.clientEngine = clientEngine;
@@ -39275,8 +39345,9 @@ class RpgRenderer {
39275
39345
  this.canvasEl = this.selector.querySelector(this.options.selectorCanvas);
39276
39346
  if (!this.guiEl) {
39277
39347
  this.guiEl = document.createElement("div");
39278
- this.selector.appendChild(this.guiEl);
39348
+ this.guiEl = this.selector.appendChild(this.guiEl);
39279
39349
  }
39350
+ elementToPositionAbsolute(this.guiEl);
39280
39351
  if (!this.canvasEl) {
39281
39352
  this.selector.insertBefore(this.renderer.view, this.selector.firstChild);
39282
39353
  const [canvas] = document.querySelector(this.options.selector).children;
@@ -39289,7 +39360,7 @@ class RpgRenderer {
39289
39360
  this.fadeContainer.addChild(this.spinner);
39290
39361
  this.fadeContainer.visible = false;
39291
39362
  this.fadeContainer.alpha = 0;
39292
- RpgGui._initalize(this.clientEngine);
39363
+ RpgGui._initialize(this.clientEngine, this.guiEl);
39293
39364
  this.resize();
39294
39365
  }
39295
39366
  /** @internal */
@@ -44015,5 +44086,7 @@ export {
44015
44086
  Sound$1 as Sound,
44016
44087
  Spritesheet,
44017
44088
  Timeline,
44018
- clientEntryPoint as entryPoint
44089
+ World,
44090
+ clientEntryPoint as entryPoint,
44091
+ room
44019
44092
  };