@melonjs/spine-plugin 1.4.0 → 1.5.0
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 +13 -1
- package/README.md +34 -12
- package/dist/@melonjs/spine-plugin.d.ts +162 -57
- package/dist/@melonjs/spine-plugin.js +315 -218
- package/package.json +8 -8
- package/src/AssetManager.js +74 -13
- package/src/SpinePlugin.js +24 -0
- package/src/index.js +123 -75
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@melonjs/spine-plugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "melonJS Spine plugin",
|
|
5
5
|
"homepage": "https://github.com/melonjs/spine-plugin#readme",
|
|
6
6
|
"type": "module",
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
"CHANGELOG.md"
|
|
47
47
|
],
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"melonjs": "^15.
|
|
49
|
+
"melonjs": "^15.12.0"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@esotericsoftware/spine-canvas": "^4.2.
|
|
53
|
-
"@esotericsoftware/spine-core": "^4.2.
|
|
54
|
-
"@esotericsoftware/spine-webgl": "^4.2.
|
|
52
|
+
"@esotericsoftware/spine-canvas": "^4.2.23",
|
|
53
|
+
"@esotericsoftware/spine-core": "^4.2.23",
|
|
54
|
+
"@esotericsoftware/spine-webgl": "^4.2.23"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@babel/eslint-parser": "^7.22.15",
|
|
@@ -61,9 +61,9 @@
|
|
|
61
61
|
"@rollup/plugin-node-resolve": "^15.2.1",
|
|
62
62
|
"@rollup/plugin-replace": "^5.0.2",
|
|
63
63
|
"del-cli": "^5.1.0",
|
|
64
|
-
"eslint": "^8.
|
|
65
|
-
"eslint-plugin-jsdoc": "^46.
|
|
66
|
-
"rollup": "^3.
|
|
64
|
+
"eslint": "^8.50.0",
|
|
65
|
+
"eslint-plugin-jsdoc": "^46.8.2",
|
|
66
|
+
"rollup": "^3.29.2",
|
|
67
67
|
"rollup-plugin-bundle-size": "^1.0.3",
|
|
68
68
|
"typescript": "^5.2.2"
|
|
69
69
|
},
|
package/src/AssetManager.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { utils, loader } from "melonjs";
|
|
2
2
|
import * as spineWebGL from "@esotericsoftware/spine-webgl";
|
|
3
3
|
import * as spineCanvas from "@esotericsoftware/spine-canvas";
|
|
4
4
|
|
|
@@ -11,18 +11,46 @@ export default class AssetManager {
|
|
|
11
11
|
pathPrefix;
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
+
* @param {CanvasRenderer|WebGLRenderer} renderer - a melonJS renderer instance
|
|
14
15
|
* @param {string} [pathPrefix=""] - a default path prefix for assets location
|
|
15
16
|
*/
|
|
16
|
-
constructor(pathPrefix = "") {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
constructor(renderer, pathPrefix = "") {
|
|
18
|
+
this.pathPrefix = pathPrefix;
|
|
19
|
+
if (renderer.WebGLVersion >= 1) {
|
|
20
|
+
this.asset_manager = new spineWebGL.AssetManager(renderer.getContext(), this.pathPrefix);
|
|
21
|
+
} else {
|
|
22
|
+
// canvas renderer
|
|
23
|
+
this.asset_manager = new spineCanvas.AssetManager(this.pathPrefix);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// set the spine custom parser
|
|
27
|
+
loader.setParser("spine", (data, onload, onerror) => {
|
|
28
|
+
// decompose data.src for the spine loader
|
|
29
|
+
const ext = utils.file.getExtension(data.src);
|
|
30
|
+
const basename = utils.file.getBasename(data.src);
|
|
31
|
+
const path = utils.file.getPath(data.src);
|
|
32
|
+
const filename = basename + "." + ext;
|
|
33
|
+
|
|
34
|
+
this.setPrefix(path);
|
|
35
|
+
|
|
36
|
+
// load asset
|
|
37
|
+
switch (ext) {
|
|
38
|
+
case "atlas":
|
|
39
|
+
this.loadTextureAtlas(filename, onload, onerror);
|
|
40
|
+
break;
|
|
41
|
+
case "json":
|
|
42
|
+
this.loadText(filename, onload, onerror);
|
|
43
|
+
break;
|
|
44
|
+
case "skel":
|
|
45
|
+
this.loadBinary(filename, onload, onerror);
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
throw "Spine plugin: unknown extension when preloading spine assets";
|
|
24
49
|
}
|
|
50
|
+
|
|
51
|
+
return 1;
|
|
25
52
|
});
|
|
53
|
+
|
|
26
54
|
}
|
|
27
55
|
|
|
28
56
|
/**
|
|
@@ -41,23 +69,48 @@ export default class AssetManager {
|
|
|
41
69
|
* @param {string} atlas
|
|
42
70
|
* @param {string} skel
|
|
43
71
|
* @example
|
|
44
|
-
* // load spine assets
|
|
72
|
+
* // "manually" load spine assets
|
|
45
73
|
* Spine.assetManager.setPrefix("data/spine/");
|
|
46
74
|
* Spine.assetManager.loadAsset("alien.atlas", "alien-ess.json");
|
|
47
75
|
* await Spine.assetManager.loadAll();
|
|
48
76
|
*/
|
|
49
77
|
loadAsset(atlas, skel) {
|
|
50
78
|
if (atlas) {
|
|
51
|
-
this.
|
|
79
|
+
this.loadTextureAtlas(atlas);
|
|
52
80
|
}
|
|
53
81
|
|
|
54
82
|
if (skel.endsWith(".skel")) {
|
|
55
|
-
this.
|
|
83
|
+
this.loadBinary(skel);
|
|
56
84
|
} else {
|
|
57
|
-
this.
|
|
85
|
+
this.loadText(skel);
|
|
58
86
|
}
|
|
59
87
|
}
|
|
60
88
|
|
|
89
|
+
/**
|
|
90
|
+
* load the given texture atlas
|
|
91
|
+
* @param {string} atlas
|
|
92
|
+
*/
|
|
93
|
+
loadTextureAtlas(atlas, onload, onerror) {
|
|
94
|
+
return this.asset_manager.loadTextureAtlas(atlas, onload, onerror);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* load the given skeleton .skel file
|
|
100
|
+
* @param {string} skel
|
|
101
|
+
*/
|
|
102
|
+
loadBinary(skel, onload, onerror) {
|
|
103
|
+
return this.asset_manager.loadBinary(skel, onload, onerror);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* load the given skeleton binary file
|
|
108
|
+
* @param {string} skel
|
|
109
|
+
*/
|
|
110
|
+
loadText(skel, onload, onerror) {
|
|
111
|
+
return this.asset_manager.loadText(skel, onload, onerror);
|
|
112
|
+
}
|
|
113
|
+
|
|
61
114
|
/**
|
|
62
115
|
* load all defined spine assets
|
|
63
116
|
* @see loadAsset
|
|
@@ -65,4 +118,12 @@ export default class AssetManager {
|
|
|
65
118
|
loadAll() {
|
|
66
119
|
return this.asset_manager.loadAll();
|
|
67
120
|
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* get the loaded skeleton data
|
|
124
|
+
* @param {string} path
|
|
125
|
+
*/
|
|
126
|
+
require(path) {
|
|
127
|
+
return this.asset_manager.require(path);
|
|
128
|
+
}
|
|
68
129
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { plugin } from "melonjs";
|
|
2
|
+
import { name, version, dependencies, homepage, peerDependencies } from "../package.json";
|
|
3
|
+
import AssetManager from "./AssetManager";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @classdesc
|
|
7
|
+
* a Spine 4.x plugin implementation for melonJS
|
|
8
|
+
* @augments plugin.BasePlugin
|
|
9
|
+
*/
|
|
10
|
+
export class SpinePlugin extends plugin.BasePlugin {
|
|
11
|
+
constructor() {
|
|
12
|
+
// call the super constructor
|
|
13
|
+
super();
|
|
14
|
+
|
|
15
|
+
// minimum melonJS version expected to run this plugin
|
|
16
|
+
this.version = peerDependencies["melonjs"];
|
|
17
|
+
|
|
18
|
+
// hello world
|
|
19
|
+
console.log(`${name} ${version} - spine runtime ${dependencies["@esotericsoftware/spine-core"]} | ${homepage}`);
|
|
20
|
+
|
|
21
|
+
// instantiate the asset manager
|
|
22
|
+
this.assetManager = new AssetManager(this.app.renderer);
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/index.js
CHANGED
|
@@ -1,67 +1,55 @@
|
|
|
1
|
-
import { Math, Renderable, Vector2d,
|
|
1
|
+
import { Math, Renderable, Vector2d, plugin } from "melonjs";
|
|
2
2
|
import * as spineWebGL from "@esotericsoftware/spine-webgl";
|
|
3
3
|
import * as spineCanvas from "@esotericsoftware/spine-canvas";
|
|
4
4
|
import { Vector2 } from "@esotericsoftware/spine-core";
|
|
5
5
|
|
|
6
|
-
import AssetManager from "./AssetManager.js";
|
|
7
6
|
import SkeletonRenderer from "./SkeletonRenderer.js";
|
|
7
|
+
import { SpinePlugin } from "./SpinePlugin.js";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export let assetManager = new AssetManager();
|
|
12
|
-
|
|
13
|
-
// a custom Spine parser for melonJS preloader
|
|
14
|
-
function spineParser(data, onload, onerror) {
|
|
15
|
-
|
|
16
|
-
// decompose data.src for the spine loader
|
|
17
|
-
const ext = utils.file.getExtension(data.src);
|
|
18
|
-
const basename = utils.file.getBasename(data.src);
|
|
19
|
-
const path = utils.file.getPath(data.src);
|
|
20
|
-
const filename = basename + "." + ext;
|
|
21
|
-
|
|
22
|
-
// set url prefix
|
|
23
|
-
assetManager.setPrefix(path);
|
|
24
|
-
|
|
25
|
-
// load asset
|
|
26
|
-
switch (ext) {
|
|
27
|
-
case "atlas":
|
|
28
|
-
assetManager.asset_manager.loadTextureAtlas(filename, onload, onerror);
|
|
29
|
-
break;
|
|
30
|
-
case "json":
|
|
31
|
-
assetManager.asset_manager.loadText(filename, onload, onerror);
|
|
32
|
-
break;
|
|
33
|
-
case "skel":
|
|
34
|
-
assetManager.asset_manager.loadBinary(filename, onload, onerror);
|
|
35
|
-
break;
|
|
36
|
-
default:
|
|
37
|
-
throw "Spine plugin: unknown extension when preloading spine assets";
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return 1;
|
|
41
|
-
}
|
|
9
|
+
export { SpinePlugin } from "./SpinePlugin.js";
|
|
42
10
|
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// hello world
|
|
47
|
-
event.once(event.VIDEO_INIT, () => {
|
|
48
|
-
console.log(`${name} ${version} - spine runtime ${dependencies["@esotericsoftware/spine-core"]} | ${homepage}`);
|
|
49
|
-
});
|
|
11
|
+
// a temporary array used for skeleton.getBounds();
|
|
12
|
+
let tempArray = [];
|
|
50
13
|
|
|
51
14
|
/**
|
|
52
15
|
* @classdesc
|
|
53
|
-
* An object to
|
|
16
|
+
* An renderable object to render Spine animated skeleton.
|
|
54
17
|
* @augments Renderable
|
|
55
18
|
*/
|
|
56
19
|
export default class Spine extends Renderable {
|
|
57
20
|
runtime;
|
|
58
21
|
skeleton;
|
|
22
|
+
plugin;
|
|
23
|
+
renderer;
|
|
59
24
|
animationState;
|
|
60
25
|
skeletonRenderer;
|
|
61
|
-
assetManager;
|
|
62
26
|
root;
|
|
63
27
|
boneOffset;
|
|
64
28
|
boneSize;
|
|
29
|
+
isSpineFlipped = {
|
|
30
|
+
x : false,
|
|
31
|
+
y : false
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Stores settings and other state for the playback of the current animation (if any).
|
|
36
|
+
* @type {TrackEntry}
|
|
37
|
+
* @see http://en.esotericsoftware.com/spine-api-reference#TrackEntry
|
|
38
|
+
* @see setAnimation
|
|
39
|
+
* @default undefined
|
|
40
|
+
* @example
|
|
41
|
+
* // set a default animation to "run"
|
|
42
|
+
* this.setAnimation(0, "run", true);
|
|
43
|
+
* ...
|
|
44
|
+
* ...
|
|
45
|
+
* // pause the animation
|
|
46
|
+
* this.currentTrack.timeScale = 0;
|
|
47
|
+
* ...
|
|
48
|
+
* ...
|
|
49
|
+
* // resume the animation
|
|
50
|
+
* this.currentTrack.timeScale = 1;
|
|
51
|
+
*/
|
|
52
|
+
currentTrack;
|
|
65
53
|
|
|
66
54
|
/**
|
|
67
55
|
* @param {number} x - the x coordinates of the Spine object
|
|
@@ -100,13 +88,19 @@ export default class Spine extends Renderable {
|
|
|
100
88
|
constructor(x, y, settings) {
|
|
101
89
|
super(x, y, settings.width, settings.height);
|
|
102
90
|
|
|
103
|
-
|
|
91
|
+
// ensure plugin was properly registered
|
|
92
|
+
this.plugin = plugin.get(SpinePlugin);
|
|
93
|
+
if (typeof this.plugin === "undefined") {
|
|
94
|
+
throw "Spine plugin: plugin needs to be registered first using plugin.register";
|
|
95
|
+
}
|
|
96
|
+
this.renderer = this.plugin.app.renderer;
|
|
97
|
+
|
|
98
|
+
if (this.renderer.WebGLVersion >= 1) {
|
|
104
99
|
this.runtime = spineWebGL;
|
|
105
100
|
} else {
|
|
106
101
|
this.runtime = spineCanvas;
|
|
107
102
|
}
|
|
108
103
|
|
|
109
|
-
this.assetManager = assetManager.asset_manager;
|
|
110
104
|
this.skeletonRenderer = new SkeletonRenderer(this.runtime);
|
|
111
105
|
|
|
112
106
|
// force anchorPoint to 0,0
|
|
@@ -165,15 +159,15 @@ export default class Spine extends Renderable {
|
|
|
165
159
|
*/
|
|
166
160
|
setSkeleton(atlasFile, jsonFile) {
|
|
167
161
|
// Create the texture atlas and skeleton data.
|
|
168
|
-
let atlas = this.assetManager.require(atlasFile);
|
|
162
|
+
let atlas = this.plugin.assetManager.require(atlasFile);
|
|
169
163
|
let atlasLoader = new this.runtime.AtlasAttachmentLoader(atlas);
|
|
170
164
|
let skeletonJson = new this.runtime.SkeletonJson(atlasLoader);
|
|
171
|
-
let skeletonData = skeletonJson.readSkeletonData(this.assetManager.require(jsonFile));
|
|
165
|
+
let skeletonData = skeletonJson.readSkeletonData(this.plugin.assetManager.require(jsonFile));
|
|
172
166
|
|
|
173
167
|
// Instantiate a new skeleton based on the atlas and skeleton data.
|
|
174
168
|
this.skeleton = new this.runtime.Skeleton(skeletonData);
|
|
175
|
-
|
|
176
|
-
this.
|
|
169
|
+
|
|
170
|
+
this.setToSetupPose();
|
|
177
171
|
|
|
178
172
|
// Setup an animation state with a default mix of 0.2 seconds.
|
|
179
173
|
var animationStateData = new this.runtime.AnimationStateData(this.skeleton.data);
|
|
@@ -182,11 +176,34 @@ export default class Spine extends Renderable {
|
|
|
182
176
|
|
|
183
177
|
// get a reference to the root bone
|
|
184
178
|
this.root = this.skeleton.getRootBone();
|
|
185
|
-
|
|
186
|
-
this.root.scaleY *= -1;
|
|
179
|
+
}
|
|
187
180
|
|
|
188
|
-
|
|
189
|
-
|
|
181
|
+
/**
|
|
182
|
+
* flip the Spine skeleton on the horizontal axis (around its center)
|
|
183
|
+
* @param {boolean} [flip=true] - `true` to flip this Spine object.
|
|
184
|
+
* @returns {Spine} Reference to this object for method chaining
|
|
185
|
+
*/
|
|
186
|
+
flipX(flip = true) {
|
|
187
|
+
if (this.isSpineFlipped.x !== flip) {
|
|
188
|
+
this.isSpineFlipped.x = flip;
|
|
189
|
+
this.root.scaleX *= -1;
|
|
190
|
+
this.isDirty = true;
|
|
191
|
+
}
|
|
192
|
+
return this;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* flip the Spine skeleton on the vertical axis (around its center)
|
|
197
|
+
* @param {boolean} [flip=true] - `true` to flip this Spine object.
|
|
198
|
+
* @returns {Spine} Reference to this object for method chaining
|
|
199
|
+
*/
|
|
200
|
+
flipY(flip = true) {
|
|
201
|
+
if (this.isSpineFlipped.y !== flip) {
|
|
202
|
+
this.isSpineFlipped.y = flip;
|
|
203
|
+
this.root.scaleY *= -1;
|
|
204
|
+
this.isDirty = true;
|
|
205
|
+
}
|
|
206
|
+
return this;
|
|
190
207
|
}
|
|
191
208
|
|
|
192
209
|
/**
|
|
@@ -235,13 +252,16 @@ export default class Spine extends Renderable {
|
|
|
235
252
|
let boneOffset = this.boneOffset;
|
|
236
253
|
let boneSize = this.boneSize;
|
|
237
254
|
|
|
238
|
-
this.skeleton.getBounds(boneOffset, boneSize);
|
|
255
|
+
this.skeleton.getBounds(boneOffset, boneSize, tempArray);
|
|
256
|
+
|
|
257
|
+
let minX = boneOffset.x - rootBone.x,
|
|
258
|
+
minY = boneOffset.y - rootBone.y;
|
|
239
259
|
|
|
240
260
|
bounds.addFrame(
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
261
|
+
minX,
|
|
262
|
+
minY,
|
|
263
|
+
minX + boneSize.x,
|
|
264
|
+
minY + boneSize.y,
|
|
245
265
|
!isIdentity ? this.currentTransform : undefined
|
|
246
266
|
);
|
|
247
267
|
} else {
|
|
@@ -256,6 +276,7 @@ export default class Spine extends Renderable {
|
|
|
256
276
|
|
|
257
277
|
if (absolute === true) {
|
|
258
278
|
var absPos = this.getAbsolutePosition();
|
|
279
|
+
//bounds.translate(absPos.x, absPos.y);
|
|
259
280
|
bounds.centerOn(absPos.x + bounds.centerX, absPos.y + bounds.centerY);
|
|
260
281
|
}
|
|
261
282
|
return bounds;
|
|
@@ -275,22 +296,24 @@ export default class Spine extends Renderable {
|
|
|
275
296
|
update(dt) {
|
|
276
297
|
if (typeof this.skeleton !== "undefined") {
|
|
277
298
|
let rootBone = this.skeleton.getRootBone();
|
|
278
|
-
|
|
279
|
-
// update the root bone position
|
|
280
|
-
if (rootBone.x !== this.pos.x) {
|
|
281
|
-
rootBone.x = this.pos.x;
|
|
282
|
-
}
|
|
283
|
-
if (rootBone.y !== this.pos.y) {
|
|
284
|
-
rootBone.y = this.pos.y;
|
|
285
|
-
}
|
|
299
|
+
//let height = this.renderer.getHeight();
|
|
286
300
|
|
|
287
301
|
// Update and apply the animation state, update the skeleton's
|
|
288
|
-
// world transforms and render the skeleton.
|
|
289
302
|
this.animationState.update(dt / 1000);
|
|
290
303
|
this.animationState.apply(this.skeleton);
|
|
304
|
+
|
|
305
|
+
// update the root bone position
|
|
306
|
+
rootBone.x = this.pos.x;
|
|
307
|
+
rootBone.y = this.pos.y;
|
|
308
|
+
|
|
309
|
+
// world transforms
|
|
291
310
|
this.skeleton.updateWorldTransform();
|
|
292
311
|
|
|
312
|
+
// update Bounds
|
|
293
313
|
this.updateBounds();
|
|
314
|
+
|
|
315
|
+
// world transforms
|
|
316
|
+
//this.skeleton.updateWorldTransform();
|
|
294
317
|
}
|
|
295
318
|
return true;
|
|
296
319
|
}
|
|
@@ -310,13 +333,13 @@ export default class Spine extends Renderable {
|
|
|
310
333
|
* @param {number} [track_index] - If the formerly current track entry was never applied to a skeleton, it is replaced (not mixed from). In either case trackEnd determines when the track is cleared.
|
|
311
334
|
* @param {number} [index] - the animation index
|
|
312
335
|
* @param {boolean} [loop= false] - If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its duration.
|
|
313
|
-
* @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept after the dispose event occurs.
|
|
336
|
+
* @returns {TrackEntry} A track entry to allow further customization of animation playback. References to the track entry must not be kept after the dispose event occurs.
|
|
314
337
|
*/
|
|
315
338
|
setAnimationByIndex(track_index, index, loop = false) {
|
|
316
339
|
if (index < 0 || index >= this.skeleton.data.animations.length) {
|
|
317
340
|
return (console.log("Animation Index not found"));
|
|
318
341
|
} else {
|
|
319
|
-
this.
|
|
342
|
+
return this.setAnimation(track_index, this.skeleton.data.animations[index].name, loop);
|
|
320
343
|
}
|
|
321
344
|
}
|
|
322
345
|
|
|
@@ -325,25 +348,40 @@ export default class Spine extends Renderable {
|
|
|
325
348
|
* @param {number} [track_index] - If the formerly current track entry was never applied to a skeleton, it is replaced (not mixed from). In either case trackEnd determines when the track is cleared.
|
|
326
349
|
* @param {string} [name] - the animation name
|
|
327
350
|
* @param {boolean} [loop= false] - If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its duration.
|
|
328
|
-
* @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept after the dispose event occurs.
|
|
351
|
+
* @returns {TrackEntry} A track entry to allow further customization of animation playback. References to the track entry must not be kept after the dispose event occurs.
|
|
329
352
|
* @example
|
|
330
353
|
* // set the current animation
|
|
331
354
|
* spineAlien.setAnimation(0, "death", true);
|
|
332
355
|
*/
|
|
333
356
|
setAnimation(track_index, name, loop = false) {
|
|
334
|
-
this.animationState.setAnimation(track_index, name, loop);
|
|
357
|
+
this.currentTrack = this.animationState.setAnimation(track_index, name, loop);
|
|
358
|
+
return this.currentTrack;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* return true if the given animation name is the current running animation for the current track.
|
|
363
|
+
* @name isCurrentAnimation
|
|
364
|
+
* @param {string} name - animation name
|
|
365
|
+
* @returns {boolean}
|
|
366
|
+
* @example
|
|
367
|
+
* if (!this.isCurrentAnimation("death")) {
|
|
368
|
+
* // do something funny...
|
|
369
|
+
* }
|
|
370
|
+
*/
|
|
371
|
+
isCurrentAnimation(name) {
|
|
372
|
+
return typeof this.currentTrack !== "undefined" && this.currentTrack.animation.name === name;
|
|
335
373
|
}
|
|
336
374
|
|
|
337
375
|
/**
|
|
338
376
|
* Adds an animation to be played after the current or last queued animation for a track, and sets the track entry's mixDuration.
|
|
339
377
|
* @param {number} [delay=0] - If > 0, sets delay. If <= 0, the delay set is the duration of the previous track entry minus any mix duration plus the specified `delay` (ie the mix ends at (`delay` = 0) or before (`delay` < 0) the previous track entry duration). If the previous entry is looping, its next loop completion is used instead of its duration.
|
|
340
|
-
* @return A track entry to allow further customization of animation playback. References to the track entry must not be kept after the dispose} event occurs.
|
|
378
|
+
* @return {TrackEntry} A track entry to allow further customization of animation playback. References to the track entry must not be kept after the dispose} event occurs.
|
|
341
379
|
*/
|
|
342
380
|
addAnimationByIndex(track_index, index, loop = false, delay = 0) {
|
|
343
381
|
if (index < 0 || index >= this.skeleton.data.animations.length) {
|
|
344
382
|
return (console.log("Animation Index not found"));
|
|
345
383
|
} else {
|
|
346
|
-
this.
|
|
384
|
+
return this.addAnimation(track_index, this.skeleton.data.animations[index].name, loop, delay);
|
|
347
385
|
}
|
|
348
386
|
}
|
|
349
387
|
|
|
@@ -403,9 +441,19 @@ export default class Spine extends Renderable {
|
|
|
403
441
|
}
|
|
404
442
|
|
|
405
443
|
/**
|
|
406
|
-
*
|
|
444
|
+
* Reset this slot to the setup pose.
|
|
407
445
|
*/
|
|
408
446
|
setToSetupPose() {
|
|
409
447
|
this.skeleton.setToSetupPose();
|
|
448
|
+
// Spine uses Y-up, melonJS uses Y-down
|
|
449
|
+
this.skeleton.getRootBone().scaleY *= -1;
|
|
450
|
+
this.skeleton.updateWorldTransform();
|
|
451
|
+
// reset flip flags
|
|
452
|
+
this.isSpineFlipped.y = false;
|
|
453
|
+
this.isSpineFlipped.x = false;
|
|
454
|
+
// reset reference to current track entry
|
|
455
|
+
this.currentTrack = undefined;
|
|
456
|
+
// mark the object as dirty
|
|
457
|
+
this.isDirty = true;
|
|
410
458
|
}
|
|
411
459
|
}
|