@rpgjs/client 3.3.2 → 4.0.0-beta.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.
- package/LICENSE +19 -0
- package/lib/Components/AbstractComponent.d.ts +3 -2
- package/lib/Components/AbstractComponent.js +17 -28
- package/lib/Components/AbstractComponent.js.map +1 -1
- package/lib/Components/BarComponent.d.ts +2 -1
- package/lib/Components/BarComponent.js +32 -33
- package/lib/Components/BarComponent.js.map +1 -1
- package/lib/Components/Component.d.ts +3 -3
- package/lib/Components/Component.js +84 -96
- package/lib/Components/Component.js.map +1 -1
- package/lib/Components/DebugComponent.d.ts +2 -1
- package/lib/Components/DebugComponent.js +9 -10
- package/lib/Components/DebugComponent.js.map +1 -1
- package/lib/Components/ImageComponent.d.ts +2 -1
- package/lib/Components/ImageComponent.js +5 -7
- package/lib/Components/ImageComponent.js.map +1 -1
- package/lib/Components/ShapeComponent.d.ts +2 -1
- package/lib/Components/ShapeComponent.js +14 -14
- package/lib/Components/ShapeComponent.js.map +1 -1
- package/lib/Components/TextComponent.d.ts +3 -2
- package/lib/Components/TextComponent.js +10 -9
- package/lib/Components/TextComponent.js.map +1 -1
- package/lib/Components/TileComponent.d.ts +2 -1
- package/lib/Components/TileComponent.js +12 -16
- package/lib/Components/TileComponent.js.map +1 -1
- package/lib/Effects/Animation.d.ts +10 -9
- package/lib/Effects/Animation.js +36 -36
- package/lib/Effects/Animation.js.map +1 -1
- package/lib/Effects/AnimationCharacter.js +2 -5
- package/lib/Effects/AnimationCharacter.js.map +1 -1
- package/lib/Effects/Spinner.d.ts +3 -2
- package/lib/Effects/Spinner.js +2 -5
- package/lib/Effects/Spinner.js.map +1 -1
- package/lib/Effects/Timeline.d.ts +1 -1
- package/lib/Effects/Timeline.js +6 -10
- package/lib/Effects/Timeline.js.map +1 -1
- package/lib/Effects/TransitionScene.d.ts +2 -1
- package/lib/Effects/TransitionScene.js +3 -7
- package/lib/Effects/TransitionScene.js.map +1 -1
- package/lib/GameEngine.js +51 -26
- package/lib/GameEngine.js.map +1 -1
- package/lib/Interfaces/Character.js +1 -2
- package/lib/Interfaces/Scene.js +1 -2
- package/lib/KeyboardControls.d.ts +2 -1
- package/lib/KeyboardControls.js +47 -45
- package/lib/KeyboardControls.js.map +1 -1
- package/lib/Logger.js +1 -5
- package/lib/Logger.js.map +1 -1
- package/lib/Presets/AnimationSpritesheet.js +9 -13
- package/lib/Presets/AnimationSpritesheet.js.map +1 -1
- package/lib/Presets/Scene.js +2 -5
- package/lib/Presets/Scene.js.map +1 -1
- package/lib/Renderer.d.ts +5 -3
- package/lib/Renderer.js +68 -60
- package/lib/Renderer.js.map +1 -1
- package/lib/Resources.js +1 -5
- package/lib/Resources.js.map +1 -1
- package/lib/RpgClient.d.ts +3 -2
- package/lib/RpgClient.js +1 -2
- package/lib/RpgClientEngine.d.ts +2 -1
- package/lib/RpgClientEngine.js +192 -176
- package/lib/RpgClientEngine.js.map +1 -1
- package/lib/RpgGui.js +40 -41
- package/lib/RpgGui.js.map +1 -1
- package/lib/Scene/EventLayer.d.ts +4 -0
- package/lib/Scene/EventLayer.js +8 -0
- package/lib/Scene/EventLayer.js.map +1 -0
- package/lib/Scene/Map.d.ts +17 -3
- package/lib/Scene/Map.js +157 -113
- package/lib/Scene/Map.js.map +1 -1
- package/lib/Scene/Scene.d.ts +3 -3
- package/lib/Scene/Scene.js +24 -20
- package/lib/Scene/Scene.js.map +1 -1
- package/lib/Scene/SceneData.js +1 -5
- package/lib/Scene/SceneData.js.map +1 -1
- package/lib/Sound/RpgSound.js +8 -11
- package/lib/Sound/RpgSound.js.map +1 -1
- package/lib/Sound/Sound.d.ts +2 -2
- package/lib/Sound/Sound.js +1 -5
- package/lib/Sound/Sound.js.map +1 -1
- package/lib/Sound/Sounds.js +4 -8
- package/lib/Sound/Sounds.js.map +1 -1
- package/lib/Sprite/Character.d.ts +3 -2
- package/lib/Sprite/Character.js +15 -16
- package/lib/Sprite/Character.js.map +1 -1
- package/lib/Sprite/Player.js +2 -9
- package/lib/Sprite/Player.js.map +1 -1
- package/lib/Sprite/Spritesheet.d.ts +4 -4
- package/lib/Sprite/Spritesheet.js +1 -5
- package/lib/Sprite/Spritesheet.js.map +1 -1
- package/lib/Sprite/Spritesheets.js +4 -8
- package/lib/Sprite/Spritesheets.js.map +1 -1
- package/lib/Tilemap/CommonLayer.d.ts +2 -1
- package/lib/Tilemap/CommonLayer.js +7 -11
- package/lib/Tilemap/CommonLayer.js.map +1 -1
- package/lib/Tilemap/ImageLayer.js +5 -7
- package/lib/Tilemap/ImageLayer.js.map +1 -1
- package/lib/Tilemap/Tile.d.ts +5 -5
- package/lib/Tilemap/Tile.js +19 -21
- package/lib/Tilemap/Tile.js.map +1 -1
- package/lib/Tilemap/TileLayer.d.ts +0 -7
- package/lib/Tilemap/TileLayer.js +27 -29
- package/lib/Tilemap/TileLayer.js.map +1 -1
- package/lib/Tilemap/TileSet.d.ts +2 -1
- package/lib/Tilemap/TileSet.js +9 -12
- package/lib/Tilemap/TileSet.js.map +1 -1
- package/lib/Tilemap/index.d.ts +3 -11
- package/lib/Tilemap/index.js +22 -61
- package/lib/Tilemap/index.js.map +1 -1
- package/lib/clientEntryPoint.js +26 -28
- package/lib/clientEntryPoint.js.map +1 -1
- package/lib/index.js +21 -75
- package/lib/index.js.map +1 -1
- package/package.json +19 -19
- package/src/Components/AbstractComponent.ts +120 -0
- package/src/Components/BarComponent.ts +179 -0
- package/src/Components/Component.ts +506 -0
- package/src/Components/DebugComponent.ts +36 -0
- package/src/Components/ImageComponent.ts +30 -0
- package/src/Components/ShapeComponent.ts +64 -0
- package/src/Components/TextComponent.ts +33 -0
- package/src/Components/TileComponent.ts +43 -0
- package/src/Effects/Animation.ts +297 -0
- package/src/Effects/AnimationCharacter.ts +7 -0
- package/src/Effects/Spinner.ts +19 -0
- package/src/Effects/Timeline.ts +294 -0
- package/src/Effects/TransitionScene.ts +57 -0
- package/src/GameEngine.ts +284 -0
- package/src/Interfaces/Character.ts +7 -0
- package/src/Interfaces/Scene.ts +9 -0
- package/src/KeyboardControls.ts +552 -0
- package/src/Logger.ts +3 -0
- package/src/Presets/AnimationSpritesheet.ts +36 -0
- package/src/Presets/Scene.ts +3 -0
- package/src/Renderer.ts +263 -0
- package/src/Resources.ts +40 -0
- package/src/RpgClient.ts +333 -0
- package/src/RpgClientEngine.ts +709 -0
- package/src/RpgGui.ts +553 -0
- package/src/RpgGuiCompiled.ts +43 -0
- package/src/Scene/EventLayer.ts +9 -0
- package/src/Scene/Map.ts +393 -0
- package/src/Scene/Scene.ts +270 -0
- package/src/Scene/SceneData.ts +13 -0
- package/src/Sound/RpgSound.ts +50 -0
- package/src/Sound/Sound.ts +91 -0
- package/src/Sound/Sounds.ts +7 -0
- package/src/Sprite/Character.ts +149 -0
- package/src/Sprite/Player.ts +3 -0
- package/src/Sprite/Spritesheet.ts +392 -0
- package/src/Sprite/Spritesheets.ts +8 -0
- package/src/Tilemap/CommonLayer.ts +20 -0
- package/src/Tilemap/ImageLayer.ts +20 -0
- package/src/Tilemap/Tile.ts +80 -0
- package/src/Tilemap/TileLayer.ts +142 -0
- package/src/Tilemap/TileSet.ts +40 -0
- package/src/Tilemap/index.ts +173 -0
- package/src/clientEntryPoint.ts +141 -0
- package/src/index.ts +25 -0
- package/src/types/howler.d.ts +73 -0
- package/tsconfig.json +30 -0
- package/lib/Components/ColorComponent.d.ts +0 -9
- package/lib/Components/ColorComponent.js +0 -18
- package/lib/Components/ColorComponent.js.map +0 -1
package/src/Renderer.ts
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { RpgPlugin, HookClient } from '@rpgjs/common'
|
|
2
|
+
import { SceneMap } from './Scene/Map'
|
|
3
|
+
import { Scene } from './Scene/Scene'
|
|
4
|
+
import { Scene as PresetScene } from './Presets/Scene'
|
|
5
|
+
import { RpgGui } from './RpgGui'
|
|
6
|
+
import { RpgClientEngine } from './RpgClientEngine'
|
|
7
|
+
import type { App, ComponentPublicInstance } from 'vue'
|
|
8
|
+
import { TransitionScene } from './Effects/TransitionScene'
|
|
9
|
+
import { Subject, forkJoin } from 'rxjs'
|
|
10
|
+
import { GameEngineClient } from './GameEngine'
|
|
11
|
+
import { SpinnerGraphic } from './Effects/Spinner'
|
|
12
|
+
import { autoDetectRenderer, Container, Graphics, ICanvas, IRenderer } from 'pixi.js'
|
|
13
|
+
|
|
14
|
+
export enum TransitionMode {
|
|
15
|
+
None,
|
|
16
|
+
Fading
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
enum ContainerName {
|
|
20
|
+
Map = 'map'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class RpgRenderer {
|
|
24
|
+
public vm: ComponentPublicInstance
|
|
25
|
+
public app: App
|
|
26
|
+
public readonly stage: Container = new Container()
|
|
27
|
+
private readonly sceneContainer: Container = new Container()
|
|
28
|
+
private readonly fadeContainer: Graphics = new Graphics()
|
|
29
|
+
private readonly spinner: SpinnerGraphic = new SpinnerGraphic(this.clientEngine)
|
|
30
|
+
public options: any = {}
|
|
31
|
+
public guiEl: HTMLDivElement
|
|
32
|
+
|
|
33
|
+
private scene: Scene | null = null
|
|
34
|
+
private renderer: IRenderer
|
|
35
|
+
private _width: number = 800
|
|
36
|
+
private _height: number = 400
|
|
37
|
+
private canvasEl: HTMLElement
|
|
38
|
+
private selector: HTMLElement
|
|
39
|
+
private gameEngine: GameEngineClient = this.clientEngine.gameEngine
|
|
40
|
+
private loadingScene = {
|
|
41
|
+
transitionIn: new Subject(),
|
|
42
|
+
transitionOut: new Subject()
|
|
43
|
+
}
|
|
44
|
+
private freeze: boolean = false
|
|
45
|
+
private prevObjectScene: any = {}
|
|
46
|
+
public transitionMode: TransitionMode = TransitionMode.Fading
|
|
47
|
+
|
|
48
|
+
constructor(private clientEngine: RpgClientEngine) {
|
|
49
|
+
this.clientEngine.tick.subscribe(({ timestamp, deltaRatio, frame, deltaTime }) => {
|
|
50
|
+
this.draw(timestamp, deltaTime, deltaRatio, frame)
|
|
51
|
+
})
|
|
52
|
+
this.transitionCompleted()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** @internal */
|
|
56
|
+
async init() {
|
|
57
|
+
this.onDOMLoaded()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** @internal */
|
|
61
|
+
_resize(w: number, h: number) {
|
|
62
|
+
if (!w) w = this.options.canvas.width
|
|
63
|
+
if (!h) h = this.options.canvas.height
|
|
64
|
+
const scene = this.getScene<SceneMap>()
|
|
65
|
+
if (this.scene && scene?.viewport) {
|
|
66
|
+
scene.viewport.screenWidth = w
|
|
67
|
+
scene.viewport.screenHeight = h
|
|
68
|
+
}
|
|
69
|
+
if (this.vm) {
|
|
70
|
+
this.vm.$el.style = `width:${w}px;height:${h}px`
|
|
71
|
+
}
|
|
72
|
+
this.renderer.resize(w, h)
|
|
73
|
+
this._width = w
|
|
74
|
+
this._height = h
|
|
75
|
+
this.fadeContainer.beginFill(0x00000)
|
|
76
|
+
this.fadeContainer.drawRect(0, 0, w, h)
|
|
77
|
+
this.fadeContainer.endFill()
|
|
78
|
+
this.spinner.x = w * 0.5
|
|
79
|
+
this.spinner.y = h * 0.5
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
get canvas(): ICanvas {
|
|
83
|
+
return this.renderer.view
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
get height(): number {
|
|
87
|
+
return this._height
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
set height(val: number) {
|
|
91
|
+
this._resize(this._width, val)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
get width(): number {
|
|
95
|
+
return this._width
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
set width(val: number) {
|
|
99
|
+
this._resize(val, this.height)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** @internal */
|
|
103
|
+
onDOMLoaded() {
|
|
104
|
+
let options = {
|
|
105
|
+
antialias: true,
|
|
106
|
+
...this.options.canvas
|
|
107
|
+
};
|
|
108
|
+
this.renderer = autoDetectRenderer(options)
|
|
109
|
+
this.selector = document.body.querySelector(this.options.selector)
|
|
110
|
+
this.guiEl = this.selector.querySelector(this.options.selectorGui)
|
|
111
|
+
this.canvasEl = this.selector.querySelector(this.options.selectorCanvas)
|
|
112
|
+
|
|
113
|
+
if (!this.guiEl) {
|
|
114
|
+
this.guiEl = document.createElement('div')
|
|
115
|
+
this.selector.appendChild(this.guiEl)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (!this.canvasEl) {
|
|
119
|
+
this.selector.insertBefore(this.renderer.view as HTMLCanvasElement, this.selector.firstChild)
|
|
120
|
+
const [canvas] = document.querySelector(this.options.selector).children
|
|
121
|
+
canvas.style.position = 'absolute'
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
this.canvasEl.appendChild(this.renderer.view as HTMLCanvasElement)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
this.stage.addChild(this.sceneContainer)
|
|
128
|
+
this.stage.addChild(this.fadeContainer)
|
|
129
|
+
this.fadeContainer.addChild(this.spinner)
|
|
130
|
+
|
|
131
|
+
this.fadeContainer.visible = false
|
|
132
|
+
this.fadeContainer.alpha = 0
|
|
133
|
+
|
|
134
|
+
RpgGui._initalize(this.clientEngine)
|
|
135
|
+
|
|
136
|
+
this.resize()
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** @internal */
|
|
140
|
+
resize() {
|
|
141
|
+
const size = () => {
|
|
142
|
+
const { offsetWidth, offsetHeight } = this.canvasEl || this.selector
|
|
143
|
+
this._resize(offsetWidth, offsetHeight)
|
|
144
|
+
RpgPlugin.emit(HookClient.WindowResize)
|
|
145
|
+
}
|
|
146
|
+
window.addEventListener('resize', size)
|
|
147
|
+
size()
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** @internal */
|
|
151
|
+
getScene<T = Scene>(): T | null {
|
|
152
|
+
return this.scene as any
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** @internal */
|
|
156
|
+
draw(t: number, deltaTime: number, deltaRatio: number, frame: number) {
|
|
157
|
+
if (!this.renderer) return
|
|
158
|
+
if (this.scene && !this.freeze) this.scene.draw(t, deltaTime, deltaRatio, frame)
|
|
159
|
+
this.renderer.render(this.stage)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** @internal */
|
|
163
|
+
async loadScene(name: string, obj) {
|
|
164
|
+
const scene = this.getScene<SceneMap | null>()
|
|
165
|
+
if (scene && scene.data.id == obj.id) {
|
|
166
|
+
const container = await scene.load(obj, this.prevObjectScene, true)
|
|
167
|
+
this.sceneContainer.removeChildren()
|
|
168
|
+
this.sceneContainer.addChild(container)
|
|
169
|
+
scene.updateTilesOverlayAllSprites()
|
|
170
|
+
this.scene?.update()
|
|
171
|
+
return
|
|
172
|
+
}
|
|
173
|
+
this.loadingScene.transitionIn.next({ name, obj })
|
|
174
|
+
this.loadingScene.transitionIn.complete()
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private async createScene(name: string, obj) {
|
|
178
|
+
const container = await this.getScene<SceneMap>()?.load(obj, this.prevObjectScene)
|
|
179
|
+
this.prevObjectScene = { ...obj }
|
|
180
|
+
this.sceneContainer.children.forEach(child => {
|
|
181
|
+
if (child.name === ContainerName.Map) this.sceneContainer.removeChild(child)
|
|
182
|
+
})
|
|
183
|
+
if (container) {
|
|
184
|
+
container.name = ContainerName.Map
|
|
185
|
+
this.sceneContainer.addChild(container)
|
|
186
|
+
}
|
|
187
|
+
this.scene?.update()
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** @internal */
|
|
191
|
+
transitionScene(name: string) {
|
|
192
|
+
this.freeze = true
|
|
193
|
+
this.fadeContainer.visible = true
|
|
194
|
+
RpgPlugin.emit(HookClient.BeforeSceneLoading, {
|
|
195
|
+
name
|
|
196
|
+
})
|
|
197
|
+
this.clientEngine.controls.stopInputs()
|
|
198
|
+
const finish = () => {
|
|
199
|
+
this.clearScene()
|
|
200
|
+
this.loadingScene.transitionOut.next(name)
|
|
201
|
+
this.loadingScene.transitionOut.complete()
|
|
202
|
+
}
|
|
203
|
+
if (this.transitionMode == TransitionMode.Fading) {
|
|
204
|
+
new TransitionScene(this.clientEngine, this.fadeContainer)
|
|
205
|
+
.addFadeOut()
|
|
206
|
+
.onComplete(finish)
|
|
207
|
+
.start()
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
finish()
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/** @internal */
|
|
215
|
+
transitionCompleted() {
|
|
216
|
+
this.loadingScene = {
|
|
217
|
+
transitionIn: new Subject(),
|
|
218
|
+
transitionOut: new Subject()
|
|
219
|
+
}
|
|
220
|
+
this.clientEngine.roomJoin = new Subject()
|
|
221
|
+
forkJoin({
|
|
222
|
+
in: this.loadingScene.transitionIn,
|
|
223
|
+
out: this.loadingScene.transitionOut,
|
|
224
|
+
room: this.clientEngine.roomJoin
|
|
225
|
+
}).subscribe(async (data: { in: any }) => {
|
|
226
|
+
const { in: { obj, name } } = data
|
|
227
|
+
const scenes = this.options.scenes || {}
|
|
228
|
+
switch (name) {
|
|
229
|
+
case PresetScene.Map:
|
|
230
|
+
const sceneClass = scenes[PresetScene.Map] || SceneMap
|
|
231
|
+
this.scene = new sceneClass(this.gameEngine, this.renderer, {
|
|
232
|
+
screenWidth: this.renderer.screen.width,
|
|
233
|
+
screenHeight: this.renderer.screen.height,
|
|
234
|
+
drawMap: this.options.drawMap
|
|
235
|
+
})
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
await this.createScene(name, obj)
|
|
239
|
+
this.freeze = false
|
|
240
|
+
const finish = () => {
|
|
241
|
+
this.clientEngine.controls.listenInputs()
|
|
242
|
+
this.fadeContainer.visible = false
|
|
243
|
+
this.transitionCompleted()
|
|
244
|
+
RpgPlugin.emit(HookClient.AfterSceneLoading, this.scene)
|
|
245
|
+
}
|
|
246
|
+
if (this.transitionMode == TransitionMode.Fading) {
|
|
247
|
+
new TransitionScene(this.clientEngine, this.fadeContainer)
|
|
248
|
+
.addFadeIn()
|
|
249
|
+
.onComplete(finish)
|
|
250
|
+
.start()
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
finish()
|
|
254
|
+
}
|
|
255
|
+
})
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/** @internal */
|
|
259
|
+
clearScene() {
|
|
260
|
+
this.scene = null
|
|
261
|
+
this.sceneContainer.removeChildren()
|
|
262
|
+
}
|
|
263
|
+
}
|
package/src/Resources.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { RpgClientEngine } from "./RpgClientEngine"
|
|
2
|
+
import { Utils } from '@rpgjs/common'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get/Set images in resources
|
|
6
|
+
```ts
|
|
7
|
+
import { RpgResource } from '@rpg/client'
|
|
8
|
+
const fileLink = RpgResource.spritesheets.get('resource_id')
|
|
9
|
+
```
|
|
10
|
+
* @title Get/Set image link
|
|
11
|
+
* @prop { Map< string, string > } spritesheets
|
|
12
|
+
* @memberof Resources
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Get/Set sounds in resources
|
|
16
|
+
```ts
|
|
17
|
+
import { RpgResource } from '@rpg/client'
|
|
18
|
+
const fileLink = RpgResource.sounds.get('resource_id')
|
|
19
|
+
```
|
|
20
|
+
* @title Get/Set sound link
|
|
21
|
+
* @prop { Map< string, string > } sounds
|
|
22
|
+
* @memberof Resources
|
|
23
|
+
*/
|
|
24
|
+
export function _initResource(memory: Map<string, any>, _resources, prop: string, engine: RpgClientEngine) {
|
|
25
|
+
for (let resource of _resources) {
|
|
26
|
+
const pluralProp = prop + 's'
|
|
27
|
+
if (resource[pluralProp]) {
|
|
28
|
+
for (let key in resource[pluralProp]) {
|
|
29
|
+
const instance = new resource()
|
|
30
|
+
instance[prop] = engine.getResourceUrl(resource[pluralProp][key])
|
|
31
|
+
memory.set(key, instance)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const instance = new resource(engine)
|
|
36
|
+
instance[prop] = engine.getResourceUrl(instance[prop])
|
|
37
|
+
memory.set(resource.id, instance)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
package/src/RpgClient.ts
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import { ModuleType } from '@rpgjs/common'
|
|
2
|
+
import { SceneMap } from './Scene/Map'
|
|
3
|
+
import { RpgClientEngine } from './RpgClientEngine'
|
|
4
|
+
import { RpgComponent } from './Components/Component'
|
|
5
|
+
import { Loader } from 'pixi.js'
|
|
6
|
+
|
|
7
|
+
type RpgClass<T = any> = new (...args: any[]) => T
|
|
8
|
+
|
|
9
|
+
export interface RpgClientEngineHooks {
|
|
10
|
+
/**
|
|
11
|
+
* When the engine is started. If you send false, you prevent the client from connecting to the server
|
|
12
|
+
*
|
|
13
|
+
* @prop { (engine: RpgClientEngine) => boolean | any } [onStart]
|
|
14
|
+
* @memberof RpgEngineHooks
|
|
15
|
+
*/
|
|
16
|
+
onStart?: (engine: RpgClientEngine) => boolean | void
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Each frame
|
|
20
|
+
*
|
|
21
|
+
* @prop { (engine: RpgClientEngine, t: number) => boolean | any } [onStep]
|
|
22
|
+
* @memberof RpgEngineHooks
|
|
23
|
+
*/
|
|
24
|
+
onStep?: (engine: RpgClientEngine, t?: number, dt?: number) => any
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Recover keys from the pressed keyboard
|
|
28
|
+
*
|
|
29
|
+
* @prop { (engine: RpgClientEngine, obj: { input: string, playerId: number }) => any } [onInput]
|
|
30
|
+
* @memberof RpgEngineHooks
|
|
31
|
+
*/
|
|
32
|
+
onInput?: (engine: RpgClientEngine, obj: { input: string, playerId: number }) => any
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Called when the user is connected to the server
|
|
36
|
+
*
|
|
37
|
+
* @prop { (engine: RpgClientEngine, socket: any) => any } [onConnected]
|
|
38
|
+
* @memberof RpgEngineHooks
|
|
39
|
+
*/
|
|
40
|
+
onConnected?: (engine: RpgClientEngine, socket: any) => any
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Called when the user is disconnected to the server
|
|
44
|
+
*
|
|
45
|
+
* @prop { (engine: RpgClientEngine, reason: any, socket: any) => any } [onDisconnect]
|
|
46
|
+
* @memberof RpgEngineHooks
|
|
47
|
+
*/
|
|
48
|
+
onDisconnect?: (engine: RpgClientEngine, reason: any, socket: any) => any
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Called when there was a connection error
|
|
52
|
+
*
|
|
53
|
+
* @prop { (engine: RpgClientEngine, err: any, socket: any) => any } [onConnectError]
|
|
54
|
+
* @memberof RpgEngineHooks
|
|
55
|
+
*/
|
|
56
|
+
onConnectError?: (engine: RpgClientEngine, err: any, socket: any) => any
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Called when window is resized
|
|
60
|
+
*
|
|
61
|
+
* @prop { () => any } [onWindowResize]
|
|
62
|
+
* @since 3.0.0-beta.4
|
|
63
|
+
* @memberof RpgEngineHooks
|
|
64
|
+
*/
|
|
65
|
+
onWindowResize?: () => any
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface RpgSpriteHooks {
|
|
69
|
+
/**
|
|
70
|
+
* As soon as the sprite is initialized
|
|
71
|
+
*
|
|
72
|
+
* @prop { (sprite: RpgSprite) => any } [onInit]
|
|
73
|
+
* @memberof RpgSpriteHooks
|
|
74
|
+
*/
|
|
75
|
+
onInit?: (sprite: RpgComponent) => any
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Called when the sprite is deleted
|
|
79
|
+
*
|
|
80
|
+
* @prop { (sprite: RpgSprite) => any } [onDestroy]
|
|
81
|
+
* @memberof RpgSpriteHooks
|
|
82
|
+
*/
|
|
83
|
+
onDestroy?: (sprite: RpgComponent) => any
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* As soon as a data is changed on the server side (the name for example), you are able to know the new data but also the old data.
|
|
87
|
+
*
|
|
88
|
+
* @prop { (sprite: RpgSprite, data: any, old: any) => any } [onChanges]
|
|
89
|
+
* @memberof RpgSpriteHooks
|
|
90
|
+
*/
|
|
91
|
+
onChanges?: (sprite: RpgComponent, data: any, old: any) => any
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* At each tick, the method is called
|
|
95
|
+
*
|
|
96
|
+
* @prop { (sprite: RpgSprite, obj: any) => any } [onUpdate]
|
|
97
|
+
* @memberof RpgSpriteHooks
|
|
98
|
+
*/
|
|
99
|
+
onUpdate?: (sprite: RpgComponent, obj: any) => any
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* When the x, y positions change
|
|
103
|
+
*
|
|
104
|
+
* @prop { (sprite: RpgSprite) => any } [onMove]
|
|
105
|
+
* @since 3.0.0-beta.4
|
|
106
|
+
* @memberof RpgSpriteHooks
|
|
107
|
+
*/
|
|
108
|
+
onMove?: (sprite: RpgComponent) => any
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface RpgSceneHooks<Scene> {
|
|
112
|
+
/**
|
|
113
|
+
* a sprite has been added on the scene
|
|
114
|
+
*
|
|
115
|
+
* @prop { (scene: RpgScene, sprite: RpgComponent) => any } [onAddSprite]
|
|
116
|
+
* @memberof RpgSceneHooks
|
|
117
|
+
*/
|
|
118
|
+
onAddSprite?: (scene: Scene, sprite: RpgComponent) => any
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* a sprite has been removed on the scene
|
|
122
|
+
*
|
|
123
|
+
* @prop { (scene: RpgScene, sprite: RpgSprite) => any } [onRemoveSprite]
|
|
124
|
+
* @memberof RpgSceneHooks
|
|
125
|
+
*/
|
|
126
|
+
onRemoveSprite?: (scene: Scene, sprite: RpgComponent) => any
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Before the scene is loaded
|
|
130
|
+
*
|
|
131
|
+
* @prop { (scene: RpgScene) => any } [onBeforeLoading]
|
|
132
|
+
* @memberof RpgSceneHooks
|
|
133
|
+
*/
|
|
134
|
+
onBeforeLoading?: (scene: Scene) => any
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* When the scene is loaded (Image of the loaded tileset, drawing completed and viewport assigned)
|
|
138
|
+
*
|
|
139
|
+
* @prop { (scene: RpgScene) => any } [onAfterLoading]
|
|
140
|
+
* @memberof RpgSceneHooks
|
|
141
|
+
*/
|
|
142
|
+
onAfterLoading?: (scene: Scene) => any
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* When server data changes on the map (events, players, or other)
|
|
146
|
+
*
|
|
147
|
+
* @prop { (scene: RpgScene, obj: { data: any, partial: any }) => any } [onChanges]
|
|
148
|
+
* @memberof RpgSceneHooks
|
|
149
|
+
*/
|
|
150
|
+
onChanges?: (scene: Scene, obj: { data: any, partial: any }) => any
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* the scene is drawn
|
|
154
|
+
*
|
|
155
|
+
* @prop { (scene: RpgScene, t: number) => any } [onDraw]
|
|
156
|
+
* @memberof RpgSceneHooks
|
|
157
|
+
*/
|
|
158
|
+
onDraw?: (scene: Scene, t: number) => any
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export interface RpgSceneMapHooks extends RpgSceneHooks<SceneMap> {
|
|
162
|
+
/**
|
|
163
|
+
* The map and resources are being loaded
|
|
164
|
+
*
|
|
165
|
+
* @prop { (scene: RpgSceneMap, loader: PIXI.Loader) => any } [onMapLoading]
|
|
166
|
+
* @memberof RpgSceneHooks
|
|
167
|
+
*/
|
|
168
|
+
onMapLoading?: (scene: SceneMap, loader: Loader) => any
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export interface RpgClient {
|
|
172
|
+
/**
|
|
173
|
+
* Adding sub-modules
|
|
174
|
+
*
|
|
175
|
+
* @prop { { client: null | Function, server: null | Function }[]} [imports]
|
|
176
|
+
* @memberof RpgClient
|
|
177
|
+
*/
|
|
178
|
+
imports?: ModuleType[]
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Object containing the hooks concerning the engine
|
|
182
|
+
*
|
|
183
|
+
* ```ts
|
|
184
|
+
* import { RpgClientEngine, RpgClientEngineHooks, RpgModule, RpgClient } from '@rpgjs/client'
|
|
185
|
+
*
|
|
186
|
+
* const engine: RpgClientEngineHooks = {
|
|
187
|
+
* onConnected(engine: RpgClientEngine) {
|
|
188
|
+
* console.log('client is connected')
|
|
189
|
+
* }
|
|
190
|
+
* }
|
|
191
|
+
*
|
|
192
|
+
* @RpgModule<RpgClient>({
|
|
193
|
+
* engine
|
|
194
|
+
* })
|
|
195
|
+
* class RpgClientModule {}
|
|
196
|
+
* ```
|
|
197
|
+
*
|
|
198
|
+
* @prop {RpgClientEngineHooks} [engine]
|
|
199
|
+
* @memberof RpgClient
|
|
200
|
+
*/
|
|
201
|
+
engine?: RpgClientEngineHooks
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Array containing the list of spritesheets
|
|
205
|
+
* An element contains a class with the `@Spritesheet` decorator
|
|
206
|
+
*
|
|
207
|
+
* ```ts
|
|
208
|
+
* import { Spritesheet, Animation, Direction, RpgClient, RpgModule } from '@rpgjs/client'
|
|
209
|
+
*
|
|
210
|
+
* @Spritesheet({
|
|
211
|
+
* id: 'chest',
|
|
212
|
+
* image: require('./assets/chest.png'),
|
|
213
|
+
* // other options
|
|
214
|
+
* })
|
|
215
|
+
* class Chest { }
|
|
216
|
+
*
|
|
217
|
+
* @RpgModule<RpgClient>({
|
|
218
|
+
* spritesheets: [
|
|
219
|
+
* Chest
|
|
220
|
+
* ]
|
|
221
|
+
* })
|
|
222
|
+
* class RpgClientEngine {}
|
|
223
|
+
* ```
|
|
224
|
+
*
|
|
225
|
+
* [Guide: Create Sprite](/guide/create-sprite.html)
|
|
226
|
+
*
|
|
227
|
+
* @prop {Array<Class>} [spritesheets]
|
|
228
|
+
* @memberof RpgClient
|
|
229
|
+
* */
|
|
230
|
+
spritesheets?: RpgClass[],
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Array containing the list of VueJS components
|
|
234
|
+
*
|
|
235
|
+
* ```ts
|
|
236
|
+
* import { RpgClient, RpgModule } from '@rpgjs/client'
|
|
237
|
+
*
|
|
238
|
+
* const component = {
|
|
239
|
+
* name: 'my-gui',
|
|
240
|
+
* template: `
|
|
241
|
+
* <div>
|
|
242
|
+
* Component
|
|
243
|
+
* </div>
|
|
244
|
+
* `
|
|
245
|
+
* }
|
|
246
|
+
*
|
|
247
|
+
* @RpgModule<RpgClient>({
|
|
248
|
+
* gui: [
|
|
249
|
+
* component
|
|
250
|
+
* ]
|
|
251
|
+
* })
|
|
252
|
+
* class RpgClientEngine {}
|
|
253
|
+
* ```
|
|
254
|
+
*
|
|
255
|
+
* [Guide: Create GUI](/guide/create-gui.html)
|
|
256
|
+
*
|
|
257
|
+
* @prop {Array<Component of VueJS>} [gui]
|
|
258
|
+
* @memberof RpgClient
|
|
259
|
+
* */
|
|
260
|
+
gui?: any[],
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Array containing the list of sounds
|
|
264
|
+
* An element contains a class with the `@Sound` decorator
|
|
265
|
+
*
|
|
266
|
+
* ```ts
|
|
267
|
+
* import { Sound, RpgModule, RpgClient } from '@rpgjs/client'
|
|
268
|
+
*
|
|
269
|
+
* @Sound({
|
|
270
|
+
* sounds: {
|
|
271
|
+
* town: require('./assets/Town_Theme.ogg')
|
|
272
|
+
* }
|
|
273
|
+
* })
|
|
274
|
+
* class Sounds {}
|
|
275
|
+
*
|
|
276
|
+
* @RpgModule<RpgClient>({
|
|
277
|
+
* sounds: [ Sounds ]
|
|
278
|
+
* })
|
|
279
|
+
* class RpgClientEngine {}
|
|
280
|
+
* ```
|
|
281
|
+
*
|
|
282
|
+
* @prop {Array<Class>} [sounds]
|
|
283
|
+
* @memberof RpgClient
|
|
284
|
+
* */
|
|
285
|
+
sounds?: RpgClass[],
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Give the `RpgSprite` class. A Sprite represents a player or an event
|
|
289
|
+
*
|
|
290
|
+
* ```ts
|
|
291
|
+
* import { RpgSprite, RpgSpriteHooks, RpgClient, RpgModule } from '@rpgjs/client'
|
|
292
|
+
*
|
|
293
|
+
* export const sprite: RpgSpriteHooks = {
|
|
294
|
+
* onInit(sprite: RpgSprite) {}
|
|
295
|
+
* }
|
|
296
|
+
*
|
|
297
|
+
* @RpgModule<RpgClient>({
|
|
298
|
+
* sprite
|
|
299
|
+
* })
|
|
300
|
+
* class RpgClientEngine {}
|
|
301
|
+
* ```
|
|
302
|
+
*
|
|
303
|
+
* @prop {RpgSpriteHooks} [sprite]
|
|
304
|
+
* @memberof RpgClient
|
|
305
|
+
* */
|
|
306
|
+
sprite?: RpgSpriteHooks
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Reference the scenes of the game. Here you can put your own class that inherits RpgSceneMap
|
|
310
|
+
*
|
|
311
|
+
* ```ts
|
|
312
|
+
* import { RpgSceneMapHooks, RpgClient, RpgModule } from '@rpgjs/client'
|
|
313
|
+
*
|
|
314
|
+
* export const sceneMap: RpgSceneMapHooks = {
|
|
315
|
+
*
|
|
316
|
+
* }
|
|
317
|
+
*
|
|
318
|
+
* @RpgModule<RpgClient>({
|
|
319
|
+
* scenes: {
|
|
320
|
+
* // If you put the RpgSceneMap scene, Thhe key is called mandatory `map`
|
|
321
|
+
* map: sceneMap
|
|
322
|
+
* }
|
|
323
|
+
* })
|
|
324
|
+
* class RpgClientEngine {}
|
|
325
|
+
* ```
|
|
326
|
+
*
|
|
327
|
+
* @prop { [sceneName: string]: RpgSceneMapHooks } [scenes]
|
|
328
|
+
* @memberof RpgClient
|
|
329
|
+
* */
|
|
330
|
+
scenes?: {
|
|
331
|
+
map: RpgSceneMapHooks
|
|
332
|
+
}
|
|
333
|
+
}
|