@rpgjs/client 4.1.3 → 4.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/browser/{React-da18564b.js → React-f6f9b1de.js} +25 -0
- package/browser/index-e74a289f.js +44225 -0
- package/browser/manifest.json +10 -1
- package/browser/rpg.client.js +33 -44122
- package/browser/rpg.client.umd.cjs +470 -341
- package/lib/Effects/TransitionScene.d.ts +4 -3
- package/lib/Effects/TransitionScene.js +4 -2
- package/lib/Effects/TransitionScene.js.map +1 -1
- package/lib/GameEngine.d.ts +1 -1
- package/lib/GameEngine.js +4 -1
- package/lib/GameEngine.js.map +1 -1
- package/lib/Gui/Gui.d.ts +2 -1
- package/lib/Gui/Gui.js +7 -5
- package/lib/Gui/Gui.js.map +1 -1
- package/lib/Gui/React.d.ts +1 -0
- package/lib/Gui/React.js +23 -0
- package/lib/Gui/React.js.map +1 -1
- package/lib/Gui/Vue.js +21 -2
- package/lib/Gui/Vue.js.map +1 -1
- package/lib/KeyboardControls.d.ts +40 -14
- package/lib/KeyboardControls.js +42 -15
- package/lib/KeyboardControls.js.map +1 -1
- package/lib/Presets/AnimationSpritesheet.d.ts +3 -3
- package/lib/Presets/AnimationSpritesheet.js +7 -3
- package/lib/Presets/AnimationSpritesheet.js.map +1 -1
- package/lib/Renderer.d.ts +13 -5
- package/lib/Renderer.js +40 -16
- package/lib/Renderer.js.map +1 -1
- package/lib/Resources.js.map +1 -1
- package/lib/RpgClientEngine.d.ts +10 -4
- package/lib/RpgClientEngine.js +26 -17
- package/lib/RpgClientEngine.js.map +1 -1
- package/lib/Scene/Map.d.ts +4 -5
- package/lib/Scene/Map.js +6 -4
- package/lib/Scene/Map.js.map +1 -1
- package/lib/Scene/Scene.d.ts +7 -2
- package/lib/Scene/Scene.js +9 -3
- package/lib/Scene/Scene.js.map +1 -1
- package/lib/Tilemap/index.d.ts +4 -3
- package/lib/Tilemap/index.js +7 -3
- package/lib/Tilemap/index.js.map +1 -1
- package/lib/clientEntryPoint.js +5 -5
- package/lib/clientEntryPoint.js.map +1 -1
- package/lib/index.d.ts +3 -0
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -1
- package/lib/inject.d.ts +23 -0
- package/lib/inject.js +30 -0
- package/lib/inject.js.map +1 -0
- package/package.json +6 -6
- package/src/Effects/TransitionScene.ts +3 -1
- package/src/GameEngine.ts +2 -2
- package/src/Gui/Gui.ts +5 -5
- package/src/Gui/React.ts +26 -1
- package/src/Gui/Vue.ts +24 -6
- package/src/KeyboardControls.ts +43 -15
- package/src/Presets/AnimationSpritesheet.ts +9 -4
- package/src/Renderer.ts +44 -19
- package/src/Resources.ts +0 -1
- package/src/RpgClientEngine.ts +29 -18
- package/src/Scene/Map.ts +8 -7
- package/src/Scene/Scene.ts +8 -4
- package/src/Tilemap/index.ts +6 -4
- package/src/clientEntryPoint.ts +6 -4
- package/src/index.ts +4 -1
- package/src/inject.ts +34 -0
package/src/KeyboardControls.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DefaultInput, Direction, Input, Utils } from '@rpgjs/common'
|
|
1
|
+
import { DefaultInput, Direction, InjectContext, Input, Utils } from '@rpgjs/common'
|
|
2
2
|
import { ControlOptions, Controls } from '@rpgjs/types';
|
|
3
3
|
import { RpgClientEngine } from './RpgClientEngine';
|
|
4
4
|
|
|
@@ -191,6 +191,8 @@ const inverseKeyCodeTable = inverse(keyCodeTable)
|
|
|
191
191
|
type BoundKey = { actionName: string, options: ControlOptions, parameters?: any }
|
|
192
192
|
|
|
193
193
|
export class KeyboardControls {
|
|
194
|
+
private clientEngine: RpgClientEngine = this.context.inject(RpgClientEngine)
|
|
195
|
+
|
|
194
196
|
private keyState: {
|
|
195
197
|
[keyName: string]: {
|
|
196
198
|
isDown: boolean,
|
|
@@ -204,8 +206,8 @@ export class KeyboardControls {
|
|
|
204
206
|
private lastKeyPressed: number | null = null
|
|
205
207
|
private _controlsOptions: Controls = {}
|
|
206
208
|
|
|
207
|
-
constructor(private
|
|
208
|
-
const { globalConfig } = clientEngine
|
|
209
|
+
constructor(private context: InjectContext) {
|
|
210
|
+
const { globalConfig } = this.clientEngine
|
|
209
211
|
this.setupListeners();
|
|
210
212
|
this.setInputs({
|
|
211
213
|
...DefaultInput,
|
|
@@ -340,10 +342,11 @@ export class KeyboardControls {
|
|
|
340
342
|
* From the name of the entry, we retrieve the control information
|
|
341
343
|
*
|
|
342
344
|
* ```ts
|
|
343
|
-
* import { Input } from '@rpgjs/client'
|
|
345
|
+
* import { Input, inject, KeyboardControls } from '@rpgjs/client'
|
|
344
346
|
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
+
* const controls = inject(KeyboardControls)
|
|
348
|
+
* controls.getControl(Input.Enter)
|
|
349
|
+
|
|
347
350
|
* if (control) {
|
|
348
351
|
* console.log(control.actionName) // action
|
|
349
352
|
* }
|
|
@@ -358,23 +361,36 @@ export class KeyboardControls {
|
|
|
358
361
|
return this.boundKeys[inputName]
|
|
359
362
|
}
|
|
360
363
|
|
|
364
|
+
/**
|
|
365
|
+
* Returns all controls
|
|
366
|
+
*
|
|
367
|
+
* @method getControls()
|
|
368
|
+
* @since 4.2.0
|
|
369
|
+
* @returns { { [key: string]: BoundKey } }
|
|
370
|
+
* @memberof KeyboardControls
|
|
371
|
+
*/
|
|
372
|
+
getControls(): { [key: string]: BoundKey } {
|
|
373
|
+
return this.boundKeys
|
|
374
|
+
}
|
|
375
|
+
|
|
361
376
|
/**
|
|
362
377
|
* Triggers an input according to the name of the control
|
|
363
378
|
*
|
|
364
379
|
* ```ts
|
|
365
|
-
* import { Control } from '@rpgjs/client'
|
|
380
|
+
* import { Control, inject, KeyboardControls } from '@rpgjs/client'
|
|
366
381
|
*
|
|
367
|
-
*
|
|
368
|
-
*
|
|
382
|
+
* const controls = inject(KeyboardControls)
|
|
383
|
+
* controls.applyControl(Control.Action)
|
|
369
384
|
* ```
|
|
370
385
|
*
|
|
371
386
|
* You can put a second parameter or indicate on whether the key is pressed or released
|
|
372
387
|
*
|
|
373
388
|
* ```ts
|
|
374
|
-
* import { Control } from '@rpgjs/client'
|
|
389
|
+
* import { Control, inject, KeyboardControls } from '@rpgjs/client'
|
|
375
390
|
*
|
|
376
|
-
*
|
|
377
|
-
*
|
|
391
|
+
* const controls = inject(KeyboardControls)
|
|
392
|
+
* controls.applyControl(Control.Up, true) // keydown
|
|
393
|
+
* controls.applyControl(Control.Up, false) // keyup
|
|
378
394
|
* ```
|
|
379
395
|
* @title Apply Control
|
|
380
396
|
* @method applyControl(controlName,isDown)
|
|
@@ -439,10 +455,10 @@ export class KeyboardControls {
|
|
|
439
455
|
* * delay.otherControls {string | string[]} Indicates the other controls that will also have the delay at the same time
|
|
440
456
|
*
|
|
441
457
|
* ```ts
|
|
442
|
-
* import { Control, Input } from '@rpgjs/client'
|
|
458
|
+
* import { Control, Input, inject, KeyboardControls } from '@rpgjs/client'
|
|
443
459
|
*
|
|
444
|
-
*
|
|
445
|
-
*
|
|
460
|
+
* const controls = inject(KeyboardControls)
|
|
461
|
+
* controls.setInputs({
|
|
446
462
|
[Control.Up]: {
|
|
447
463
|
repeat: true,
|
|
448
464
|
bind: Input.Up
|
|
@@ -505,6 +521,18 @@ export class KeyboardControls {
|
|
|
505
521
|
* Control.Action | action
|
|
506
522
|
* Control.Back | back
|
|
507
523
|
*
|
|
524
|
+
* @enum {string} Mouse Event
|
|
525
|
+
*
|
|
526
|
+
* click | Click
|
|
527
|
+
* dblclick | Double Click
|
|
528
|
+
* mousedown | Mouse Down
|
|
529
|
+
* mouseup | Mouse Up
|
|
530
|
+
* mouseover | Mouse Over
|
|
531
|
+
* mousemove | Mouse Move
|
|
532
|
+
* mouseout | Mouse Out
|
|
533
|
+
* contextmenu | Context Menu
|
|
534
|
+
*
|
|
535
|
+
*
|
|
508
536
|
* @enum {string} Input
|
|
509
537
|
*
|
|
510
538
|
* break | Pause
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { Direction } from '@rpgjs/common'
|
|
2
2
|
import { Animation } from '../Effects/AnimationCharacter'
|
|
3
3
|
|
|
4
|
-
export const RMSpritesheet = (framesWidth, framesHeight, frameStand = 1) => {
|
|
4
|
+
export const RMSpritesheet = (framesWidth: number, framesHeight: number, frameStand: number = 1) => {
|
|
5
|
+
|
|
6
|
+
if (framesWidth <= frameStand) {
|
|
7
|
+
frameStand = framesWidth - 1
|
|
8
|
+
}
|
|
5
9
|
|
|
6
10
|
const frameY = direction => {
|
|
11
|
+
const gap = Math.max(4 - framesHeight, 0)
|
|
7
12
|
return {
|
|
8
13
|
[Direction.Down]: 0,
|
|
9
|
-
[Direction.Left]: 1,
|
|
10
|
-
[Direction.Right]: 2,
|
|
11
|
-
[Direction.Up]: 3
|
|
14
|
+
[Direction.Left]: Math.max(0, 1 - gap),
|
|
15
|
+
[Direction.Right]: Math.max(0, 2 - gap),
|
|
16
|
+
[Direction.Up]: Math.max(0, 3 - gap)
|
|
12
17
|
}[direction]
|
|
13
18
|
}
|
|
14
19
|
|
package/src/Renderer.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RpgPlugin, HookClient, Utils } from '@rpgjs/common'
|
|
1
|
+
import { RpgPlugin, HookClient, Utils, InjectContext } from '@rpgjs/common'
|
|
2
2
|
import { SceneMap } from './Scene/Map'
|
|
3
3
|
import { Scene } from './Scene/Scene'
|
|
4
4
|
import { Scene as PresetScene } from './Presets/Scene'
|
|
@@ -10,6 +10,7 @@ import { Subject, forkJoin } from 'rxjs'
|
|
|
10
10
|
import { GameEngineClient } from './GameEngine'
|
|
11
11
|
import { SpinnerGraphic } from './Effects/Spinner'
|
|
12
12
|
import { autoDetectRenderer, Container, EventBoundary, FederatedEvent, FederatedPointerEvent, Graphics, ICanvas, IRenderer } from 'pixi.js'
|
|
13
|
+
import { KeyboardControls } from './KeyboardControls'
|
|
13
14
|
|
|
14
15
|
const { elementToPositionAbsolute } = Utils
|
|
15
16
|
|
|
@@ -22,7 +23,17 @@ enum ContainerName {
|
|
|
22
23
|
Map = 'map'
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
export const EVENTS_MAP = {
|
|
27
|
+
MouseEvent: ['click', 'dblclick', 'mousedown', 'mouseup', 'mousemove', 'mouseenter', 'mouseleave', 'mouseover', 'mouseout', 'contextmenu', 'wheel'],
|
|
28
|
+
KeyboardEvent: ['keydown', 'keyup', 'keypress', 'keydownoutside', 'keyupoutside', 'keypressoutside'],
|
|
29
|
+
PointerEvent: ['pointerdown', 'pointerup', 'pointermove', 'pointerover', 'pointerout', 'pointerenter', 'pointerleave', 'pointercancel'],
|
|
30
|
+
TouchEvent: ['touchstart', 'touchend', 'touchmove', 'touchcancel']
|
|
31
|
+
};
|
|
32
|
+
|
|
25
33
|
export class RpgRenderer {
|
|
34
|
+
private gameEngine: GameEngineClient = this.context.inject(GameEngineClient)
|
|
35
|
+
private clientEngine: RpgClientEngine = this.context.inject(RpgClientEngine)
|
|
36
|
+
|
|
26
37
|
public vm: ComponentPublicInstance
|
|
27
38
|
public app: App
|
|
28
39
|
public readonly stage: Container = new Container()
|
|
@@ -38,7 +49,6 @@ export class RpgRenderer {
|
|
|
38
49
|
private _height: number = 400
|
|
39
50
|
private canvasEl: HTMLElement
|
|
40
51
|
private selector: HTMLElement
|
|
41
|
-
private gameEngine: GameEngineClient = this.clientEngine.gameEngine
|
|
42
52
|
private loadingScene = {
|
|
43
53
|
transitionIn: new Subject(),
|
|
44
54
|
transitionOut: new Subject()
|
|
@@ -47,7 +57,7 @@ export class RpgRenderer {
|
|
|
47
57
|
private prevObjectScene: any = {}
|
|
48
58
|
public transitionMode: TransitionMode = TransitionMode.Fading
|
|
49
59
|
|
|
50
|
-
constructor(private
|
|
60
|
+
constructor(private context: InjectContext) {
|
|
51
61
|
this.clientEngine.tick.subscribe(({ timestamp, deltaRatio, frame, deltaTime }) => {
|
|
52
62
|
this.draw(timestamp, deltaTime, deltaRatio, frame)
|
|
53
63
|
})
|
|
@@ -81,8 +91,8 @@ export class RpgRenderer {
|
|
|
81
91
|
this.spinner.y = h * 0.5
|
|
82
92
|
}
|
|
83
93
|
|
|
84
|
-
get canvas():
|
|
85
|
-
return this.renderer.view
|
|
94
|
+
get canvas(): HTMLCanvasElement {
|
|
95
|
+
return this.renderer.view as HTMLCanvasElement
|
|
86
96
|
}
|
|
87
97
|
|
|
88
98
|
get height(): number {
|
|
@@ -135,9 +145,24 @@ export class RpgRenderer {
|
|
|
135
145
|
this.fadeContainer.visible = false
|
|
136
146
|
this.fadeContainer.alpha = 0
|
|
137
147
|
|
|
138
|
-
await RpgGui._initialize(this.
|
|
148
|
+
await RpgGui._initialize(this.context, this.guiEl)
|
|
139
149
|
|
|
140
150
|
this.resize()
|
|
151
|
+
this.bindMouseControls()
|
|
152
|
+
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
private bindMouseControls() {
|
|
156
|
+
const controlInstance = this.context.inject(KeyboardControls)
|
|
157
|
+
const controls = controlInstance.getControls()
|
|
158
|
+
for (let key in controls) {
|
|
159
|
+
const { actionName } = controls[key]
|
|
160
|
+
if (EVENTS_MAP.MouseEvent.includes(key)) {
|
|
161
|
+
this.canvas.addEventListener(key, (e) => {
|
|
162
|
+
controlInstance.applyControl(actionName)
|
|
163
|
+
})
|
|
164
|
+
}
|
|
165
|
+
}
|
|
141
166
|
}
|
|
142
167
|
|
|
143
168
|
/** @internal */
|
|
@@ -205,7 +230,7 @@ export class RpgRenderer {
|
|
|
205
230
|
this.loadingScene.transitionOut.complete()
|
|
206
231
|
}
|
|
207
232
|
if (this.transitionMode == TransitionMode.Fading) {
|
|
208
|
-
new TransitionScene(this.
|
|
233
|
+
new TransitionScene(this.context, this.fadeContainer)
|
|
209
234
|
.addFadeOut()
|
|
210
235
|
.onComplete(finish)
|
|
211
236
|
.start()
|
|
@@ -232,7 +257,7 @@ export class RpgRenderer {
|
|
|
232
257
|
switch (name) {
|
|
233
258
|
case PresetScene.Map:
|
|
234
259
|
const sceneClass = scenes[PresetScene.Map] || SceneMap
|
|
235
|
-
this.scene = new sceneClass(this.
|
|
260
|
+
this.scene = new sceneClass(this.context, this.renderer, {
|
|
236
261
|
screenWidth: this.renderer.screen.width,
|
|
237
262
|
screenHeight: this.renderer.screen.height,
|
|
238
263
|
drawMap: this.options.drawMap
|
|
@@ -248,7 +273,7 @@ export class RpgRenderer {
|
|
|
248
273
|
RpgPlugin.emit(HookClient.AfterSceneLoading, this.scene)
|
|
249
274
|
}
|
|
250
275
|
if (this.transitionMode == TransitionMode.Fading) {
|
|
251
|
-
new TransitionScene(this.
|
|
276
|
+
new TransitionScene(this.context, this.fadeContainer)
|
|
252
277
|
.addFadeIn()
|
|
253
278
|
.onComplete(finish)
|
|
254
279
|
.start()
|
|
@@ -273,11 +298,18 @@ export class RpgRenderer {
|
|
|
273
298
|
* @returns {void}
|
|
274
299
|
*/
|
|
275
300
|
propagateEvent(ev: MouseEvent) {
|
|
301
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
302
|
+
const canvasX = rect.left + window.scrollX;
|
|
303
|
+
const canvasY = rect.top + window.scrollY;
|
|
304
|
+
const realX = ev.clientX - canvasX;
|
|
305
|
+
const realY = ev.clientY - canvasY;
|
|
276
306
|
const boundary = new EventBoundary(this.stage);
|
|
277
307
|
const event = new FederatedPointerEvent(boundary)
|
|
278
|
-
event.global.set(
|
|
308
|
+
event.global.set(realX, realY);
|
|
279
309
|
event.type = ev.type;
|
|
280
|
-
|
|
310
|
+
const hitTestTarget = boundary.hitTest(realX, realY);
|
|
311
|
+
hitTestTarget?.dispatchEvent(event)
|
|
312
|
+
this.canvas.dispatchEvent(new MouseEvent(ev.type, ev))
|
|
281
313
|
}
|
|
282
314
|
|
|
283
315
|
/***
|
|
@@ -290,14 +322,7 @@ export class RpgRenderer {
|
|
|
290
322
|
* @returns {void}
|
|
291
323
|
*/
|
|
292
324
|
addPropagateEventsFrom(el: HTMLElement) {
|
|
293
|
-
|
|
294
|
-
MouseEvent: ['click', 'mousedown', 'mouseup', 'mousemove', 'mouseenter', 'mouseleave', 'mouseover', 'mouseout', 'contextmenu', 'wheel'],
|
|
295
|
-
KeyboardEvent: ['keydown', 'keyup', 'keypress', 'keydownoutside', 'keyupoutside', 'keypressoutside'],
|
|
296
|
-
PointerEvent: ['pointerdown', 'pointerup', 'pointermove', 'pointerover', 'pointerout', 'pointerenter', 'pointerleave', 'pointercancel'],
|
|
297
|
-
TouchEvent: ['touchstart', 'touchend', 'touchmove', 'touchcancel']
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
for (let [_Constructor, events] of Object.entries(eventMap)) {
|
|
325
|
+
for (let [_Constructor, events] of Object.entries(EVENTS_MAP)) {
|
|
301
326
|
for (let type of events) {
|
|
302
327
|
el.addEventListener(type, (e) => {
|
|
303
328
|
const _class = window[_Constructor] ?? MouseEvent
|
package/src/Resources.ts
CHANGED
package/src/RpgClientEngine.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
RpgCommonMap,
|
|
16
16
|
Scheduler,
|
|
17
17
|
Control,
|
|
18
|
+
InjectContext,
|
|
18
19
|
} from '@rpgjs/common'
|
|
19
20
|
import { RpgSound } from './Sound/RpgSound'
|
|
20
21
|
import { SceneMap } from './Scene/Map'
|
|
@@ -48,6 +49,7 @@ export class RpgClientEngine {
|
|
|
48
49
|
*
|
|
49
50
|
* @prop {RpgRenderer} [renderer]
|
|
50
51
|
* @readonly
|
|
52
|
+
* @deprecated Use `inject(RpgRenderer)` instead. Will be removed in v5
|
|
51
53
|
* @memberof RpgClientEngine
|
|
52
54
|
* */
|
|
53
55
|
public renderer: RpgRenderer
|
|
@@ -74,6 +76,7 @@ export class RpgClientEngine {
|
|
|
74
76
|
* Get the class managing the keyboard
|
|
75
77
|
*
|
|
76
78
|
* @prop {KeyboardControls} [controls]
|
|
79
|
+
* @deprecated Use `inject(KeyboardControls)` instead. Will be removed in v5
|
|
77
80
|
* @readonly
|
|
78
81
|
* @memberof RpgClientEngine
|
|
79
82
|
* */
|
|
@@ -107,6 +110,10 @@ export class RpgClientEngine {
|
|
|
107
110
|
private serverFps: number = 60
|
|
108
111
|
private scheduler: Scheduler = new Scheduler()
|
|
109
112
|
private _serverUrl: string = ''
|
|
113
|
+
/**
|
|
114
|
+
* * @deprecated Use `inject(GameEngineClient)` instead. Will be removed in v5
|
|
115
|
+
*/
|
|
116
|
+
public gameEngine = this.context.inject(GameEngineClient)
|
|
110
117
|
|
|
111
118
|
/**
|
|
112
119
|
* Read objects synchronized with the server
|
|
@@ -124,7 +131,7 @@ export class RpgClientEngine {
|
|
|
124
131
|
|
|
125
132
|
envs?: object = {}
|
|
126
133
|
|
|
127
|
-
constructor(
|
|
134
|
+
constructor(private context: InjectContext, private options) {
|
|
128
135
|
this.envs = options.envs || {}
|
|
129
136
|
this.tick.subscribe(({ timestamp, deltaTime }) => {
|
|
130
137
|
if (timestamp != -1) this.step(timestamp, deltaTime)
|
|
@@ -132,9 +139,9 @@ export class RpgClientEngine {
|
|
|
132
139
|
}
|
|
133
140
|
|
|
134
141
|
private async _init() {
|
|
135
|
-
this.renderer =
|
|
142
|
+
this.renderer = this.context.inject(RpgRenderer)
|
|
136
143
|
|
|
137
|
-
const
|
|
144
|
+
const pluginLoadResource = async (hookName: string, type: string) => {
|
|
138
145
|
const resource = this.options[type] || []
|
|
139
146
|
this.options[type] = [
|
|
140
147
|
...Utils.arrayFlat(await RpgPlugin.emit(hookName, resource)) || [],
|
|
@@ -142,9 +149,9 @@ export class RpgClientEngine {
|
|
|
142
149
|
]
|
|
143
150
|
}
|
|
144
151
|
|
|
145
|
-
await
|
|
146
|
-
await
|
|
147
|
-
await
|
|
152
|
+
await pluginLoadResource(HookClient.AddSpriteSheet, 'spritesheets')
|
|
153
|
+
await pluginLoadResource(HookClient.AddGui, 'gui')
|
|
154
|
+
await pluginLoadResource(HookClient.AddSound, 'sounds')
|
|
148
155
|
|
|
149
156
|
this.renderer.options = {
|
|
150
157
|
selector: '#rpg',
|
|
@@ -170,8 +177,8 @@ export class RpgClientEngine {
|
|
|
170
177
|
const id: any = isString(sound) ? extractId(sound) : undefined
|
|
171
178
|
this.addSound(sound, id)
|
|
172
179
|
})
|
|
173
|
-
|
|
174
|
-
//
|
|
180
|
+
|
|
181
|
+
// deprecated
|
|
175
182
|
if (typeof __RPGJS_PRODUCTION__ != 'undefined' && __RPGJS_PRODUCTION__) {
|
|
176
183
|
if ('serviceWorker' in navigator) {
|
|
177
184
|
window.addEventListener('load', () => {
|
|
@@ -180,7 +187,7 @@ export class RpgClientEngine {
|
|
|
180
187
|
}
|
|
181
188
|
}
|
|
182
189
|
|
|
183
|
-
this.controls =
|
|
190
|
+
this.controls = this.context.inject(KeyboardControls)
|
|
184
191
|
}
|
|
185
192
|
|
|
186
193
|
private addResource(resourceClass, cb) {
|
|
@@ -333,7 +340,7 @@ export class RpgClientEngine {
|
|
|
333
340
|
}
|
|
334
341
|
// @ts-ignore
|
|
335
342
|
const envUrl = this.envs.VITE_SERVER_URL
|
|
336
|
-
this.connection(
|
|
343
|
+
await this.connection(
|
|
337
344
|
serverUri.url ? serverUri.url + ':' + serverUri.port :
|
|
338
345
|
envUrl ? envUrl : undefined
|
|
339
346
|
)
|
|
@@ -420,7 +427,7 @@ export class RpgClientEngine {
|
|
|
420
427
|
* @returns {void}
|
|
421
428
|
* @memberof RpgClientEngine
|
|
422
429
|
*/
|
|
423
|
-
connection(uri?: string) {
|
|
430
|
+
async connection(uri?: string) {
|
|
424
431
|
const { standalone } = this.gameEngine
|
|
425
432
|
|
|
426
433
|
this._serverUrl = uri || ''
|
|
@@ -451,12 +458,16 @@ export class RpgClientEngine {
|
|
|
451
458
|
RpgPlugin.emit(HookClient.ConnectedError, [this, err, this.socket], true)
|
|
452
459
|
})
|
|
453
460
|
|
|
454
|
-
this.socket.on('preLoadScene', (
|
|
455
|
-
if (this.lastScene ==
|
|
461
|
+
this.socket.on('preLoadScene', ({ id, reconnect }: { id: string, reconnect?: boolean }) => {
|
|
462
|
+
if (this.lastScene == id) {
|
|
456
463
|
return
|
|
457
464
|
}
|
|
458
|
-
this.lastScene =
|
|
459
|
-
this.renderer.transitionScene(
|
|
465
|
+
this.lastScene = id
|
|
466
|
+
this.renderer.transitionScene(id)
|
|
467
|
+
if (reconnect) {
|
|
468
|
+
this.roomJoin.next('')
|
|
469
|
+
this.roomJoin.complete()
|
|
470
|
+
}
|
|
460
471
|
})
|
|
461
472
|
|
|
462
473
|
this.socket.on(SocketEvents.GameReload, () => {
|
|
@@ -467,7 +478,7 @@ export class RpgClientEngine {
|
|
|
467
478
|
this.renderer.loadScene(name, data)
|
|
468
479
|
})
|
|
469
480
|
|
|
470
|
-
this.socket.on(SocketEvents.ChangeServer, ({ url, port }) => {
|
|
481
|
+
this.socket.on(SocketEvents.ChangeServer, async({ url, port }) => {
|
|
471
482
|
const connection = url + ':' + port
|
|
472
483
|
if (this.lastConnection == connection) {
|
|
473
484
|
return
|
|
@@ -617,7 +628,7 @@ export class RpgClientEngine {
|
|
|
617
628
|
paramsChanged,
|
|
618
629
|
isShape
|
|
619
630
|
})
|
|
620
|
-
|
|
631
|
+
|
|
621
632
|
// perform actions on the sprite after creation/update
|
|
622
633
|
callAction(key, paramsChanged)
|
|
623
634
|
}
|
|
@@ -651,7 +662,7 @@ export class RpgClientEngine {
|
|
|
651
662
|
RpgGui._setSocket(this.socket)
|
|
652
663
|
|
|
653
664
|
if (standalone) {
|
|
654
|
-
this.socket.connection({
|
|
665
|
+
await this.socket.connection({
|
|
655
666
|
auth: {
|
|
656
667
|
token: this.session
|
|
657
668
|
}
|
package/src/Scene/Map.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { RpgCommonMap, RpgPlugin, HookClient, RpgShape, Utils, RpgCommonPlayer } from '@rpgjs/common'
|
|
1
|
+
import { RpgCommonMap, RpgPlugin, HookClient, RpgShape, Utils, RpgCommonPlayer, InjectContext } from '@rpgjs/common'
|
|
2
2
|
import TileMap from '../Tilemap'
|
|
3
3
|
import * as _PixiViewport from 'pixi-viewport'
|
|
4
4
|
import { type Viewport } from 'pixi-viewport'
|
|
5
5
|
import { Scene, SceneObservableData, SceneSpriteLogic } from './Scene'
|
|
6
6
|
import { spritesheets } from '../Sprite/Spritesheets'
|
|
7
7
|
import { RpgSound } from '../Sound/RpgSound'
|
|
8
|
-
import { GameEngineClient } from '../GameEngine'
|
|
9
8
|
import { TiledLayerType, TiledMap } from '@rpgjs/tiled'
|
|
10
9
|
import { RpgComponent } from '../Components/Component'
|
|
11
|
-
import { CameraOptions } from '@rpgjs/types'
|
|
10
|
+
import { type CameraOptions } from '@rpgjs/types'
|
|
12
11
|
import { Assets, Container, Point, IRenderer, DisplayObjectEvents, utils, FederatedPointerEvent } from 'pixi.js'
|
|
13
12
|
import { EventLayer } from './EventLayer'
|
|
14
13
|
|
|
@@ -53,10 +52,11 @@ export class SceneMap extends Scene {
|
|
|
53
52
|
shapes = {}
|
|
54
53
|
|
|
55
54
|
constructor(
|
|
56
|
-
|
|
55
|
+
protected context: InjectContext,
|
|
57
56
|
private renderer: IRenderer,
|
|
58
|
-
private options: { screenWidth?: number, screenHeight?: number, drawMap?: boolean } = {}
|
|
59
|
-
|
|
57
|
+
private options: { screenWidth?: number, screenHeight?: number, drawMap?: boolean } = {}
|
|
58
|
+
) {
|
|
59
|
+
super(context)
|
|
60
60
|
if (options.drawMap === undefined) this.options.drawMap = true
|
|
61
61
|
this.onInit()
|
|
62
62
|
}
|
|
@@ -97,7 +97,7 @@ export class SceneMap extends Scene {
|
|
|
97
97
|
|
|
98
98
|
RpgCommonMap.bufferClient.set(obj.id, this.gameMap)
|
|
99
99
|
|
|
100
|
-
this.tilemap = new TileMap(this.
|
|
100
|
+
this.tilemap = new TileMap(this.context, this.gameMap.getData())
|
|
101
101
|
|
|
102
102
|
// TODO: Remove this
|
|
103
103
|
Assets.reset()
|
|
@@ -370,6 +370,7 @@ export class SceneMap extends Scene {
|
|
|
370
370
|
this.viewport.on(eventName, (...args) => {
|
|
371
371
|
const ev: FederatedPointerEvent = args[0] as any
|
|
372
372
|
const pos = ev.getLocalPosition(this.viewport as Viewport)
|
|
373
|
+
if (ev.defaultPrevented) return
|
|
373
374
|
cb(pos, ev)
|
|
374
375
|
})
|
|
375
376
|
}
|
package/src/Scene/Scene.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RpgPlugin, HookClient, DefaultInput } from '@rpgjs/common'
|
|
1
|
+
import { RpgPlugin, HookClient, DefaultInput, InjectContext } from '@rpgjs/common'
|
|
2
2
|
import { KeyboardControls } from '../KeyboardControls'
|
|
3
3
|
import RpgSprite from '../Sprite/Character'
|
|
4
4
|
import { Animation } from '../Effects/Animation'
|
|
@@ -29,7 +29,7 @@ export abstract class Scene {
|
|
|
29
29
|
protected objects: Map<string, RpgComponent> = new Map()
|
|
30
30
|
protected animationLayer: Container = new Container()
|
|
31
31
|
|
|
32
|
-
private controls: KeyboardControls
|
|
32
|
+
private controls: KeyboardControls = this.context.inject(KeyboardControls)
|
|
33
33
|
private animations: Animation[] = []
|
|
34
34
|
|
|
35
35
|
private _data: BehaviorSubject<SceneObservableData> = new BehaviorSubject({
|
|
@@ -37,6 +37,11 @@ export abstract class Scene {
|
|
|
37
37
|
partial: {}
|
|
38
38
|
})
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* @deprecated Use `inject(GameEngineClient)` instead. Will be removed in v5
|
|
42
|
+
*/
|
|
43
|
+
public game: GameEngineClient = this.context.inject(GameEngineClient)
|
|
44
|
+
|
|
40
45
|
/**
|
|
41
46
|
* Listen to the movement of objects on stage
|
|
42
47
|
*
|
|
@@ -63,9 +68,8 @@ export abstract class Scene {
|
|
|
63
68
|
[key: string]: any
|
|
64
69
|
}> = new Subject()
|
|
65
70
|
|
|
66
|
-
constructor(
|
|
71
|
+
constructor(protected context: InjectContext) {
|
|
67
72
|
const { globalConfig } = this.game.clientEngine
|
|
68
|
-
this.controls = this.game.clientEngine.controls
|
|
69
73
|
const mergeInputs = {
|
|
70
74
|
...DefaultInput,
|
|
71
75
|
...(globalConfig.inputs || {})
|
package/src/Tilemap/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Utils } from '@rpgjs/common'
|
|
1
|
+
import { InjectContext, Utils } from '@rpgjs/common'
|
|
2
2
|
import ImageLayer from './ImageLayer'
|
|
3
3
|
import TileLayer from './TileLayer'
|
|
4
4
|
import TileSet from './TileSet'
|
|
@@ -25,9 +25,9 @@ export default class TileMap extends Container {
|
|
|
25
25
|
} = {}
|
|
26
26
|
private tilesLayer: Container = new Container()
|
|
27
27
|
private frameTile: number = 0
|
|
28
|
+
private renderer: RpgRenderer = this.context.inject(RpgRenderer)
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
constructor(private data: MapInfo, private renderer: RpgRenderer) {
|
|
30
|
+
constructor(private context: InjectContext, private data: MapInfo) {
|
|
31
31
|
super()
|
|
32
32
|
this.x = 0
|
|
33
33
|
this.y = 0
|
|
@@ -108,7 +108,9 @@ export default class TileMap extends Container {
|
|
|
108
108
|
// if (yObject - tile.y >= height) {
|
|
109
109
|
// return false
|
|
110
110
|
// }
|
|
111
|
-
|
|
111
|
+
// Always get tile.height for height. TODO: Fix this the height of the character. To be seen according to future implementations...
|
|
112
|
+
// Discussion: https://community.rpgjs.dev/d/250-rpgjs-v420/6
|
|
113
|
+
const zIntersection = intersection([zObject, zObject + tile.height /** Old code: height */], [realZ, realZ + tile.height])
|
|
112
114
|
if (!zIntersection) {
|
|
113
115
|
return true
|
|
114
116
|
}
|
package/src/clientEntryPoint.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { HookClient, loadModules, ModuleType } from '@rpgjs/common'
|
|
1
|
+
import { InjectContext, HookClient, loadModules, ModuleType } from '@rpgjs/common'
|
|
2
2
|
import { GameEngineClient } from './GameEngine'
|
|
3
3
|
import { RpgClientEngine } from './RpgClientEngine'
|
|
4
|
+
import { setInject } from './inject'
|
|
4
5
|
|
|
5
6
|
interface RpgClientEntryPointOptions {
|
|
6
7
|
/**
|
|
@@ -142,7 +143,8 @@ export default (modules: ModuleType[], options: RpgClientEntryPointOptions): Rpg
|
|
|
142
143
|
}
|
|
143
144
|
})
|
|
144
145
|
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
const context = new InjectContext()
|
|
147
|
+
setInject(context)
|
|
148
|
+
|
|
149
|
+
return context.inject(RpgClientEngine, [options])
|
|
148
150
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { Direction, Control, Input, PrebuiltGui, HookServer, HookClient, RpgPlugin, RpgModule, RpgCommonPlayer as RpgSpriteLogic } from '@rpgjs/common'
|
|
2
2
|
export { default as entryPoint } from './clientEntryPoint'
|
|
3
3
|
export type { RpgClient, RpgSceneHooks, RpgSceneMapHooks, RpgSpriteHooks, RpgClientEngineHooks } from './RpgClient'
|
|
4
|
+
export { RpgRenderer } from './Renderer'
|
|
4
5
|
export { Scene as RpgScene } from './Scene/Scene'
|
|
5
6
|
export { RpgClientEngine } from './RpgClientEngine'
|
|
6
7
|
export { Spritesheet } from './Sprite/Spritesheet'
|
|
@@ -16,6 +17,7 @@ export { SceneMap as RpgSceneMap } from './Scene/Map'
|
|
|
16
17
|
export { RpgGui } from './Gui/Gui';
|
|
17
18
|
export { Timeline, Ease } from './Effects/Timeline';
|
|
18
19
|
export { RpgComponent, RpgComponent as RpgSprite } from './Components/Component'
|
|
20
|
+
export { KeyboardControls } from './KeyboardControls'
|
|
19
21
|
export { World, room } from 'simple-room-client'
|
|
20
22
|
|
|
21
23
|
import { spritesheets } from './Sprite/Spritesheets'
|
|
@@ -23,4 +25,5 @@ import { sounds } from './Sound/Sounds'
|
|
|
23
25
|
export const RpgResource = {
|
|
24
26
|
spritesheets,
|
|
25
27
|
sounds
|
|
26
|
-
}
|
|
28
|
+
}
|
|
29
|
+
export { inject } from './inject'
|
package/src/inject.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { InjectContext } from "@rpgjs/common";
|
|
2
|
+
|
|
3
|
+
let instanceContext: InjectContext | null = null
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Dependency injection function for RPGJS client side.
|
|
7
|
+
*
|
|
8
|
+
* This client-side `inject` function is used to retrieve instances of various classes within the RPGJS framework,
|
|
9
|
+
* specifically for client-side modules. It enables developers to access singleton instances of key classes such as
|
|
10
|
+
* `RpgClientEngine`, `KeyboardControls`, and `RpgRenderer`. Utilizing `inject` on the client side promotes modular
|
|
11
|
+
* and maintainable code by simplifying dependency management.
|
|
12
|
+
*
|
|
13
|
+
* @template T The class type that you want to retrieve an instance of, relevant to client-side modules.
|
|
14
|
+
* @returns {T} Returns the singleton instance of the specified class, ensuring only one instance is used client-side.
|
|
15
|
+
* @since 4.2.0
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* // Example of injecting the RpgClientEngine
|
|
20
|
+
* import { inject, RpgClientEngine } from '@rpgjs/client'
|
|
21
|
+
* const client = inject(RpgClientEngine)
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function inject<T>(service: new (...args: any[]) => T, args: any[] = []): T {
|
|
25
|
+
return instanceContext!.inject(service, args);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function setInject(context: InjectContext) {
|
|
29
|
+
instanceContext = context;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function clearInject() {
|
|
33
|
+
instanceContext = null
|
|
34
|
+
}
|