@makefully/platypus 4.1.4 → 4.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.md +4 -2
- package/lib/platypus.js +1 -1
- package/package.json +7 -2
- package/src/AABB.js +685 -0
- package/src/ActionState.js +121 -0
- package/src/AssetManager.js +206 -0
- package/src/CollisionData.js +96 -0
- package/src/CollisionDataContainer.js +127 -0
- package/src/CollisionShape.js +315 -0
- package/src/Component.js +231 -0
- package/src/Data.js +64 -0
- package/src/DataMap.js +204 -0
- package/src/Entity.js +404 -0
- package/src/EntityLinker.js +113 -0
- package/src/EventHandler.js +115 -0
- package/src/EventHandlerList.js +251 -0
- package/src/Game.js +840 -0
- package/src/Gamepad.js +175 -0
- package/src/ID3CaptionPlayer.js +61 -0
- package/src/Messenger.js +365 -0
- package/src/PIXIAnimation.js +622 -0
- package/src/RandomSet.js +140 -0
- package/src/SFXPlayer.js +120 -0
- package/src/StateMap.js +252 -0
- package/src/Storage.js +152 -0
- package/src/TickerClient.js +48 -0
- package/src/TickerServer.js +23 -0
- package/src/TimeEvent.js +50 -0
- package/src/TimeEventList.js +100 -0
- package/src/VOPlayer.js +684 -0
- package/src/Vector.js +702 -0
- package/src/components/AIChaser.js +161 -0
- package/src/components/AIPacer.js +107 -0
- package/src/components/AudioMusic.js +151 -0
- package/src/components/AudioSFX.js +673 -0
- package/src/components/AudioVO.js +301 -0
- package/src/components/CollisionBasic.js +826 -0
- package/src/components/CollisionFilter.js +74 -0
- package/src/components/CollisionGroup.js +448 -0
- package/src/components/CollisionTiles.js +608 -0
- package/src/components/ComponentSwitcher.js +173 -0
- package/src/components/ControllerInput.js +65 -0
- package/src/components/Counter.js +165 -0
- package/src/components/EntityCamera.js +215 -0
- package/src/components/EntityContainer.js +549 -0
- package/src/components/EntityController.js +541 -0
- package/src/components/HandlerCamera.js +1052 -0
- package/src/components/HandlerCollision.js +1318 -0
- package/src/components/HandlerController.js +291 -0
- package/src/components/HandlerLogic.js +394 -0
- package/src/components/HandlerRender.js +217 -0
- package/src/components/Interactive.js +502 -0
- package/src/components/LevelBuilder.js +524 -0
- package/src/components/LogicAngularMovement.js +154 -0
- package/src/components/LogicAttachment.js +265 -0
- package/src/components/LogicButton.js +466 -0
- package/src/components/LogicCarrier.js +39 -0
- package/src/components/LogicDestroyMe.js +58 -0
- package/src/components/LogicDirectionalMovement.js +325 -0
- package/src/components/LogicDragDrop.js +371 -0
- package/src/components/LogicImpactLaunch.js +144 -0
- package/src/components/LogicPacingPlatform.js +64 -0
- package/src/components/LogicPortable.js +112 -0
- package/src/components/LogicPortal.js +115 -0
- package/src/components/LogicPushable.js +98 -0
- package/src/components/LogicRebounder.js +136 -0
- package/src/components/LogicRegionSpawner.js +139 -0
- package/src/components/LogicRotationalMovement.js +205 -0
- package/src/components/LogicSpawner.js +159 -0
- package/src/components/LogicStateMachine.js +382 -0
- package/src/components/LogicSwitch.js +77 -0
- package/src/components/LogicTeleportee.js +68 -0
- package/src/components/LogicTeleporter.js +93 -0
- package/src/components/LogicTimer.js +178 -0
- package/src/components/LogicWindUpRacer.js +179 -0
- package/src/components/Motion.js +371 -0
- package/src/components/Mover.js +566 -0
- package/src/components/Node.js +289 -0
- package/src/components/NodeMap.js +295 -0
- package/src/components/NodeResident.js +636 -0
- package/src/components/Orientation.js +697 -0
- package/src/components/RandomEvents.js +73 -0
- package/src/components/RelativePosition.js +204 -0
- package/src/components/RelayFamily.js +106 -0
- package/src/components/RelayGame.js +53 -0
- package/src/components/RelayLinker.js +94 -0
- package/src/components/RelayParent.js +57 -0
- package/src/components/RelaySelf.js +55 -0
- package/src/components/Render.js +178 -0
- package/src/components/RenderAnimator.js +275 -0
- package/src/components/RenderContainer.js +646 -0
- package/src/components/RenderDebug.js +319 -0
- package/src/components/RenderDestroyMe.js +59 -0
- package/src/components/RenderLottie.js +149 -0
- package/src/components/RenderProgress.js +120 -0
- package/src/components/RenderSpine.js +833 -0
- package/src/components/RenderSprite.js +527 -0
- package/src/components/RenderText.js +147 -0
- package/src/components/RenderTiles.js +1391 -0
- package/src/components/SceneChanger.js +128 -0
- package/src/components/TiledLoader.js +1451 -0
- package/src/components/Timeline.js +314 -0
- package/src/components/Tutorial.js +267 -0
- package/src/components/Tween.js +296 -0
- package/src/components/VoiceOver.js +373 -0
- package/src/components/XHR.js +129 -0
- package/src/components/index.js +79 -0
- package/src/factory.js +305 -0
- package/src/index.js +159 -0
- package/src/mixins/PIXI.Graphics.js +41 -0
- package/src/platypus.css +68 -0
- package/src/sayHello.js +50 -0
- package/src/shapes/Capsule.js +74 -0
- package/src/shapes/Circle.js +43 -0
- package/src/shapes/Ellipse.js +117 -0
- package/src/shapes/Point.js +191 -0
- package/src/shapes/Polygon.js +112 -0
- package/src/shapes/Polyline.js +97 -0
- package/src/shapes/Rectangle.js +78 -0
- package/src/shapes/RoundedRectangle.js +33 -0
- package/src/shapes/Segment.js +346 -0
- package/src/shapes/adjustedXY.js +19 -0
- package/src/shapes/castFromBox2D.js +92 -0
- package/src/shapes/castFromObject.js +53 -0
- package/src/shapes/castFromPixiGraphics.js +6 -0
- package/src/shapes/castFromPixiShape.js +89 -0
- package/src/shapes/castToBox2D.js +190 -0
- package/src/shapes/castToPixiGraphics.js +100 -0
- package/src/shapes/castToPixiShape.js +61 -0
- package/src/shapes/checkPointsMap.js +313 -0
- package/src/shapes/index.js +35 -0
- package/src/utils/array.js +73 -0
- package/src/utils/string.js +39 -0
|
@@ -0,0 +1,622 @@
|
|
|
1
|
+
/*global platypus */
|
|
2
|
+
import {AnimatedSprite, TextureSource, Container, Point, Rectangle, Sprite, Texture} from 'pixi.js';
|
|
3
|
+
import {arrayCache, greenSlice} from './utils/array.js';
|
|
4
|
+
import Data from './Data.js';
|
|
5
|
+
|
|
6
|
+
const
|
|
7
|
+
MAX_KEY_LENGTH_PER_IMAGE = 128,
|
|
8
|
+
animationCache = {},
|
|
9
|
+
textureSourceCache = {},
|
|
10
|
+
doNothing = function () {},
|
|
11
|
+
emptyFrame = Texture.EMPTY,
|
|
12
|
+
regex = /[\[\]{},-]/g,
|
|
13
|
+
getTextureSources = function (images) {
|
|
14
|
+
const
|
|
15
|
+
assetCache = platypus.assetCache,
|
|
16
|
+
bts = arrayCache.setUp();
|
|
17
|
+
|
|
18
|
+
for (let i = 0; i < images.length; i++) {
|
|
19
|
+
const
|
|
20
|
+
path = images[i];
|
|
21
|
+
|
|
22
|
+
if (typeof path === 'string') {
|
|
23
|
+
if (!textureSourceCache[path]) {
|
|
24
|
+
const
|
|
25
|
+
asset = assetCache.get(path);
|
|
26
|
+
|
|
27
|
+
if (!asset) {
|
|
28
|
+
platypus.debug.warn(`PIXIAnimation: "${path}" is not a loaded asset.`);
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
textureSourceCache[path] = asset.source;
|
|
32
|
+
}
|
|
33
|
+
bts.push(textureSourceCache[path]);
|
|
34
|
+
} else {
|
|
35
|
+
bts.push(new TextureSource(path));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return bts;
|
|
40
|
+
},
|
|
41
|
+
getTexturesCacheId = function (spriteSheet) {
|
|
42
|
+
if (spriteSheet.id) {
|
|
43
|
+
return spriteSheet.id;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
for (let i = 0; i < spriteSheet.images.length; i++) {
|
|
47
|
+
if (typeof spriteSheet.images[i] !== 'string') {
|
|
48
|
+
return '';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
spriteSheet.id = JSON.stringify(spriteSheet).replace(regex, '');
|
|
53
|
+
|
|
54
|
+
return spriteSheet.id;
|
|
55
|
+
},
|
|
56
|
+
getDefaultAnimation = function (length, textures) {
|
|
57
|
+
const
|
|
58
|
+
frames = arrayCache.setUp();
|
|
59
|
+
|
|
60
|
+
for (let i = 0; i < length; i++) {
|
|
61
|
+
frames.push(textures[i] ?? emptyFrame);
|
|
62
|
+
}
|
|
63
|
+
return Data.setUp(
|
|
64
|
+
"id", "default",
|
|
65
|
+
"frames", frames,
|
|
66
|
+
"next", "default",
|
|
67
|
+
"speed", 1
|
|
68
|
+
);
|
|
69
|
+
},
|
|
70
|
+
standardizeAnimations = function (def, textures) {
|
|
71
|
+
const
|
|
72
|
+
anims = Data.setUp(),
|
|
73
|
+
keys = Object.keys(def),
|
|
74
|
+
{length} = keys;
|
|
75
|
+
|
|
76
|
+
for (let i = 0; i < length; i++) {
|
|
77
|
+
const
|
|
78
|
+
key = keys[i],
|
|
79
|
+
animation = def[key],
|
|
80
|
+
frames = greenSlice(animation.frames);
|
|
81
|
+
let j = frames.length;
|
|
82
|
+
|
|
83
|
+
while (j--) {
|
|
84
|
+
frames[j] = textures[frames[j]] || emptyFrame;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
anims[key] = Data.setUp(
|
|
88
|
+
'id', key,
|
|
89
|
+
'frames', frames,
|
|
90
|
+
'next', animation.next,
|
|
91
|
+
'speed', animation.speed
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!anims.default) {
|
|
96
|
+
// Set up a default animation that plays through all frames
|
|
97
|
+
anims.default = getDefaultAnimation(textures.length, textures);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return anims;
|
|
101
|
+
},
|
|
102
|
+
getAnimations = function (spriteSheet = {}) {
|
|
103
|
+
const
|
|
104
|
+
{frames, images} = spriteSheet,
|
|
105
|
+
bases = getTextureSources(images),
|
|
106
|
+
textures = frames.map((frame) => new Texture({
|
|
107
|
+
source: bases[frame[4]],
|
|
108
|
+
frame: new Rectangle(frame[0], frame[1], frame[2], frame[3]),
|
|
109
|
+
rotate: 0,
|
|
110
|
+
defaultAnchor: new Point((frame[5] || 0) / frame[2], (frame[6] || 0) / frame[3])
|
|
111
|
+
})), // Set up texture for each frame
|
|
112
|
+
anims = standardizeAnimations(spriteSheet.animations, textures); // Set up animations
|
|
113
|
+
|
|
114
|
+
// Set up a default animation that plays through all frames
|
|
115
|
+
if (!anims.default) {
|
|
116
|
+
anims.default = getDefaultAnimation(textures.length, textures);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
arrayCache.recycle(bases);
|
|
120
|
+
|
|
121
|
+
return Data.setUp(
|
|
122
|
+
"textures", textures,
|
|
123
|
+
"animations", anims
|
|
124
|
+
);
|
|
125
|
+
},
|
|
126
|
+
cacheAnimations = function (spriteSheet, cacheId) {
|
|
127
|
+
const
|
|
128
|
+
{frames, images} = spriteSheet,
|
|
129
|
+
bases = getTextureSources(images),
|
|
130
|
+
textures = frames.map((frame) => new Texture({
|
|
131
|
+
source: bases[frame[4]],
|
|
132
|
+
frame: new Rectangle(frame[0], frame[1], frame[2], frame[3]),
|
|
133
|
+
rotate: 0,
|
|
134
|
+
defaultAnchor: new Point((frame[5] || 0) / frame[2], (frame[6] || 0) / frame[3])
|
|
135
|
+
})), // Set up texture for each frame
|
|
136
|
+
anims = standardizeAnimations(spriteSheet.animations, textures); // Set up animations
|
|
137
|
+
|
|
138
|
+
arrayCache.recycle(bases);
|
|
139
|
+
|
|
140
|
+
return Data.setUp(
|
|
141
|
+
"textures", textures,
|
|
142
|
+
"animations", anims,
|
|
143
|
+
"viable", 1,
|
|
144
|
+
"cacheId", cacheId
|
|
145
|
+
);
|
|
146
|
+
},
|
|
147
|
+
/**
|
|
148
|
+
* This class plays animation sequences of frames and mimics the syntax required for creating CreateJS Sprites, allowing CreateJS Sprite Sheet definitions to be used with PixiJS.
|
|
149
|
+
*
|
|
150
|
+
* @memberof platypus
|
|
151
|
+
* @class PIXIAnimation
|
|
152
|
+
* @param {Object} spriteSheet JSON sprite sheet definition.
|
|
153
|
+
* @param {string} animation The name of the animation to start playing.
|
|
154
|
+
*/
|
|
155
|
+
PIXIAnimation = class extends Container {
|
|
156
|
+
constructor (spriteSheet, animation) {
|
|
157
|
+
const
|
|
158
|
+
FR = 60,
|
|
159
|
+
cacheId = getTexturesCacheId(spriteSheet),
|
|
160
|
+
speed = (spriteSheet.framerate || FR) / FR;
|
|
161
|
+
let cache = (cacheId ? animationCache[cacheId] : null);
|
|
162
|
+
|
|
163
|
+
super();
|
|
164
|
+
|
|
165
|
+
if (!cacheId) {
|
|
166
|
+
cache = getAnimations(spriteSheet);
|
|
167
|
+
} else if (!cache) {
|
|
168
|
+
cache = animationCache[cacheId] = cacheAnimations(spriteSheet, cacheId);
|
|
169
|
+
this.cacheId = cacheId;
|
|
170
|
+
} else {
|
|
171
|
+
cache.viable += 1;
|
|
172
|
+
this.cacheId = cacheId;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* @private
|
|
177
|
+
*/
|
|
178
|
+
this._animations = {};
|
|
179
|
+
{
|
|
180
|
+
const
|
|
181
|
+
_animations = this._animations,
|
|
182
|
+
{animations} = cache,
|
|
183
|
+
keys = Object.keys(animations),
|
|
184
|
+
{length} = keys;
|
|
185
|
+
|
|
186
|
+
for (let i = 0; i < length; i++) {
|
|
187
|
+
const
|
|
188
|
+
key = keys[i],
|
|
189
|
+
animation = animations[key];
|
|
190
|
+
|
|
191
|
+
if (animation.frames.length === 1) {
|
|
192
|
+
_animations[key] = new Sprite(animation.frames[0]);
|
|
193
|
+
} else {
|
|
194
|
+
const anim = _animations[key] = new AnimatedSprite(animation.frames);
|
|
195
|
+
|
|
196
|
+
anim.animationSpeed = speed * animation.speed;
|
|
197
|
+
anim.onComplete = anim.onLoop = () => {
|
|
198
|
+
if (this.onComplete) {
|
|
199
|
+
this.onComplete(key);
|
|
200
|
+
}
|
|
201
|
+
if (animation.next) {
|
|
202
|
+
this.gotoAndPlay(animation.next);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
anim.updateAnchor = true;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
this._animation = null;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* The speed that the PIXIAnimation will play at. Higher is faster, lower is slower
|
|
214
|
+
*
|
|
215
|
+
* @member {number}
|
|
216
|
+
* @default 1
|
|
217
|
+
*/
|
|
218
|
+
this.animationSpeed = speed;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* The currently playing animation name.
|
|
222
|
+
*
|
|
223
|
+
* @property currentAnimation
|
|
224
|
+
* @default ""
|
|
225
|
+
* @type String
|
|
226
|
+
*/
|
|
227
|
+
this.currentAnimation = null;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Indicates if the PIXIAnimation is currently playing
|
|
231
|
+
*
|
|
232
|
+
* @member {boolean}
|
|
233
|
+
* @readonly
|
|
234
|
+
*/
|
|
235
|
+
this.playing = false;
|
|
236
|
+
|
|
237
|
+
this._visible = true;
|
|
238
|
+
|
|
239
|
+
this._updating = false;
|
|
240
|
+
|
|
241
|
+
/*
|
|
242
|
+
* Updates the object transform for rendering
|
|
243
|
+
* @private
|
|
244
|
+
*/
|
|
245
|
+
this.update = doNothing;
|
|
246
|
+
|
|
247
|
+
// Set up initial playthrough.
|
|
248
|
+
this.gotoAndPlay(animation);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
get visible () {
|
|
252
|
+
return this._visible;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
set visible (value) {
|
|
256
|
+
this._visible = value;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* The PIXIAnimations paused state. If paused, the animation doesn't update.
|
|
261
|
+
*
|
|
262
|
+
* @property paused
|
|
263
|
+
* @memberof platypus.PIXIAnimation.prototype
|
|
264
|
+
*/
|
|
265
|
+
get paused () {
|
|
266
|
+
return !this.playing;
|
|
267
|
+
}
|
|
268
|
+
set paused (value) {
|
|
269
|
+
if ((value && this.playing) || (!value && !this.playing)) {
|
|
270
|
+
this.playing = !value;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Stops the PIXIAnimation
|
|
276
|
+
*
|
|
277
|
+
* @method platypus.PIXIAnimation#stop
|
|
278
|
+
*/
|
|
279
|
+
stop () {
|
|
280
|
+
this.paused = true;
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Plays the PIXIAnimation
|
|
285
|
+
*
|
|
286
|
+
* @method platypus.PIXIAnimation#play
|
|
287
|
+
*/
|
|
288
|
+
play () {
|
|
289
|
+
this.paused = false;
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Stops the PIXIAnimation and goes to a specific frame
|
|
294
|
+
*
|
|
295
|
+
* @method platypus.PIXIAnimation#gotoAndStop
|
|
296
|
+
* @param animation {number} frame index to stop at
|
|
297
|
+
*/
|
|
298
|
+
gotoAndStop (animation) {
|
|
299
|
+
this.stop();
|
|
300
|
+
if (this._animation && this._animation.stop) {
|
|
301
|
+
this._animation.stop();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
this._animation = this._animations[animation];
|
|
305
|
+
if (!this._animation) {
|
|
306
|
+
this._animation = this._animations.default;
|
|
307
|
+
}
|
|
308
|
+
this.removeChildren();
|
|
309
|
+
this.addChild(this._animation);
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Goes to a specific frame and begins playing the PIXIAnimation
|
|
314
|
+
*
|
|
315
|
+
* @method platypus.PIXIAnimation#gotoAndPlay
|
|
316
|
+
* @param animation {string} The animation to begin playing.
|
|
317
|
+
* @param [loop = true] {Boolean} Whether this animation should loop.
|
|
318
|
+
* @param [restart = true] {Boolean} Whether to restart the animation if it's currently playing.
|
|
319
|
+
*/
|
|
320
|
+
gotoAndPlay (animation, loop = true, restart = true) {
|
|
321
|
+
if ((this.currentAnimation !== animation) || restart) {
|
|
322
|
+
if (this._animation && this._animation.stop) {
|
|
323
|
+
this._animation.stop();
|
|
324
|
+
}
|
|
325
|
+
this._animation = this._animations[animation];
|
|
326
|
+
this.currentAnimation = animation;
|
|
327
|
+
if (!this._animation) {
|
|
328
|
+
this._animation = this._animations.default;
|
|
329
|
+
this.currentAnimation = 'default';
|
|
330
|
+
}
|
|
331
|
+
this.removeChildren();
|
|
332
|
+
this.addChild(this._animation);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
this._animation.loop = loop;
|
|
336
|
+
|
|
337
|
+
if (this._animation.play) {
|
|
338
|
+
this._animation.play();
|
|
339
|
+
}
|
|
340
|
+
this.play();
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Returns whether a particular animation is available.
|
|
345
|
+
*
|
|
346
|
+
* @method platypus.PIXIAnimation#has
|
|
347
|
+
* @param animation {string} The animation to check.
|
|
348
|
+
*/
|
|
349
|
+
has (animation) {
|
|
350
|
+
return !!this._animations[animation];
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Stops the PIXIAnimation and destroys it
|
|
355
|
+
*
|
|
356
|
+
* @method platypus.PIXIAnimation#destroy
|
|
357
|
+
*/
|
|
358
|
+
destroy () {
|
|
359
|
+
this.stop();
|
|
360
|
+
if (this._animation?.stop) {
|
|
361
|
+
this._animation.stop();
|
|
362
|
+
}
|
|
363
|
+
super.destroy();
|
|
364
|
+
if (this.cacheId) {
|
|
365
|
+
const
|
|
366
|
+
cachedAnimation = animationCache[this.cacheId];
|
|
367
|
+
|
|
368
|
+
cachedAnimation.viable -= 1;
|
|
369
|
+
if (cachedAnimation.viable <= 0) {
|
|
370
|
+
arrayCache.recycle(cachedAnimation.textures);
|
|
371
|
+
|
|
372
|
+
const
|
|
373
|
+
animations = cachedAnimation.animations,
|
|
374
|
+
keys = Object.keys(animations),
|
|
375
|
+
{length} = keys;
|
|
376
|
+
|
|
377
|
+
for (let i = 0; i < length; i++) {
|
|
378
|
+
const
|
|
379
|
+
key = keys[i];
|
|
380
|
+
|
|
381
|
+
arrayCache.recycle(animations[key].frames);
|
|
382
|
+
}
|
|
383
|
+
delete animationCache[this.cacheId];
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
static get EmptySpriteSheet () {
|
|
389
|
+
return {
|
|
390
|
+
framerate: 60,
|
|
391
|
+
frames: [],
|
|
392
|
+
images: [],
|
|
393
|
+
animations: {},
|
|
394
|
+
recycleSpriteSheet: function () {
|
|
395
|
+
// We don't recycle this sprite sheet.
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* This method formats a provided value into a valid PIXIAnimation Sprite Sheet. This includes accepting the EaselJS spec, strings mapping to Platypus sprite sheets, or arrays of either.
|
|
402
|
+
*
|
|
403
|
+
* @method platypus.PIXIAnimation.formatSpriteSheet
|
|
404
|
+
* @param spriteSheet {String|Array|Object} The value to cast to a valid Sprite Sheet.
|
|
405
|
+
* @return {Object}
|
|
406
|
+
*/
|
|
407
|
+
static formatSpriteSheet (spriteSheet) {
|
|
408
|
+
const
|
|
409
|
+
imageParts = /([\w-\.]+)\.(\w+)$/,
|
|
410
|
+
addAnimations = function (source = {}, destination, speedRatio, firstFrameIndex, id) {
|
|
411
|
+
const
|
|
412
|
+
keys = Object.keys(source),
|
|
413
|
+
{length} = keys;
|
|
414
|
+
|
|
415
|
+
for (let i = 0; i < length; i++) {
|
|
416
|
+
const
|
|
417
|
+
key = keys[i];
|
|
418
|
+
|
|
419
|
+
if (destination[key]) {
|
|
420
|
+
arrayCache.recycle(destination[key].frames);
|
|
421
|
+
destination[key].recycle();
|
|
422
|
+
platypus.debug.log('PIXIAnimation "' + id + '": Overwriting duplicate animation for "' + key + '".');
|
|
423
|
+
}
|
|
424
|
+
destination[key] = formatAnimation(key, source[key], speedRatio, firstFrameIndex);
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
addFrameObject = function (source, destination, firstImageIndex, bases) {
|
|
428
|
+
const
|
|
429
|
+
{width, height, regX = 0, regY = 0} = source;
|
|
430
|
+
|
|
431
|
+
for (let i = 0; i < bases.length; i++) {
|
|
432
|
+
// Subtract the size of a frame so that margin slivers aren't returned as frames.
|
|
433
|
+
const
|
|
434
|
+
base = bases[i],
|
|
435
|
+
w = base.realWidth - width,
|
|
436
|
+
h = base.realHeight - height;
|
|
437
|
+
|
|
438
|
+
for (let y = 0; y <= h; y += height) {
|
|
439
|
+
for (let x = 0; x <= w; x += width) {
|
|
440
|
+
destination.push([x, y, width, height, i + firstImageIndex, regX, regY]);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
addFrameArray = function (source, destination, firstImageIndex) {
|
|
446
|
+
for (let i = 0; i < source.length; i++) {
|
|
447
|
+
const
|
|
448
|
+
frame = source[i];
|
|
449
|
+
|
|
450
|
+
destination.push(arrayCache.setUp(
|
|
451
|
+
frame[0],
|
|
452
|
+
frame[1],
|
|
453
|
+
frame[2],
|
|
454
|
+
frame[3],
|
|
455
|
+
frame[4] + firstImageIndex,
|
|
456
|
+
frame[5],
|
|
457
|
+
frame[6]
|
|
458
|
+
));
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
createId = (images) => images.map((image) => (image.src ?? image).substring(0, MAX_KEY_LENGTH_PER_IMAGE)).join(','),
|
|
462
|
+
format = function (source, destination) {
|
|
463
|
+
const
|
|
464
|
+
{
|
|
465
|
+
animations: sAnims,
|
|
466
|
+
id: sID,
|
|
467
|
+
images: sImages,
|
|
468
|
+
framerate: sFR = 60,
|
|
469
|
+
frames: sFrames
|
|
470
|
+
} = source,
|
|
471
|
+
{
|
|
472
|
+
animations: dAnims,
|
|
473
|
+
id: dID,
|
|
474
|
+
images: dImages,
|
|
475
|
+
framerate: dFR = 60,
|
|
476
|
+
frames: dFrames
|
|
477
|
+
} = destination,
|
|
478
|
+
images = sImages.map((image) => formatImages(image)),
|
|
479
|
+
firstImageIndex = dImages.length,
|
|
480
|
+
firstFrameIndex = dFrames.length;
|
|
481
|
+
|
|
482
|
+
// Set up id
|
|
483
|
+
if (dID) {
|
|
484
|
+
destination.id = `${dID};${sID ?? createId(sImages)}`;
|
|
485
|
+
} else {
|
|
486
|
+
destination.id = sID ?? createId(sImages);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// Set up images array
|
|
490
|
+
dImages.push(...images);
|
|
491
|
+
|
|
492
|
+
// Set up frames array
|
|
493
|
+
if (Array.isArray(sFrames)) {
|
|
494
|
+
addFrameArray(sFrames, dFrames, firstImageIndex);
|
|
495
|
+
} else {
|
|
496
|
+
const
|
|
497
|
+
bases = getTextureSources(images);
|
|
498
|
+
|
|
499
|
+
addFrameObject(sFrames, dFrames, firstImageIndex, bases);
|
|
500
|
+
arrayCache.recycle(bases);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Set up animations object
|
|
504
|
+
addAnimations(sAnims, dAnims, sFR / dFR, firstFrameIndex, destination.id);
|
|
505
|
+
|
|
506
|
+
arrayCache.recycle(images);
|
|
507
|
+
|
|
508
|
+
return destination;
|
|
509
|
+
},
|
|
510
|
+
formatAnimation = function (key, animation, speedRatio, firstFrameIndex) {
|
|
511
|
+
const
|
|
512
|
+
frames = arrayCache.setUp();
|
|
513
|
+
|
|
514
|
+
if (typeof animation === 'number') {
|
|
515
|
+
frames.push(animation + firstFrameIndex);
|
|
516
|
+
return Data.setUp(
|
|
517
|
+
"frames", frames,
|
|
518
|
+
"next", key,
|
|
519
|
+
"speed", speedRatio
|
|
520
|
+
);
|
|
521
|
+
} else if (Array.isArray(animation)) {
|
|
522
|
+
const
|
|
523
|
+
first = animation[0] ?? 0,
|
|
524
|
+
last = (animation[1] ?? first) + 1 + firstFrameIndex,
|
|
525
|
+
offsetFirst = first + firstFrameIndex;
|
|
526
|
+
|
|
527
|
+
for (let i = offsetFirst; i < last; i++) {
|
|
528
|
+
frames.push(i);
|
|
529
|
+
}
|
|
530
|
+
return Data.setUp(
|
|
531
|
+
"frames", frames,
|
|
532
|
+
"next", animation[2] || key,
|
|
533
|
+
"speed", (animation[3] || 1) * speedRatio
|
|
534
|
+
);
|
|
535
|
+
} else {
|
|
536
|
+
for (let i = 0; i < animation.frames.length; i++) {
|
|
537
|
+
frames.push(animation.frames[i] + firstFrameIndex);
|
|
538
|
+
}
|
|
539
|
+
return Data.setUp(
|
|
540
|
+
"frames", frames,
|
|
541
|
+
"next", animation.next || key,
|
|
542
|
+
"speed", (animation.speed || 1) * speedRatio
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
formatImages = function (name) {
|
|
547
|
+
if (typeof name === 'string') {
|
|
548
|
+
const
|
|
549
|
+
match = name.match(imageParts);
|
|
550
|
+
|
|
551
|
+
if (match) {
|
|
552
|
+
return match[1];
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
return name;
|
|
557
|
+
},
|
|
558
|
+
recycle = function () {
|
|
559
|
+
const
|
|
560
|
+
animations = this.animations,
|
|
561
|
+
keys = Object.keys(animations),
|
|
562
|
+
{length} = keys;
|
|
563
|
+
|
|
564
|
+
for (let i = 0; i < length; i++) {
|
|
565
|
+
const
|
|
566
|
+
key = keys[i];
|
|
567
|
+
|
|
568
|
+
arrayCache.recycle(animations[key].frames);
|
|
569
|
+
animations[key].recycle();
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
arrayCache.recycle(this.frames, 2);
|
|
573
|
+
this.frames = null;
|
|
574
|
+
arrayCache.recycle(this.images);
|
|
575
|
+
this.images = null;
|
|
576
|
+
this.recycle();
|
|
577
|
+
},
|
|
578
|
+
merge = function (spriteSheets, destination) {
|
|
579
|
+
let i = spriteSheets.length;
|
|
580
|
+
|
|
581
|
+
while (i--) {
|
|
582
|
+
let ss = spriteSheets[i];
|
|
583
|
+
|
|
584
|
+
if (typeof ss === 'string') {
|
|
585
|
+
ss = platypus.game.settings.spriteSheets[ss];
|
|
586
|
+
}
|
|
587
|
+
if (ss) {
|
|
588
|
+
format(ss, destination);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
return destination;
|
|
593
|
+
};
|
|
594
|
+
let response = PIXIAnimation.EmptySpriteSheet,
|
|
595
|
+
ss = spriteSheet;
|
|
596
|
+
|
|
597
|
+
if (typeof ss === 'string') {
|
|
598
|
+
ss = platypus.game.settings.spriteSheets[spriteSheet];
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
if (ss) {
|
|
602
|
+
response = Data.setUp(
|
|
603
|
+
"animations", Data.setUp(),
|
|
604
|
+
"framerate", 60,
|
|
605
|
+
"frames", arrayCache.setUp(),
|
|
606
|
+
"id", '',
|
|
607
|
+
"images", arrayCache.setUp(),
|
|
608
|
+
"recycleSpriteSheet", recycle
|
|
609
|
+
);
|
|
610
|
+
|
|
611
|
+
if (Array.isArray(ss)) {
|
|
612
|
+
return merge(ss, response);
|
|
613
|
+
} else if (ss) {
|
|
614
|
+
return format(ss, response);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
return response;
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
|
|
622
|
+
export default PIXIAnimation;
|