@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
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
import { Direction, HookClient, RpgCommonPlayer, RpgPlugin, RpgShape, Utils } from "@rpgjs/common"
|
|
2
|
+
import { ComponentObject, LayoutObject, LayoutOptions, LayoutPositionEnum, PlayerType, PositionXY } from "@rpgjs/types"
|
|
3
|
+
import { Subject, Subscription, map, filter, tap, distinctUntilChanged, takeUntil, finalize } from "rxjs"
|
|
4
|
+
import { log } from "../Logger"
|
|
5
|
+
import { Scene } from "../Scene/Scene"
|
|
6
|
+
import { RpgSprite } from "../Sprite/Player"
|
|
7
|
+
import { AbstractComponent } from "./AbstractComponent"
|
|
8
|
+
import { BarComponent } from "./BarComponent"
|
|
9
|
+
import { ShapeComponent } from "./ShapeComponent"
|
|
10
|
+
import { DebugComponent } from "./DebugComponent"
|
|
11
|
+
import { ImageComponent } from "./ImageComponent"
|
|
12
|
+
import { TextComponent } from "./TextComponent"
|
|
13
|
+
import { TileComponent } from "./TileComponent"
|
|
14
|
+
import { Container, Sprite } from "pixi.js"
|
|
15
|
+
|
|
16
|
+
type SpriteInfo = {
|
|
17
|
+
width: number,
|
|
18
|
+
height: number,
|
|
19
|
+
x: number,
|
|
20
|
+
y: number,
|
|
21
|
+
anchor: { x: number, y: number },
|
|
22
|
+
spriteWidth: number
|
|
23
|
+
spriteHeight: number
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface IComponent {
|
|
27
|
+
id: string,
|
|
28
|
+
value: any
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const layoutObject = {
|
|
32
|
+
lines: []
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const layoutTypes: LayoutPositionEnum[] = ['top', 'bottom', 'left', 'right']
|
|
36
|
+
|
|
37
|
+
export class RpgComponent<T = any> extends Container {
|
|
38
|
+
/** @internal */
|
|
39
|
+
tilesOverlay: any
|
|
40
|
+
/** @internal */
|
|
41
|
+
h: number = 1
|
|
42
|
+
/** @internal */
|
|
43
|
+
w: number = 1
|
|
44
|
+
protected _x: number = 0
|
|
45
|
+
protected _y: number = 0
|
|
46
|
+
private _rotation: number = 0
|
|
47
|
+
protected teleported: number = 0
|
|
48
|
+
protected map: string = ''
|
|
49
|
+
protected z: number = 0
|
|
50
|
+
protected fixed: boolean = false
|
|
51
|
+
private components: LayoutObject<any> = {
|
|
52
|
+
top: layoutObject,
|
|
53
|
+
bottom: layoutObject,
|
|
54
|
+
left: layoutObject,
|
|
55
|
+
right: layoutObject,
|
|
56
|
+
center: layoutObject
|
|
57
|
+
}
|
|
58
|
+
private direction: number = 0
|
|
59
|
+
private container: Container = new Container()
|
|
60
|
+
|
|
61
|
+
private containersLayout: {
|
|
62
|
+
[key in LayoutPositionEnum]: Container
|
|
63
|
+
} = {} as any
|
|
64
|
+
|
|
65
|
+
private subscriptionGraphic: Subscription
|
|
66
|
+
private layoutNotifierClear: { [key in LayoutPositionEnum]: Subject<void> } = {
|
|
67
|
+
top: new Subject(),
|
|
68
|
+
bottom: new Subject(),
|
|
69
|
+
left: new Subject(),
|
|
70
|
+
right: new Subject(),
|
|
71
|
+
center: new Subject()
|
|
72
|
+
}
|
|
73
|
+
private registerComponents: Map<string, any> = new Map()
|
|
74
|
+
private dragMode?: {
|
|
75
|
+
data: any,
|
|
76
|
+
dragging: boolean
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
readonly game = this.scene.game
|
|
80
|
+
readonly id: string = this.data.id
|
|
81
|
+
|
|
82
|
+
constructor(private data: RpgCommonPlayer | RpgShape, private scene: Scene) {
|
|
83
|
+
super()
|
|
84
|
+
this.setPosition(false)
|
|
85
|
+
this.registerComponents.set(RpgSprite.id, RpgSprite)
|
|
86
|
+
this.registerComponents.set(TextComponent.id, TextComponent)
|
|
87
|
+
this.registerComponents.set(ShapeComponent.id, ShapeComponent)
|
|
88
|
+
this.registerComponents.set(TileComponent.id, TileComponent)
|
|
89
|
+
this.registerComponents.set(ImageComponent.id, ImageComponent)
|
|
90
|
+
this.registerComponents.set(BarComponent.id, BarComponent)
|
|
91
|
+
this.registerComponents.set(DebugComponent.id, DebugComponent)
|
|
92
|
+
|
|
93
|
+
this.addChild(this.container)
|
|
94
|
+
|
|
95
|
+
for (let layout of [...layoutTypes, 'center']) {
|
|
96
|
+
this.containersLayout[layout] = new Container()
|
|
97
|
+
this.container.addChild(this.containersLayout[layout])
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
RpgPlugin.emit(HookClient.AddSprite, this)
|
|
101
|
+
RpgPlugin.emit(HookClient.SceneAddSprite, [this.scene, this], true)
|
|
102
|
+
|
|
103
|
+
this.game.listenObject(data.id)
|
|
104
|
+
.pipe(
|
|
105
|
+
takeUntil(this.game.getDeleteNotifier(data.id)),
|
|
106
|
+
map(object => object?.paramsChanged),
|
|
107
|
+
tap(() => {
|
|
108
|
+
RpgPlugin.emit(HookClient.ChangesSprite, [this, this.logic?.['paramsChanged'], this.logic?.['prevParamsChanged']], true)
|
|
109
|
+
}),
|
|
110
|
+
filter(object => {
|
|
111
|
+
return this.logic?.['componentChanged']
|
|
112
|
+
})
|
|
113
|
+
)
|
|
114
|
+
.subscribe((val) => {
|
|
115
|
+
if (this.logic) {
|
|
116
|
+
this.updateComponents(this.logic?.['componentChanged'])
|
|
117
|
+
this.logic['componentChanged'] = undefined
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* the direction of the sprite
|
|
125
|
+
*
|
|
126
|
+
* @prop {Direction} dir
|
|
127
|
+
* @readonly
|
|
128
|
+
* @memberof RpgSprite
|
|
129
|
+
* */
|
|
130
|
+
get dir(): Direction {
|
|
131
|
+
return this.direction
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* To know if the sprite is a player
|
|
136
|
+
*
|
|
137
|
+
* @prop {boolean} isPlayer
|
|
138
|
+
* @readonly
|
|
139
|
+
* @memberof RpgSprite
|
|
140
|
+
* */
|
|
141
|
+
get isPlayer(): boolean {
|
|
142
|
+
return this.data.type == PlayerType.Player
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* To know if the sprite is an event
|
|
147
|
+
*
|
|
148
|
+
* @prop {boolean} isEvent
|
|
149
|
+
* @readonly
|
|
150
|
+
* @memberof RpgSprite
|
|
151
|
+
* */
|
|
152
|
+
get isEvent(): boolean {
|
|
153
|
+
return this.data.type == PlayerType.Event
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* To know if the sprite is a shape
|
|
158
|
+
*
|
|
159
|
+
* @prop {boolean} isShape
|
|
160
|
+
* @since 3.0.0-rc
|
|
161
|
+
* @readonly
|
|
162
|
+
* @memberof RpgSprite
|
|
163
|
+
* */
|
|
164
|
+
get isShape(): boolean {
|
|
165
|
+
return Utils.isInstanceOf(this.data, RpgShape)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* To know if the sprite is the sprite controlled by the player
|
|
170
|
+
*
|
|
171
|
+
* @prop {boolean} isCurrentPlayer
|
|
172
|
+
* @readonly
|
|
173
|
+
* @memberof RpgSprite
|
|
174
|
+
* */
|
|
175
|
+
get isCurrentPlayer(): boolean {
|
|
176
|
+
return this.data.id === this.scene.game.playerId
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Retrieves the logic of the sprite
|
|
181
|
+
*
|
|
182
|
+
* @prop {RpgSpriteLogic} logic
|
|
183
|
+
* @readonly
|
|
184
|
+
* @since 3.0.0-beta.4
|
|
185
|
+
* @memberof RpgSprite
|
|
186
|
+
* */
|
|
187
|
+
get logic(): RpgCommonPlayer | RpgShape | null {
|
|
188
|
+
return this.scene.game.world.getAll(this.data.id)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
get guiDisplay(): boolean {
|
|
192
|
+
return (this.logic as RpgCommonPlayer).guiDisplay
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
set guiDisplay(val: boolean) {
|
|
196
|
+
(this.logic as RpgCommonPlayer).guiDisplay = val
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
setPosition(smooth: boolean = true) {
|
|
200
|
+
if (this.isShape) {
|
|
201
|
+
const { width, height, x, y } = this.data as RpgShape
|
|
202
|
+
this.w = width
|
|
203
|
+
this.h = height
|
|
204
|
+
this._x = Math.floor(x)
|
|
205
|
+
this._y = Math.floor(y)
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
const { position, direction } = this.data as RpgCommonPlayer
|
|
209
|
+
this._x = Math.floor(position?.x ?? 0)
|
|
210
|
+
this._y = Math.floor(position?.y ?? 0)
|
|
211
|
+
this.z = Math.floor(position?.z ?? 0)
|
|
212
|
+
this.direction = direction
|
|
213
|
+
}
|
|
214
|
+
this._rotation = this.data['rotation'] ?? 0
|
|
215
|
+
if (!smooth) {
|
|
216
|
+
this.x = this._x
|
|
217
|
+
this.y = this._y
|
|
218
|
+
this.angle = this._rotation
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// TODO
|
|
223
|
+
/*drag() {
|
|
224
|
+
this.interactive = true
|
|
225
|
+
const filter = new filters.ColorMatrixFilter();
|
|
226
|
+
|
|
227
|
+
const onDragEnd = () => {
|
|
228
|
+
if (!this.dragMode) return
|
|
229
|
+
this.dragMode.dragging = false
|
|
230
|
+
this.dragMode.data = null
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
this
|
|
234
|
+
.on('pointerdown', (event) => {
|
|
235
|
+
this.dragMode = {
|
|
236
|
+
data: event.data,
|
|
237
|
+
dragging: true
|
|
238
|
+
}
|
|
239
|
+
})
|
|
240
|
+
.on('pointerup', onDragEnd)
|
|
241
|
+
.on('pointerupoutside', onDragEnd)
|
|
242
|
+
.on('pointermove', () => {
|
|
243
|
+
if (!this.dragMode) return
|
|
244
|
+
const { dragging, data } = this.dragMode
|
|
245
|
+
if (dragging) {
|
|
246
|
+
const newPosition = data.getLocalPosition(this.parent)
|
|
247
|
+
this.x = newPosition.x
|
|
248
|
+
this.y = newPosition.y
|
|
249
|
+
}
|
|
250
|
+
})
|
|
251
|
+
}*/
|
|
252
|
+
|
|
253
|
+
update(obj: any, objChanged: any, time: number, deltaRatio: number): { moving: boolean } {
|
|
254
|
+
if (this.dragMode?.dragging) return { moving: true }
|
|
255
|
+
|
|
256
|
+
const { speed, teleported, map, fixed, rotation } = obj
|
|
257
|
+
this.data = obj
|
|
258
|
+
this.setPosition()
|
|
259
|
+
const renderSpeed = speed * deltaRatio
|
|
260
|
+
if (this._rotation != this.angle) {
|
|
261
|
+
this.angle += Math.min(renderSpeed, this._rotation - this.angle)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
let moving = false
|
|
265
|
+
|
|
266
|
+
if (!fixed) {
|
|
267
|
+
if (teleported != this.teleported || map != this.map) {
|
|
268
|
+
this.x = this._x
|
|
269
|
+
this.y = this._y
|
|
270
|
+
this.teleported = teleported
|
|
271
|
+
this.map = map
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
this.parent.parent.zIndex = this._y
|
|
275
|
+
|
|
276
|
+
obj.posX = this._x
|
|
277
|
+
obj.posY = this._y
|
|
278
|
+
|
|
279
|
+
if (this._x > this.x) {
|
|
280
|
+
this.x += Math.min(renderSpeed, this._x - this.x)
|
|
281
|
+
moving = true
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (this._x < this.x) {
|
|
285
|
+
this.x -= Math.min(renderSpeed, this.x - this._x)
|
|
286
|
+
moving = true
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (this._y > this.y) {
|
|
290
|
+
this.y += Math.min(renderSpeed, this._y - this.y)
|
|
291
|
+
moving = true
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (this._y < this.y) {
|
|
295
|
+
this.y -= Math.min(renderSpeed, this.y - this._y)
|
|
296
|
+
moving = true
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
this.callMethodInComponents('update', [obj, { moving }, deltaRatio])
|
|
301
|
+
this.onUpdate(obj)
|
|
302
|
+
|
|
303
|
+
return {
|
|
304
|
+
moving
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
showAnimation(graphic: string | string[], animationName: string) {
|
|
309
|
+
return this.callMethodInComponents('showAnimation', [graphic, animationName])
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Recover the position according to the graphic
|
|
314
|
+
* Normally, the position is that of the hitbox but, we retrieve the top left corner of the graphic
|
|
315
|
+
*
|
|
316
|
+
* You can also pass the `middle` value as first parameter to retrieve the positions from the middle of the sprite
|
|
317
|
+
*
|
|
318
|
+
* @title Get Positions of Graphic
|
|
319
|
+
* @method sprite.getPositionsOfGraphic(align)
|
|
320
|
+
* @param {string} [align] middle
|
|
321
|
+
* @returns { x: number, y: number }
|
|
322
|
+
* @memberof RpgSprite
|
|
323
|
+
*/
|
|
324
|
+
getPositionsOfGraphic(align: string): PositionXY {
|
|
325
|
+
let sprite: RpgSprite | undefined
|
|
326
|
+
// if no component (no graphic for example)
|
|
327
|
+
if (this.components.center?.lines.length !== 0) {
|
|
328
|
+
sprite = this.containersLayout.center.getChildAt(0) as RpgSprite
|
|
329
|
+
}
|
|
330
|
+
const isMiddle = align == 'middle'
|
|
331
|
+
return {
|
|
332
|
+
x: this.x - this.w * (sprite?.anchor.x ?? 1) + (isMiddle ? this.w / 2 : 0),
|
|
333
|
+
y: this.y - this.h * (sprite?.anchor.y ?? 1) + (isMiddle ? this.h / 2 : 0)
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Get the container by position (center, left, right, top, bottom)
|
|
339
|
+
*
|
|
340
|
+
* @param {LayoutPositionEnum} [position=center]
|
|
341
|
+
* @returns {PIXI.Container}
|
|
342
|
+
*
|
|
343
|
+
* */
|
|
344
|
+
getLayoutContainer(position: LayoutPositionEnum = 'center'): Container {
|
|
345
|
+
return this.containersLayout[position]
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Get Current Scene. Scene is a map, battle, menu, etc.
|
|
350
|
+
* @returns {T}
|
|
351
|
+
*/
|
|
352
|
+
getScene<T>(): T {
|
|
353
|
+
return this.scene as any
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Hooks
|
|
357
|
+
onInit() { }
|
|
358
|
+
onUpdate(obj) { }
|
|
359
|
+
onMove() { }
|
|
360
|
+
onChanges(data, old) { }
|
|
361
|
+
|
|
362
|
+
private callMethodInComponents(name: string, params: unknown[]) {
|
|
363
|
+
for (let component of this.getLayoutContainer().children) {
|
|
364
|
+
if (component[name]) component[name](...params)
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
private createGrid(position: LayoutPositionEnum, gridArray: any, options: LayoutOptions, sprite: SpriteInfo): Container {
|
|
369
|
+
const gridContainer = new Sprite();
|
|
370
|
+
const { height, spriteWidth, spriteHeight } = sprite
|
|
371
|
+
const width = options.width ?? spriteWidth ?? sprite.width
|
|
372
|
+
const gridHeight = options.height ?? 20
|
|
373
|
+
const hitBoxWidth = this.logic?.hitbox.w ?? 0
|
|
374
|
+
const middleWidth = hitBoxWidth / 2 - width / 2
|
|
375
|
+
const posX = gridContainer.x + (options.marginLeft ?? 0) - (options.marginRight ?? 0)
|
|
376
|
+
const posY = gridContainer.y + (this.logic?.hitbox.h ?? 0) + (options.marginTop ?? 0) - (options.marginBottom ?? 0)
|
|
377
|
+
|
|
378
|
+
switch (position) {
|
|
379
|
+
case 'top':
|
|
380
|
+
gridContainer.x = posX + middleWidth
|
|
381
|
+
gridContainer.y = posY - spriteHeight
|
|
382
|
+
gridContainer.y -= (gridArray.length * gridHeight)
|
|
383
|
+
break;
|
|
384
|
+
case 'bottom':
|
|
385
|
+
gridContainer.x = posX + middleWidth
|
|
386
|
+
gridContainer.y = posY
|
|
387
|
+
break;
|
|
388
|
+
case 'left':
|
|
389
|
+
gridContainer.x = posX - width - (hitBoxWidth < spriteWidth ? hitBoxWidth / 2 : 0)
|
|
390
|
+
gridContainer.y = posY - spriteHeight
|
|
391
|
+
break;
|
|
392
|
+
case 'right':
|
|
393
|
+
gridContainer.x = posX + width + (hitBoxWidth > spriteWidth ? hitBoxWidth / 2 : 0)
|
|
394
|
+
gridContainer.y = posY - spriteHeight
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
for (let y = 0; y < gridArray.length; y++) {
|
|
398
|
+
const columns = gridArray[y].col.length;
|
|
399
|
+
const cellWidth = (width / columns);
|
|
400
|
+
for (let x = 0; x < columns; x++) {
|
|
401
|
+
const params: ComponentObject<any> = gridArray[y].col[x];
|
|
402
|
+
const component = this.applyComponent(params)
|
|
403
|
+
component.onRender$
|
|
404
|
+
.pipe(
|
|
405
|
+
takeUntil(this.layoutNotifierClear[position]),
|
|
406
|
+
finalize(() => {
|
|
407
|
+
component.onRemove()
|
|
408
|
+
})
|
|
409
|
+
)
|
|
410
|
+
.subscribe(() => {
|
|
411
|
+
component.x = Math.round((x * cellWidth) + (cellWidth / 2) - (component.width / 2))
|
|
412
|
+
component.y = Math.round((y * gridHeight) + (gridHeight / 2) - (component.height / 2))
|
|
413
|
+
})
|
|
414
|
+
component.onInit({
|
|
415
|
+
width: cellWidth,
|
|
416
|
+
height: gridHeight
|
|
417
|
+
})
|
|
418
|
+
gridContainer.addChild(component)
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return gridContainer
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
private applyComponent(component: ComponentObject<any>): AbstractComponent<any, any> {
|
|
426
|
+
const compClass = this.registerComponents.get(component.id)
|
|
427
|
+
if (!compClass) {
|
|
428
|
+
throw log(`Impossible to find ${component.id} component`)
|
|
429
|
+
}
|
|
430
|
+
return new compClass(this, component.value)
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
private createComponentCenter(components: LayoutObject<any>) {
|
|
434
|
+
const lines = components.center?.lines || []
|
|
435
|
+
|
|
436
|
+
this.getLayoutContainer().removeChildren()
|
|
437
|
+
|
|
438
|
+
for (let { col } of lines) {
|
|
439
|
+
for (let component of col) {
|
|
440
|
+
const instance = this.applyComponent(component)
|
|
441
|
+
if (instance.onInit) instance.onInit({
|
|
442
|
+
width: this.logic?.width ?? this.width,
|
|
443
|
+
height: this.logic?.height ?? this.height
|
|
444
|
+
})
|
|
445
|
+
this.getLayoutContainer().addChild(instance)
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
this.components = components
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
private refreshComponents(components: LayoutObject<any>, sprite: SpriteInfo) {
|
|
453
|
+
for (let type of layoutTypes) {
|
|
454
|
+
const layout = components[type]
|
|
455
|
+
if (layout?.lines) {
|
|
456
|
+
const layoutContainer = this.getLayoutContainer(type)
|
|
457
|
+
layoutContainer.removeChildren()
|
|
458
|
+
this.layoutNotifierClear[type].next()
|
|
459
|
+
layoutContainer.addChild(this.createGrid(type, layout.lines, layout, sprite))
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
private updateComponents(components: LayoutObject<any>) {
|
|
465
|
+
const graphicChanged: boolean = !!components.center?.lines
|
|
466
|
+
|
|
467
|
+
if (graphicChanged) {
|
|
468
|
+
this.createComponentCenter(components)
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (this.subscriptionGraphic) this.subscriptionGraphic.unsubscribe()
|
|
472
|
+
|
|
473
|
+
const child = this.getLayoutContainer().children[0]
|
|
474
|
+
|
|
475
|
+
if (child instanceof RpgSprite) {
|
|
476
|
+
this.subscriptionGraphic = (child as RpgSprite).animationSprite()
|
|
477
|
+
.pipe(
|
|
478
|
+
takeUntil(this.game.getDeleteNotifier(this.id)),
|
|
479
|
+
filter((sprite: any) => sprite),
|
|
480
|
+
distinctUntilChanged((p: any, q: any) =>
|
|
481
|
+
p.width === q.width &&
|
|
482
|
+
p.height === q.height &&
|
|
483
|
+
p.anchor.x === q.anchor.x &&
|
|
484
|
+
p.anchor.y === q.anchor.y),
|
|
485
|
+
)
|
|
486
|
+
.subscribe((sprite) => {
|
|
487
|
+
this.refreshComponents(components, sprite)
|
|
488
|
+
})
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
this.refreshComponents(components, {
|
|
492
|
+
width: this.data.width,
|
|
493
|
+
height: this.data.height,
|
|
494
|
+
anchor: {
|
|
495
|
+
x: 0,
|
|
496
|
+
y: 0
|
|
497
|
+
},
|
|
498
|
+
x: 0,
|
|
499
|
+
y: 0,
|
|
500
|
+
spriteHeight: this.data.height,
|
|
501
|
+
spriteWidth: this.data.width
|
|
502
|
+
})
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
}
|
|
506
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Utils } from "@rpgjs/common"
|
|
2
|
+
import { AbstractComponent, CellInfo } from "./AbstractComponent"
|
|
3
|
+
import { DebugComponentObject } from "@rpgjs/types"
|
|
4
|
+
import { Graphics } from "pixi.js"
|
|
5
|
+
|
|
6
|
+
export class DebugComponent extends AbstractComponent<DebugComponentObject, Graphics> {
|
|
7
|
+
static readonly id: string = 'debug'
|
|
8
|
+
color: string = '#ff0000'
|
|
9
|
+
cacheParams: string[] = ['map', 'position.x', 'position.y']
|
|
10
|
+
private container: Graphics = new Graphics()
|
|
11
|
+
|
|
12
|
+
onInit(cell: CellInfo) {
|
|
13
|
+
this.addChild(this.container)
|
|
14
|
+
this.updateRender(this.component.logic)
|
|
15
|
+
this.eventMode = 'static'
|
|
16
|
+
this.on('pointerdown', () => {
|
|
17
|
+
console.log(this.component.logic)
|
|
18
|
+
})
|
|
19
|
+
super.onInit(cell)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
updateRender(object: any) {
|
|
23
|
+
const hitbox = object.hitbox
|
|
24
|
+
const { pos, w, h } = hitbox
|
|
25
|
+
this.container.clear()
|
|
26
|
+
const { value: color, alpha } = Utils.hexaToNumber(this.color)
|
|
27
|
+
this.container.beginFill(color, alpha)
|
|
28
|
+
this.container.drawRect(
|
|
29
|
+
0,
|
|
30
|
+
0,
|
|
31
|
+
w,
|
|
32
|
+
h
|
|
33
|
+
);
|
|
34
|
+
this.container.endFill()
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Container, Sprite } from "pixi.js"
|
|
2
|
+
import { ImageComponentObject } from "@rpgjs/types"
|
|
3
|
+
import { SceneMap } from "../Scene/Map"
|
|
4
|
+
import { AbstractComponent, CellInfo } from "./AbstractComponent"
|
|
5
|
+
|
|
6
|
+
export class ImageComponent extends AbstractComponent<ImageComponentObject, Container> {
|
|
7
|
+
static readonly id: string = 'image'
|
|
8
|
+
cacheParams: string[] = []
|
|
9
|
+
source: string = ''
|
|
10
|
+
|
|
11
|
+
onInit(cell: CellInfo) {
|
|
12
|
+
super.onInit(cell)
|
|
13
|
+
this.setImage()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
private setImage() {
|
|
17
|
+
if (typeof this.value == 'string') {
|
|
18
|
+
this.source = this.value
|
|
19
|
+
} else {
|
|
20
|
+
this.source = this.value.source
|
|
21
|
+
}
|
|
22
|
+
this.updateRender({})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
updateRender(object: any) {
|
|
26
|
+
this.removeChildren()
|
|
27
|
+
const engine = this.component.getScene<SceneMap>().game.clientEngine
|
|
28
|
+
this.addChild(Sprite.from(engine.getResourceUrl(this.source)))
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Utils } from "@rpgjs/common"
|
|
2
|
+
import { AbstractComponent, CellInfo } from "./AbstractComponent"
|
|
3
|
+
import { ShapeComponentObject } from "@rpgjs/types"
|
|
4
|
+
import { Graphics } from "pixi.js"
|
|
5
|
+
|
|
6
|
+
export class ShapeComponent extends AbstractComponent<ShapeComponentObject, Graphics> {
|
|
7
|
+
static readonly id: string = 'shape'
|
|
8
|
+
private type: ShapeComponentObject['value']['type'] = this.value.type
|
|
9
|
+
private container: Graphics = new Graphics()
|
|
10
|
+
cacheParams: string[] = []
|
|
11
|
+
|
|
12
|
+
onInit(cell: CellInfo) {
|
|
13
|
+
this.cell = cell
|
|
14
|
+
this.updateRender(this.component.logic)
|
|
15
|
+
this.addChild(this.container)
|
|
16
|
+
super.onInit(cell)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
updateRender(object: any) {
|
|
20
|
+
const value = this.value as any
|
|
21
|
+
const height = this.getValue(object, value.height) ?? this.cell?.height ?? 0
|
|
22
|
+
const width = this.getValue(object, value.width) ?? this.cell?.width ?? 0
|
|
23
|
+
|
|
24
|
+
this.container.clear()
|
|
25
|
+
const { value: color, alpha } = Utils.hexaToNumber(this.value.fill)
|
|
26
|
+
this.container.beginFill(color, alpha)
|
|
27
|
+
|
|
28
|
+
if (value.line) {
|
|
29
|
+
const { value: color, alpha } = Utils.hexaToNumber(value.line.color ?? this.value.fill)
|
|
30
|
+
this.container.lineStyle(
|
|
31
|
+
this.getValue(object, value.line.width) ?? 1,
|
|
32
|
+
color,
|
|
33
|
+
this.getValue(object, value.line.alpha) ?? alpha
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
switch (this.type) {
|
|
38
|
+
case 'circle':
|
|
39
|
+
this.container.drawCircle(0, 0, this.getValue(object, value.radius))
|
|
40
|
+
break;
|
|
41
|
+
case 'ellipse':
|
|
42
|
+
this.container.drawEllipse(0, 0, width, height)
|
|
43
|
+
break;
|
|
44
|
+
case 'line':
|
|
45
|
+
if (!value.line) {
|
|
46
|
+
this.container.lineStyle(1, color, alpha)
|
|
47
|
+
}
|
|
48
|
+
this.container.moveTo(this.getValue(object, value.x1), this.getValue(object, value.y1))
|
|
49
|
+
this.container.lineTo(this.getValue(object, value.x2), this.getValue(object, value.y2))
|
|
50
|
+
break;
|
|
51
|
+
case 'polygon':
|
|
52
|
+
this.container.drawPolygon(value.points)
|
|
53
|
+
break;
|
|
54
|
+
case 'rounded-rect':
|
|
55
|
+
this.container.drawRoundedRect(0, 0, width, height, value.radius)
|
|
56
|
+
break;
|
|
57
|
+
default:
|
|
58
|
+
this.container.drawRect(0, 0, width, height)
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
this.container.endFill()
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { TextComponentObject } from "@rpgjs/types"
|
|
2
|
+
import { Graphics, Text } from "pixi.js"
|
|
3
|
+
import { AbstractComponent } from "./AbstractComponent"
|
|
4
|
+
|
|
5
|
+
export class TextComponent extends AbstractComponent<TextComponentObject, Text> {
|
|
6
|
+
static readonly id: string = 'text'
|
|
7
|
+
cacheParams: string[] = []
|
|
8
|
+
private container: Text = new Text('')
|
|
9
|
+
private originValue: string = ''
|
|
10
|
+
|
|
11
|
+
onInit(cell: Graphics) {
|
|
12
|
+
if (typeof this.value == 'string') {
|
|
13
|
+
this.container.text = this.value
|
|
14
|
+
} else if (this.value.style) {
|
|
15
|
+
this.container.style = this.value.style
|
|
16
|
+
this.container.text = this.value.text
|
|
17
|
+
}
|
|
18
|
+
this.container.style = {
|
|
19
|
+
...this.container.style,
|
|
20
|
+
wordWrapWidth: cell.width
|
|
21
|
+
}
|
|
22
|
+
this.parseTextAndCache(this.container.text)
|
|
23
|
+
this.originValue = this.container.text
|
|
24
|
+
// first render for replace variable and remove {}
|
|
25
|
+
this.updateRender(this.component.logic)
|
|
26
|
+
this.addChild(this.container)
|
|
27
|
+
super.onInit(cell)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
updateRender(object: any) {
|
|
31
|
+
this.container.text = this.replaceText(object, this.originValue)
|
|
32
|
+
}
|
|
33
|
+
}
|