Skip to content

Commit 1a4b5b2

Browse files
committed
AnimationManager.createFromAseprite is a new method that allows you to use animations created in the Aseprite editor directly in Phaser.
1 parent 5db6cba commit 1a4b5b2

1 file changed

Lines changed: 173 additions & 0 deletions

File tree

src/animations/AnimationManager.js

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ var CustomMap = require('../structs/Map');
1010
var EventEmitter = require('eventemitter3');
1111
var Events = require('./events');
1212
var GameEvents = require('../core/events');
13+
var GetFastValue = require('../utils/object/GetFastValue');
1314
var GetValue = require('../utils/object/GetValue');
1415
var Pad = require('../utils/string/Pad');
1516

@@ -168,6 +169,178 @@ var AnimationManager = new Class({
168169
return this.anims.has(key);
169170
},
170171

172+
/**
173+
* Create one, or more animations from a loaded Aseprite JSON file.
174+
*
175+
* Aseprite is a powerful animated sprite editor and pixel art tool.
176+
*
177+
* You can find more details at https://www.aseprite.org/
178+
*
179+
* To export a compatible JSON file in Aseprite, please do the following:
180+
*
181+
* 1. Go to "File - Export Sprite Sheet"
182+
*
183+
* 2. On the **Layout** tab:
184+
* 2a. Set the "Sheet type" to "Packed"
185+
* 2b. Set the "Constraints" to "None"
186+
* 2c. Check the "Merge Duplicates" checkbox
187+
*
188+
* 3. On the **Sprite** tab:
189+
* 3a. Set "Layers" to "Visible layers"
190+
* 3b. Set "Frames" to "All frames", unless you only wish to export a sub-set of tags
191+
*
192+
* 4. On the **Borders** tab:
193+
* 4a. Check the "Trim Sprite" and "Trim Cells" options
194+
* 4b. Ensure "Border Padding", "Spacing" and "Inner Padding" are all > 0 (1 is usually enough)
195+
*
196+
* 5. On the **Output** tab:
197+
* 5a. Check "Output File", give your image a name and make sure you choose "png files" as the file type
198+
* 5b. Check "JSON Data" and give your json file a name
199+
* 5c. The JSON Data type can be either a Hash or Array, Phaser doesn't mind.
200+
* 5d. Make sure "Tags" is checked in the Meta options
201+
* 5e. In the "Item Filename" input box, make sure it says just "{frame}" and nothing more.
202+
*
203+
* 6. Click export
204+
*
205+
* This was tested with Aseprite 1.2.25.
206+
*
207+
* This will export a png and json file which you can load using the Atlas Loader, i.e.:
208+
*
209+
* ```javascript
210+
* function preload ()
211+
* {
212+
* this.load.path = 'assets/animations/aseprite/';
213+
* this.load.atlas('paladin', 'paladin.png', 'paladin.json');
214+
* }
215+
* ```
216+
*
217+
* Once exported, you can call this method from within a Scene with the 'atlas' key:
218+
*
219+
* ```javascript
220+
* this.anims.createFromAseprite('paladin');
221+
* ```
222+
*
223+
* Any animations defined in the JSON will now be available to use in Phaser and you play them
224+
* via their Tag name. For example, if you have an animation called 'War Cry' on your Aseprite timeline,
225+
* you can play it in Phaser using that Tag name:
226+
*
227+
* ```javascript
228+
* this.add.sprite(400, 300).play('War Cry');
229+
* ```
230+
*
231+
* When calling this method you can optionally provide an array of tag names, and only those animations
232+
* will be created. For example:
233+
*
234+
* ```javascript
235+
* this.anims.createFromAseprite('paladin', [ 'step', 'War Cry', 'Magnum Break' ]);
236+
* ```
237+
*
238+
* This will only create the 3 animations defined. Note that the tag names are case-sensitive.
239+
*
240+
* @method Phaser.Animations.AnimationManager#createFromAseprite
241+
* @since 3.50.0
242+
*
243+
* @param {string} key - The key of the loaded Aseprite atlas. It must have been loaded prior to calling this method.
244+
* @param {string[]} [tags] - An array of Tag names. If provided, only animations found in this array will be created.
245+
*
246+
* @return {Phaser.Animations.Animation[]} An array of Animation instances that were successfully created.
247+
*/
248+
createFromAseprite: function (key, tags)
249+
{
250+
var output = [];
251+
252+
var data = this.game.cache.json.get(key);
253+
254+
if (!data)
255+
{
256+
return output;
257+
}
258+
259+
var _this = this;
260+
261+
var meta = GetValue(data, 'meta', null);
262+
var frames = GetValue(data, 'frames', null);
263+
264+
if (meta && frames)
265+
{
266+
var frameTags = GetValue(meta, 'frameTags', []);
267+
268+
frameTags.forEach(function (tag)
269+
{
270+
var animFrames = [];
271+
272+
var name = GetFastValue(tag, 'name', null);
273+
var from = GetFastValue(tag, 'from', 0);
274+
var to = GetFastValue(tag, 'to', 0);
275+
var direction = GetFastValue(tag, 'direction', 'forward');
276+
277+
if (!name)
278+
{
279+
// Skip if no name
280+
return;
281+
}
282+
283+
if (!tags || (tags && tags.indexOf(name) > -1))
284+
{
285+
// Get all the frames for this tag
286+
var tempFrames = [];
287+
var minDuration = Number.MAX_SAFE_INTEGER;
288+
289+
for (var i = from; i <= to; i++)
290+
{
291+
var frameKey = i.toString();
292+
var frame = frames[frameKey];
293+
294+
if (frame)
295+
{
296+
var frameDuration = GetFastValue(frame, 'duration', Number.MAX_SAFE_INTEGER);
297+
298+
if (frameDuration < minDuration)
299+
{
300+
minDuration = frameDuration;
301+
}
302+
303+
tempFrames.push({ frame: frameKey, duration: frameDuration });
304+
}
305+
}
306+
307+
tempFrames.forEach(function (entry)
308+
{
309+
animFrames.push({
310+
key: key,
311+
frame: entry.frame,
312+
duration: (minDuration - entry.duration)
313+
});
314+
});
315+
316+
var totalDuration = (minDuration * animFrames.length);
317+
318+
if (direction === 'reverse')
319+
{
320+
animFrames = animFrames.reverse();
321+
}
322+
323+
// Create the animation
324+
var createConfig = {
325+
key: name,
326+
frames: animFrames,
327+
duration: totalDuration,
328+
yoyo: (direction === 'pingpong')
329+
};
330+
331+
var result = _this.create(createConfig);
332+
333+
if (result)
334+
{
335+
output.push(result);
336+
}
337+
}
338+
});
339+
}
340+
341+
return output;
342+
},
343+
171344
/**
172345
* Creates a new Animation and adds it to the Animation Manager.
173346
*

0 commit comments

Comments
 (0)