@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,43 @@
|
|
|
1
|
+
import { TileComponentObject } from "@rpgjs/types"
|
|
2
|
+
import { SceneMap } from "../Scene/Map"
|
|
3
|
+
import Tile from "../Tilemap/Tile"
|
|
4
|
+
import TileLayer from "../Tilemap/TileLayer"
|
|
5
|
+
import { AbstractComponent, CellInfo } from "./AbstractComponent"
|
|
6
|
+
import { Container } from "pixi.js"
|
|
7
|
+
|
|
8
|
+
export class TileComponent extends AbstractComponent<TileComponentObject, Container> {
|
|
9
|
+
static readonly id: string = 'tile'
|
|
10
|
+
cacheParams: string[] = []
|
|
11
|
+
gid: number = 0
|
|
12
|
+
|
|
13
|
+
onInit(cell: CellInfo) {
|
|
14
|
+
this.cell = cell
|
|
15
|
+
if (typeof this.value == 'number') {
|
|
16
|
+
this.gid = this.value
|
|
17
|
+
} else {
|
|
18
|
+
this.gid = this.value.gid
|
|
19
|
+
}
|
|
20
|
+
this.updateRender({})
|
|
21
|
+
super.onInit(cell)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
updateRender(object: any) {
|
|
25
|
+
this.removeChildren()
|
|
26
|
+
const height = typeof this.value != 'number' ? this.getValue(object, this.value.height) : null ?? this.cell?.height ?? 0
|
|
27
|
+
const width = typeof this.value != 'number' ? this.getValue(object, this.value.width) : null ?? this.cell?.width ?? 0
|
|
28
|
+
const scene = this.component.getScene<SceneMap>()
|
|
29
|
+
const tilemap = scene.tilemap
|
|
30
|
+
const tileset = TileLayer.findTileSet(
|
|
31
|
+
this.gid,
|
|
32
|
+
tilemap.tilesets
|
|
33
|
+
)
|
|
34
|
+
if (tileset) {
|
|
35
|
+
const tile = new Tile({
|
|
36
|
+
gid: this.gid
|
|
37
|
+
} as any, tileset)
|
|
38
|
+
tile.width = width ?? 0
|
|
39
|
+
tile.height = height ?? 0
|
|
40
|
+
this.addChild(tile)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { Utils } from '@rpgjs/common'
|
|
2
|
+
import { spritesheets } from '../Sprite/Spritesheets'
|
|
3
|
+
import { SpritesheetOptions, TextureOptions, AnimationFrames, FrameOptions, TransformOptions } from '../Sprite/Spritesheet'
|
|
4
|
+
import { log } from '../Logger'
|
|
5
|
+
import { RpgSound } from '../Sound/RpgSound'
|
|
6
|
+
import { RpgComponent } from '../Components/Component'
|
|
7
|
+
import { Sprite, Container, Texture, Rectangle } from 'pixi.js'
|
|
8
|
+
import { Animation as AnimationEnum } from './AnimationCharacter'
|
|
9
|
+
import { BehaviorSubject, Observable } from 'rxjs'
|
|
10
|
+
|
|
11
|
+
const { isFunction, arrayEquals } = Utils
|
|
12
|
+
|
|
13
|
+
type Image = { image: string }
|
|
14
|
+
|
|
15
|
+
type TextureOptionsMerging = TextureOptions & {
|
|
16
|
+
spriteWidth: number
|
|
17
|
+
spriteHeight: number
|
|
18
|
+
sound?: string
|
|
19
|
+
} & Image & TransformOptions
|
|
20
|
+
|
|
21
|
+
type FrameOptionsMerging = TextureOptionsMerging & FrameOptions
|
|
22
|
+
type SpritesheetOptionsMerging = TextureOptionsMerging & SpritesheetOptions
|
|
23
|
+
type TransformOptionsAsArray = Pick<TransformOptions, 'anchor' | 'scale' | 'skew' | 'pivot'>
|
|
24
|
+
|
|
25
|
+
type AnimationDataFrames = {
|
|
26
|
+
container: Container,
|
|
27
|
+
sprites: FrameOptionsMerging[],
|
|
28
|
+
frames: Texture[][],
|
|
29
|
+
name: string,
|
|
30
|
+
animations: AnimationFrames,
|
|
31
|
+
params: any[],
|
|
32
|
+
data: TextureOptionsMerging
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class Animation extends Sprite {
|
|
36
|
+
public attachTo: RpgComponent
|
|
37
|
+
public hitbox: { w: number, h: number }
|
|
38
|
+
public applyTransform: (
|
|
39
|
+
frame: FrameOptionsMerging,
|
|
40
|
+
data: TextureOptionsMerging,
|
|
41
|
+
spritesheet: SpritesheetOptionsMerging
|
|
42
|
+
) => Partial<FrameOptionsMerging>
|
|
43
|
+
private spritesheet: SpritesheetOptionsMerging
|
|
44
|
+
private currentAnimation: AnimationDataFrames | null = null
|
|
45
|
+
private time: number = 0
|
|
46
|
+
private frameIndex: number = 0
|
|
47
|
+
private animations: Map<string, AnimationDataFrames> = new Map()
|
|
48
|
+
private _animation$: BehaviorSubject<Sprite | null> = new BehaviorSubject(null as any)
|
|
49
|
+
readonly animation$: Observable<Sprite | null> = this._animation$.asObservable()
|
|
50
|
+
|
|
51
|
+
onFinish: () => void
|
|
52
|
+
|
|
53
|
+
constructor(public id: string) {
|
|
54
|
+
super()
|
|
55
|
+
this.spritesheet = spritesheets.get(this.id)
|
|
56
|
+
if (!this.spritesheet) {
|
|
57
|
+
throw log(`Impossible to find the ${this.id} spritesheet. Did you put the right name or create the spritesheet?`)
|
|
58
|
+
}
|
|
59
|
+
this.createAnimations()
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private createTextures(options: Required<TextureOptionsMerging>): Texture[][] {
|
|
63
|
+
const { width, height, framesHeight, framesWidth, image, offset } = options
|
|
64
|
+
const { baseTexture } = Texture.from(image)
|
|
65
|
+
const spriteWidth = options.spriteWidth
|
|
66
|
+
const spriteHeight = options.spriteHeight
|
|
67
|
+
const frames: Texture[][] = []
|
|
68
|
+
const offsetX = (offset && offset.x) || 0
|
|
69
|
+
const offsetY = (offset && offset.y) || 0
|
|
70
|
+
for (let i = 0; i < framesHeight; i++) {
|
|
71
|
+
frames[i] = []
|
|
72
|
+
for (let j = 0; j < framesWidth; j++) {
|
|
73
|
+
const rectX = j * spriteWidth + offsetX
|
|
74
|
+
const rectY = i * spriteHeight + offsetY
|
|
75
|
+
if (rectY > height) {
|
|
76
|
+
throw log(`Warning, there is a problem with the height of the "${this.id}" spritesheet. When cutting into frames, the frame exceeds the height of the image.`)
|
|
77
|
+
}
|
|
78
|
+
if (rectX > width) {
|
|
79
|
+
throw log(`Warning, there is a problem with the width of the "${this.id}" spritesheet. When cutting into frames, the frame exceeds the width of the image.`)
|
|
80
|
+
}
|
|
81
|
+
frames[i].push(
|
|
82
|
+
new Texture(baseTexture, new Rectangle(rectX, rectY, spriteWidth, spriteHeight))
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return frames
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private createAnimations() {
|
|
90
|
+
const { textures } = this.spritesheet
|
|
91
|
+
if (!textures) {
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
for (let animationName in textures) {
|
|
95
|
+
const props: (keyof TextureOptionsMerging)[] = ['width', 'height', 'framesHeight', 'framesWidth', 'rectWidth', 'rectHeight', 'offset', 'image', 'sound']
|
|
96
|
+
const parentObj = props
|
|
97
|
+
.reduce((prev, val) => ({ ...prev, [val]: this.spritesheet[val] }), {})
|
|
98
|
+
const optionsTextures: TextureOptionsMerging = {
|
|
99
|
+
...parentObj,
|
|
100
|
+
...textures[animationName]
|
|
101
|
+
} as any
|
|
102
|
+
const { rectWidth, width = 0, framesWidth = 1, rectHeight, height = 0, framesHeight = 1 } = optionsTextures
|
|
103
|
+
optionsTextures.spriteWidth = rectWidth ? rectWidth : width / framesWidth
|
|
104
|
+
optionsTextures.spriteHeight = rectHeight ? rectHeight : height / framesHeight
|
|
105
|
+
this.animations.set(animationName, {
|
|
106
|
+
container: new Sprite(),
|
|
107
|
+
frames: this.createTextures(optionsTextures as Required<TextureOptionsMerging>),
|
|
108
|
+
name: animationName,
|
|
109
|
+
animations: textures[animationName].animations,
|
|
110
|
+
params: [],
|
|
111
|
+
data: optionsTextures,
|
|
112
|
+
sprites: []
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private getSpriteSize(name: 'spriteHeight' | 'spriteWidth'): number {
|
|
118
|
+
return this.animations.get(this.currentAnimation?.name || AnimationEnum.Stand)?.data[name] || 0
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
getSpriteHeight(): number {
|
|
122
|
+
return this.getSpriteSize('spriteHeight')
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
getSpriteWidth(): number {
|
|
126
|
+
return this.getSpriteSize('spriteWidth')
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
has(name: string): boolean {
|
|
130
|
+
return this.animations.has(name)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
get(name: string): AnimationDataFrames {
|
|
134
|
+
return this.animations.get(name) as AnimationDataFrames
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
isPlaying(name?: string): boolean {
|
|
138
|
+
if (!name) return !!this.currentAnimation
|
|
139
|
+
if (this.currentAnimation == null) return false
|
|
140
|
+
return this.currentAnimation.name == name
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
stop() {
|
|
144
|
+
this.currentAnimation = null
|
|
145
|
+
this.parent?.removeChild(this)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
play(name: string, params: any[] = []) {
|
|
149
|
+
const animParams = this.currentAnimation?.params
|
|
150
|
+
|
|
151
|
+
if (this.isPlaying(name) && arrayEquals(params, animParams || [])) return
|
|
152
|
+
|
|
153
|
+
const animation = this.get(name)
|
|
154
|
+
|
|
155
|
+
if (!animation) {
|
|
156
|
+
throw new Error(`Impossible to play the ${name} animation because it doesn't exist on the ${this.id} spritesheet`)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
this.removeChildren()
|
|
160
|
+
animation.sprites = []
|
|
161
|
+
this.currentAnimation = animation
|
|
162
|
+
this.currentAnimation.params = params
|
|
163
|
+
this.time = 0
|
|
164
|
+
this.frameIndex = 0
|
|
165
|
+
|
|
166
|
+
let animations: any = animation.animations;
|
|
167
|
+
animations = isFunction(animations) ? (animations as Function)(...params) : animations
|
|
168
|
+
|
|
169
|
+
this.currentAnimation.container = new Container()
|
|
170
|
+
|
|
171
|
+
for (let container of (animations as FrameOptionsMerging[][])) {
|
|
172
|
+
const sprite = new Sprite()
|
|
173
|
+
for (let frame of container) {
|
|
174
|
+
this.currentAnimation.sprites.push(frame)
|
|
175
|
+
}
|
|
176
|
+
this.currentAnimation.container.addChild(sprite)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const sound = this.currentAnimation.data.sound
|
|
180
|
+
|
|
181
|
+
if (sound) {
|
|
182
|
+
RpgSound.get(sound).play()
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
this.addChild(this.currentAnimation.container)
|
|
186
|
+
// Updates immediately to avoid flickering
|
|
187
|
+
this.update(1)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
update(deltaRatio: number) {
|
|
191
|
+
if (!this.isPlaying() || !this.currentAnimation) return
|
|
192
|
+
|
|
193
|
+
const { frames, container, sprites, data } = this.currentAnimation
|
|
194
|
+
let frame = sprites[this.frameIndex]
|
|
195
|
+
const nextFrame = sprites[this.frameIndex + 1]
|
|
196
|
+
|
|
197
|
+
if (this.attachTo) {
|
|
198
|
+
const sprite = this.attachTo
|
|
199
|
+
const pos = sprite?.getPositionsOfGraphic('middle')
|
|
200
|
+
if (pos) {
|
|
201
|
+
container.x = pos.x
|
|
202
|
+
container.y = pos.y
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
for (let _sprite of container.children) {
|
|
207
|
+
const sprite = _sprite as Sprite
|
|
208
|
+
|
|
209
|
+
if (!frame || frame.frameY == undefined || frame.frameX == undefined) {
|
|
210
|
+
continue
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
sprite.texture = frames[frame.frameY][frame.frameX]
|
|
214
|
+
|
|
215
|
+
const getVal = <T extends keyof TransformOptions>(prop: T): TransformOptions[T] | undefined =>
|
|
216
|
+
frame[prop] || data[prop] || this.spritesheet[prop]
|
|
217
|
+
|
|
218
|
+
const applyTransform = <T extends keyof TransformOptionsAsArray>(prop: T): void => {
|
|
219
|
+
const val = getVal<T>(prop)
|
|
220
|
+
if (val) {
|
|
221
|
+
sprite[prop as string].set(...val!)
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function applyTransformValue<T extends keyof TransformOptions>(prop: T);
|
|
226
|
+
function applyTransformValue<T extends keyof TransformOptions>(prop: string, alias: T);
|
|
227
|
+
function applyTransformValue<T extends keyof TransformOptions>(prop: T, alias?: T): void {
|
|
228
|
+
const optionProp = alias || prop
|
|
229
|
+
const val = getVal<T>(optionProp)
|
|
230
|
+
if (val !== undefined) {
|
|
231
|
+
sprite[prop as string] = val
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (this.applyTransform) {
|
|
236
|
+
frame = {
|
|
237
|
+
...frame,
|
|
238
|
+
...this.applyTransform(frame, data, this.spritesheet)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const realSize = getVal<'spriteRealSize'>('spriteRealSize')
|
|
244
|
+
const heightOfSprite = typeof realSize == 'number' ? realSize : realSize?.height
|
|
245
|
+
const widthOfSprite = typeof realSize == 'number' ? realSize : realSize?.width
|
|
246
|
+
|
|
247
|
+
const applyAnchorBySize = () => {
|
|
248
|
+
if (heightOfSprite && this.hitbox) {
|
|
249
|
+
const { spriteWidth, spriteHeight } = data
|
|
250
|
+
const w = ((spriteWidth - this.hitbox.w) / 2) / spriteWidth
|
|
251
|
+
const gap = (spriteHeight - heightOfSprite) / 2
|
|
252
|
+
const h = (spriteHeight - this.hitbox.h - gap) / spriteHeight
|
|
253
|
+
sprite.anchor.set(w, h)
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (frame.sound) {
|
|
258
|
+
RpgSound.get(frame.sound).play()
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
applyAnchorBySize()
|
|
262
|
+
|
|
263
|
+
applyTransform('anchor')
|
|
264
|
+
applyTransform('scale')
|
|
265
|
+
applyTransform('skew')
|
|
266
|
+
applyTransform('pivot')
|
|
267
|
+
|
|
268
|
+
applyTransformValue('alpha', 'opacity')
|
|
269
|
+
applyTransformValue('x')
|
|
270
|
+
applyTransformValue('y')
|
|
271
|
+
applyTransformValue('angle')
|
|
272
|
+
applyTransformValue('rotation')
|
|
273
|
+
applyTransformValue('visible')
|
|
274
|
+
|
|
275
|
+
this._animation$.next({
|
|
276
|
+
spriteWidth: widthOfSprite || sprite.width,
|
|
277
|
+
spriteHeight: heightOfSprite || sprite.height,
|
|
278
|
+
anchor: sprite.anchor,
|
|
279
|
+
width: getVal<any>('spriteWidth'),
|
|
280
|
+
height: getVal<any>('spriteHeight')
|
|
281
|
+
} as any)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (!nextFrame) {
|
|
285
|
+
this.time = 0
|
|
286
|
+
this.frameIndex = 0
|
|
287
|
+
if (this.onFinish) this.onFinish()
|
|
288
|
+
return
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
this.time += deltaRatio
|
|
292
|
+
|
|
293
|
+
if (this.time >= nextFrame.time) {
|
|
294
|
+
this.frameIndex++
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { RpgClientEngine } from "../RpgClientEngine";
|
|
2
|
+
import { Graphics, Renderer } from "pixi.js";
|
|
3
|
+
|
|
4
|
+
export class SpinnerGraphic extends Graphics {
|
|
5
|
+
constructor(private clientEngine: RpgClientEngine) {
|
|
6
|
+
super()
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
render(renderer: Renderer) {
|
|
10
|
+
super.render(renderer)
|
|
11
|
+
this.rotation += 0.12;
|
|
12
|
+
const percent = Math.abs(Math.sin(Date.now() / 1000))
|
|
13
|
+
this
|
|
14
|
+
.clear()
|
|
15
|
+
.lineStyle(4, 0xffffff, 1)
|
|
16
|
+
.moveTo(40, 0)
|
|
17
|
+
.arc(0, 0, 40, 0, Math.PI * 2 * percent, false)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { TransformOptions, FrameOptions } from '../Sprite/Spritesheet'
|
|
2
|
+
|
|
3
|
+
export const Ease = {
|
|
4
|
+
linear(t: number, b: number, c: number, d: number): number {
|
|
5
|
+
return c*(t/=d) + b;
|
|
6
|
+
},
|
|
7
|
+
easeInQuad (t: number, b: number, c: number, d: number): number {
|
|
8
|
+
return c*(t/=d)*t + b;
|
|
9
|
+
},
|
|
10
|
+
easeOutQuad (t: number, b: number, c: number, d: number): number {
|
|
11
|
+
return -c *(t/=d)*(t-2) + b;
|
|
12
|
+
},
|
|
13
|
+
easeInOutQuad (t: number, b: number, c: number, d: number): number {
|
|
14
|
+
if ((t/=d/2) < 1) return c/2*t*t + b;
|
|
15
|
+
return -c/2 * ((--t)*(t-2) - 1) + b;
|
|
16
|
+
},
|
|
17
|
+
easeInCubic (t: number, b: number, c: number, d: number): number {
|
|
18
|
+
return c*(t/=d)*t*t + b;
|
|
19
|
+
},
|
|
20
|
+
easeOutCubic (t: number, b: number, c: number, d: number): number {
|
|
21
|
+
return c*((t=t/d-1)*t*t + 1) + b;
|
|
22
|
+
},
|
|
23
|
+
easeInOutCubic (t: number, b: number, c: number, d: number): number {
|
|
24
|
+
if ((t/=d/2) < 1) return c/2*t*t*t + b;
|
|
25
|
+
return c/2*((t-=2)*t*t + 2) + b;
|
|
26
|
+
},
|
|
27
|
+
easeInQuart (t: number, b: number, c: number, d: number): number {
|
|
28
|
+
return c*(t/=d)*t*t*t + b;
|
|
29
|
+
},
|
|
30
|
+
easeOutQuart (t: number, b: number, c: number, d: number): number {
|
|
31
|
+
return -c * ((t=t/d-1)*t*t*t - 1) + b;
|
|
32
|
+
},
|
|
33
|
+
easeInOutQuart (t: number, b: number, c: number, d: number): number {
|
|
34
|
+
if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
|
|
35
|
+
return -c/2 * ((t-=2)*t*t*t - 2) + b;
|
|
36
|
+
},
|
|
37
|
+
easeInQuint (t: number, b: number, c: number, d: number): number {
|
|
38
|
+
return c*(t/=d)*t*t*t*t + b;
|
|
39
|
+
},
|
|
40
|
+
easeOutQuint (t: number, b: number, c: number, d: number): number {
|
|
41
|
+
return c*((t=t/d-1)*t*t*t*t + 1) + b;
|
|
42
|
+
},
|
|
43
|
+
easeInOutQuint (t: number, b: number, c: number, d: number): number {
|
|
44
|
+
if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
|
|
45
|
+
return c/2*((t-=2)*t*t*t*t + 2) + b;
|
|
46
|
+
},
|
|
47
|
+
easeInSine (t: number, b: number, c: number, d: number): number {
|
|
48
|
+
return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
|
|
49
|
+
},
|
|
50
|
+
easeOutSine (t: number, b: number, c: number, d: number): number {
|
|
51
|
+
return c * Math.sin(t/d * (Math.PI/2)) + b;
|
|
52
|
+
},
|
|
53
|
+
easeInOutSine (t: number, b: number, c: number, d: number): number {
|
|
54
|
+
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
|
|
55
|
+
},
|
|
56
|
+
easeInExpo (t: number, b: number, c: number, d: number): number {
|
|
57
|
+
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
|
|
58
|
+
},
|
|
59
|
+
easeOutExpo (t: number, b: number, c: number, d: number): number {
|
|
60
|
+
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
|
|
61
|
+
},
|
|
62
|
+
easeInOutExpo (t: number, b: number, c: number, d: number): number {
|
|
63
|
+
if (t==0) return b;
|
|
64
|
+
if (t==d) return b+c;
|
|
65
|
+
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
|
|
66
|
+
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
|
|
67
|
+
},
|
|
68
|
+
easeInCirc (t: number, b: number, c: number, d: number): number {
|
|
69
|
+
return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
|
|
70
|
+
},
|
|
71
|
+
easeOutCirc (t: number, b: number, c: number, d: number): number {
|
|
72
|
+
return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
|
|
73
|
+
},
|
|
74
|
+
easeInOutCirc (t: number, b: number, c: number, d: number): number {
|
|
75
|
+
if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
|
|
76
|
+
return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
|
|
77
|
+
},
|
|
78
|
+
easeInElastic (t: number, b: number, c: number, d: number): number {
|
|
79
|
+
var s=1.70158;var p=0;var a=c;
|
|
80
|
+
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
|
81
|
+
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
|
82
|
+
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
|
83
|
+
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
|
84
|
+
},
|
|
85
|
+
easeOutElastic (t: number, b: number, c: number, d: number): number {
|
|
86
|
+
var s=1.70158;var p=0;var a=c;
|
|
87
|
+
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
|
88
|
+
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
|
89
|
+
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
|
90
|
+
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
|
|
91
|
+
},
|
|
92
|
+
easeInOutElastic (t: number, b: number, c: number, d: number): number {
|
|
93
|
+
var s=1.70158;var p=0;var a=c;
|
|
94
|
+
if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
|
|
95
|
+
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
|
96
|
+
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
|
97
|
+
if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
|
98
|
+
return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
|
|
99
|
+
},
|
|
100
|
+
easeInBack (t: number, b: number, c: number, d: number, s: number): number {
|
|
101
|
+
if (s == undefined) s = 1.70158;
|
|
102
|
+
return c*(t/=d)*t*((s+1)*t - s) + b;
|
|
103
|
+
},
|
|
104
|
+
easeOutBack (t: number, b: number, c: number, d: number, s: number): number {
|
|
105
|
+
if (s == undefined) s = 1.70158;
|
|
106
|
+
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
|
|
107
|
+
},
|
|
108
|
+
easeInOutBack (t: number, b: number, c: number, d: number, s: number): number {
|
|
109
|
+
if (s == undefined) s = 1.70158;
|
|
110
|
+
if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
|
|
111
|
+
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
|
|
112
|
+
},
|
|
113
|
+
easeInBounce (t: number, b: number, c: number, d: number): number {
|
|
114
|
+
return c - Ease.easeOutBounce (d-t, 0, c, d) + b;
|
|
115
|
+
},
|
|
116
|
+
easeOutBounce (t: number, b: number, c: number, d: number): number {
|
|
117
|
+
if ((t/=d) < (1/2.75)) {
|
|
118
|
+
return c*(7.5625*t*t) + b;
|
|
119
|
+
} else if (t < (2/2.75)) {
|
|
120
|
+
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
|
|
121
|
+
} else if (t < (2.5/2.75)) {
|
|
122
|
+
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
|
|
123
|
+
} else {
|
|
124
|
+
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
easeInOutBounce (t: number, b: number, c: number, d: number): number {
|
|
128
|
+
if (t < d/2) return Ease.easeInBounce (t*2, 0, c, d) * .5 + b;
|
|
129
|
+
return Ease.easeOutBounce (t*2-d, 0, c, d) * .5 + c*.5 + b;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
type EaseType = (t: number, b: number, c: number, d: number) => number
|
|
134
|
+
|
|
135
|
+
export class Timeline {
|
|
136
|
+
private time: number = 0
|
|
137
|
+
private animation: FrameOptions[][] = []
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Allows you to create complex animations more easily. For example, to display a movement with an Easing function
|
|
141
|
+
*
|
|
142
|
+
* ```ts
|
|
143
|
+
* import { Timeline, Ease } from '@rpgjs/client'
|
|
144
|
+
*
|
|
145
|
+
* new Timeline()
|
|
146
|
+
* .add(30, ({ scale }) => [{
|
|
147
|
+
* frameX: 0,
|
|
148
|
+
* frameY: 1,
|
|
149
|
+
* scale: [scale]
|
|
150
|
+
* }], {
|
|
151
|
+
* scale: {
|
|
152
|
+
* from: 0,
|
|
153
|
+
* to: 1,
|
|
154
|
+
* easing: Ease.easeOutBounce
|
|
155
|
+
* }
|
|
156
|
+
* })
|
|
157
|
+
* .add(100)
|
|
158
|
+
* .create()
|
|
159
|
+
* ```
|
|
160
|
+
*
|
|
161
|
+
* Here we say
|
|
162
|
+
*
|
|
163
|
+
* - For a duration of 30 seconds
|
|
164
|
+
* - A function that will be called every 1 frame with the `scale` property defined in transform
|
|
165
|
+
* - An object of transformation. Define the properties of your choice to be passed to the callback function
|
|
166
|
+
* - `to`: the starting value
|
|
167
|
+
* - `from`: the end value
|
|
168
|
+
* - `easing`: An easing function (By default, it is a linear function)
|
|
169
|
+
*
|
|
170
|
+
* Note that if you just put a duration (`add(100)`), it will only put a pause on the animation
|
|
171
|
+
*
|
|
172
|
+
* Easing functions available but you can create your own
|
|
173
|
+
*
|
|
174
|
+
* ```ts
|
|
175
|
+
* function myEase(t: number, b: number, c: number, d: number): number { }
|
|
176
|
+
* ```
|
|
177
|
+
*
|
|
178
|
+
* `t`: current time
|
|
179
|
+
* `b`: start value
|
|
180
|
+
* `c`: end value
|
|
181
|
+
* `d`: duration
|
|
182
|
+
*
|
|
183
|
+
* @title Add Animation in timeline
|
|
184
|
+
* @enum {Function}
|
|
185
|
+
*
|
|
186
|
+
* Ease.linear | linear
|
|
187
|
+
* Ease.easeInQuad | easeInQuad
|
|
188
|
+
* Ease.easeOutQuad | easeOutQuad
|
|
189
|
+
* Ease.easeInOutQuad | easeInOutQuad
|
|
190
|
+
* Ease.easeInCubic | easeInCubic
|
|
191
|
+
* Ease.easeOutCubic | easeOutCubic
|
|
192
|
+
* Ease.easeInOutCubic | easeInOutCubic
|
|
193
|
+
* Ease.easeInQuart | easeInQuart
|
|
194
|
+
* Ease.easeOutQuart | easeOutQuart
|
|
195
|
+
* Ease.easeInOutQuart | easeInOutQuart
|
|
196
|
+
* Ease.easeInQuint | easeInQuint
|
|
197
|
+
* Ease.easeOutQuint | easeOutQuint
|
|
198
|
+
* Ease.easeInOutQuint | easeInOutQuint
|
|
199
|
+
* Ease.easeInSine | easeInSine
|
|
200
|
+
* Ease.easeOutSine | easeOutSine
|
|
201
|
+
* Ease.easeInOutSine | easeInOutSine
|
|
202
|
+
* Ease.easeInExpo | easeInExpo
|
|
203
|
+
* Ease.easeOutExpo | easeOutExpo
|
|
204
|
+
* Ease.easeInOutExpo | easeInOutExpo
|
|
205
|
+
* Ease.easeInCirc | easeInCirc
|
|
206
|
+
* Ease.easeOutCirc | easeOutCirc
|
|
207
|
+
* Ease.easeInOutCirc | easeInOutCirc
|
|
208
|
+
* Ease.easeInElastic | easeInElastic
|
|
209
|
+
* Ease.easeOutElastic | easeOutElastic
|
|
210
|
+
* Ease.easeInOutElastic | easeInOutElastic
|
|
211
|
+
* Ease.easeInBack | easeInBack
|
|
212
|
+
* Ease.easeOutBack | easeOutBack
|
|
213
|
+
* Ease.easeInOutBack | easeInOutBack
|
|
214
|
+
* Ease.easeInBounce | easeInBounce
|
|
215
|
+
* Ease.easeOutBounce | easeOutBounce
|
|
216
|
+
* @method timeline.add(duration,cb?,transform?)
|
|
217
|
+
* @param {number} duration
|
|
218
|
+
* @param { (obj?: number, time?: number) => TransformOptions[] } [cb]
|
|
219
|
+
* @param { [property: string]: { to:number, from: number: easing?: Function } } [transform]
|
|
220
|
+
* @returns {Timeline}
|
|
221
|
+
* @memberof Timeline
|
|
222
|
+
*/
|
|
223
|
+
add(duration: number, cb?: (obj?: any, time?: number) => TransformOptions[], transform?: {
|
|
224
|
+
[property: string]: {
|
|
225
|
+
to: number,
|
|
226
|
+
from: number,
|
|
227
|
+
easing?: EaseType
|
|
228
|
+
}
|
|
229
|
+
}): Timeline {
|
|
230
|
+
if (!cb) {
|
|
231
|
+
this.animation.push([{
|
|
232
|
+
time: duration + this.time,
|
|
233
|
+
}])
|
|
234
|
+
this.time += duration
|
|
235
|
+
return this
|
|
236
|
+
}
|
|
237
|
+
for (let i=0 ; i < duration ; i++) {
|
|
238
|
+
let anim
|
|
239
|
+
const obj = {}
|
|
240
|
+
for (let prop in transform) {
|
|
241
|
+
const param = transform[prop]
|
|
242
|
+
const cbEasing = param.easing || Ease.linear
|
|
243
|
+
if (param.to < param.from) {
|
|
244
|
+
obj[prop] = 1 - cbEasing(i, param.to, param.from, duration)
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
obj[prop] = cbEasing(i, param.from, param.to, duration)
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const ret = cb(obj, i)
|
|
251
|
+
anim = ret.map(el => {
|
|
252
|
+
(el as any).time = i + this.time
|
|
253
|
+
return el
|
|
254
|
+
})
|
|
255
|
+
this.animation.push(anim)
|
|
256
|
+
}
|
|
257
|
+
this.time += duration
|
|
258
|
+
return this
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Allows you to create the animation array to assign to the `animations` property in the Spritesheet
|
|
263
|
+
*
|
|
264
|
+
* ```ts
|
|
265
|
+
* import { Spritesheet, Timeline } from '@rpgjs/server'
|
|
266
|
+
*
|
|
267
|
+
* @Spritesheet({
|
|
268
|
+
* id: 'sprite',
|
|
269
|
+
* image: require('./sprite.png'),
|
|
270
|
+
* width: 192,
|
|
271
|
+
* height: 228,
|
|
272
|
+
* framesHeight: 6,
|
|
273
|
+
* framesWidth: 6,
|
|
274
|
+
* anchor: [0.5],
|
|
275
|
+
* textures: {
|
|
276
|
+
* myanim: {
|
|
277
|
+
* animations: new Timeline()
|
|
278
|
+
* .add(SEE THE ADD METHOD)
|
|
279
|
+
* .create()
|
|
280
|
+
* }
|
|
281
|
+
* }
|
|
282
|
+
* })
|
|
283
|
+
* export class MyAnim {}
|
|
284
|
+
* ```
|
|
285
|
+
*
|
|
286
|
+
* @title Create the animation array
|
|
287
|
+
* @method timeline.create()
|
|
288
|
+
* @returns {FrameOptions[][]} The animation array
|
|
289
|
+
* @memberof Timeline
|
|
290
|
+
*/
|
|
291
|
+
create(): FrameOptions[][] {
|
|
292
|
+
return this.animation
|
|
293
|
+
}
|
|
294
|
+
}
|