Skip to content

Commit 62c03f6

Browse files
committed
AsepriteFile is a new File Type for the Loader that allows you to load Aseprite images and animation data for use with the new Aseprite animation features. You can call this via this.load.asesprite(png, json).
1 parent 2c36126 commit 62c03f6

3 files changed

Lines changed: 276 additions & 0 deletions

File tree

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
/**
2+
* @author Richard Davey <rich@photonstorm.com>
3+
* @copyright 2020 Photon Storm Ltd.
4+
* @license {@link https://opensource.org/licenses/MIT|MIT License}
5+
*/
6+
7+
var Class = require('../../utils/Class');
8+
var FileTypesManager = require('../FileTypesManager');
9+
var GetFastValue = require('../../utils/object/GetFastValue');
10+
var ImageFile = require('./ImageFile.js');
11+
var IsPlainObject = require('../../utils/object/IsPlainObject');
12+
var JSONFile = require('./JSONFile.js');
13+
var MultiFile = require('../MultiFile.js');
14+
15+
/**
16+
* @classdesc
17+
* A single JSON based Texture Atlas File suitable for loading by the Loader.
18+
*
19+
* These are created when you use the Phaser.Loader.LoaderPlugin#atlas method and are not typically created directly.
20+
*
21+
* For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#atlas.
22+
*
23+
* https://www.codeandweb.com/texturepacker/tutorials/how-to-create-sprite-sheets-for-phaser3?source=photonstorm
24+
*
25+
* @class AsepriteFile
26+
* @extends Phaser.Loader.MultiFile
27+
* @memberof Phaser.Loader.FileTypes
28+
* @constructor
29+
* @since 3.50.0
30+
*
31+
* @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file.
32+
* @param {(string|Phaser.Types.Loader.FileTypes.AsepriteFileConfig)} key - The key to use for this file, or a file configuration object.
33+
* @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `<key>.png`, i.e. if `key` was "alien" then the URL will be "alien.png".
34+
* @param {object|string} [atlasURL] - The absolute or relative URL to load the texture atlas json data file from. If undefined or `null` it will be set to `<key>.json`, i.e. if `key` was "alien" then the URL will be "alien.json". Or, a well formed JSON object.
35+
* @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings.
36+
* @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas json file. Used in replacement of the Loaders default XHR Settings.
37+
*/
38+
var AsepriteFile = new Class({
39+
40+
Extends: MultiFile,
41+
42+
initialize:
43+
44+
function AsepriteFile (loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings)
45+
{
46+
var image;
47+
var data;
48+
49+
if (IsPlainObject(key))
50+
{
51+
var config = key;
52+
53+
key = GetFastValue(config, 'key');
54+
55+
image = new ImageFile(loader, {
56+
key: key,
57+
url: GetFastValue(config, 'textureURL'),
58+
extension: GetFastValue(config, 'textureExtension', 'png'),
59+
normalMap: GetFastValue(config, 'normalMap'),
60+
xhrSettings: GetFastValue(config, 'textureXhrSettings')
61+
});
62+
63+
data = new JSONFile(loader, {
64+
key: key,
65+
url: GetFastValue(config, 'atlasURL'),
66+
extension: GetFastValue(config, 'atlasExtension', 'json'),
67+
xhrSettings: GetFastValue(config, 'atlasXhrSettings')
68+
});
69+
}
70+
else
71+
{
72+
image = new ImageFile(loader, key, textureURL, textureXhrSettings);
73+
data = new JSONFile(loader, key, atlasURL, atlasXhrSettings);
74+
}
75+
76+
if (image.linkFile)
77+
{
78+
// Image has a normal map
79+
MultiFile.call(this, loader, 'atlasjson', key, [ image, data, image.linkFile ]);
80+
}
81+
else
82+
{
83+
MultiFile.call(this, loader, 'atlasjson', key, [ image, data ]);
84+
}
85+
},
86+
87+
/**
88+
* Adds this file to its target cache upon successful loading and processing.
89+
*
90+
* @method Phaser.Loader.FileTypes.AsepriteFile#addToCache
91+
* @since 3.7.0
92+
*/
93+
addToCache: function ()
94+
{
95+
if (this.isReadyToProcess())
96+
{
97+
var image = this.files[0];
98+
var json = this.files[1];
99+
var normalMap = (this.files[2]) ? this.files[2].data : null;
100+
101+
this.loader.textureManager.addAtlas(image.key, image.data, json.data, normalMap);
102+
103+
json.addToCache();
104+
105+
this.complete = true;
106+
}
107+
}
108+
109+
});
110+
111+
/**
112+
* Aseprite is a powerful animated sprite editor and pixel art tool.
113+
*
114+
* You can find more details at https://www.aseprite.org/
115+
*
116+
* Adds a JSON based Aseprite Animation, or array of animations, to the current load queue.
117+
*
118+
* You can call this method from within your Scene's `preload`, along with any other files you wish to load:
119+
*
120+
* ```javascript
121+
* function preload ()
122+
* {
123+
* this.load.aseprite('gladiator', 'images/Gladiator.png', 'images/Gladiator.json');
124+
* }
125+
* ```
126+
*
127+
* The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts,
128+
* or if it's already running, when the next free load slot becomes available. This happens automatically if you
129+
* are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued
130+
* it means you cannot use the file immediately after calling this method, but must wait for the file to complete.
131+
* The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the
132+
* Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been
133+
* loaded.
134+
*
135+
* If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring
136+
* its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details.
137+
*
138+
* To export a compatible JSON file in Aseprite, please do the following:
139+
*
140+
* 1. Go to "File - Export Sprite Sheet"
141+
*
142+
* 2. On the **Layout** tab:
143+
* 2a. Set the "Sheet type" to "Packed"
144+
* 2b. Set the "Constraints" to "None"
145+
* 2c. Check the "Merge Duplicates" checkbox
146+
*
147+
* 3. On the **Sprite** tab:
148+
* 3a. Set "Layers" to "Visible layers"
149+
* 3b. Set "Frames" to "All frames", unless you only wish to export a sub-set of tags
150+
*
151+
* 4. On the **Borders** tab:
152+
* 4a. Check the "Trim Sprite" and "Trim Cells" options
153+
* 4b. Ensure "Border Padding", "Spacing" and "Inner Padding" are all > 0 (1 is usually enough)
154+
*
155+
* 5. On the **Output** tab:
156+
* 5a. Check "Output File", give your image a name and make sure you choose "png files" as the file type
157+
* 5b. Check "JSON Data" and give your json file a name
158+
* 5c. The JSON Data type can be either a Hash or Array, Phaser doesn't mind.
159+
* 5d. Make sure "Tags" is checked in the Meta options
160+
* 5e. In the "Item Filename" input box, make sure it says just "{frame}" and nothing more.
161+
*
162+
* 6. Click export
163+
*
164+
* This was tested with Aseprite 1.2.25.
165+
*
166+
* This will export a png and json file which you can load using the Aseprite Loader, i.e.:
167+
*
168+
* Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle.
169+
*
170+
* The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load.
171+
* The key should be unique both in terms of files being loaded and files already present in the Texture Manager.
172+
* Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file
173+
* then remove it from the Texture Manager first, before loading a new one.
174+
*
175+
* Instead of passing arguments you can pass a configuration object, such as:
176+
*
177+
* ```javascript
178+
* this.load.aseprite({
179+
* key: 'gladiator',
180+
* textureURL: 'images/Gladiator.png',
181+
* atlasURL: 'images/Gladiator.json'
182+
* });
183+
* ```
184+
*
185+
* See the documentation for `Phaser.Types.Loader.FileTypes.AsepriteFileConfig` for more details.
186+
*
187+
* Instead of passing a URL for the JSON data you can also pass in a well formed JSON object instead.
188+
*
189+
* Once loaded, you can call this method from within a Scene with the 'atlas' key:
190+
*
191+
* ```javascript
192+
* this.anims.createFromAseprite('paladin');
193+
* ```
194+
*
195+
* Any animations defined in the JSON will now be available to use in Phaser and you play them
196+
* via their Tag name. For example, if you have an animation called 'War Cry' on your Aseprite timeline,
197+
* you can play it in Phaser using that Tag name:
198+
*
199+
* ```javascript
200+
* this.add.sprite(400, 300).play('War Cry');
201+
* ```
202+
*
203+
* When calling this method you can optionally provide an array of tag names, and only those animations
204+
* will be created. For example:
205+
*
206+
* ```javascript
207+
* this.anims.createFromAseprite('paladin', [ 'step', 'War Cry', 'Magnum Break' ]);
208+
* ```
209+
*
210+
* This will only create the 3 animations defined. Note that the tag names are case-sensitive.
211+
*
212+
* If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files
213+
* key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and
214+
* this is what you would use to retrieve the image from the Texture Manager.
215+
*
216+
* The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it.
217+
*
218+
* If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien"
219+
* and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although
220+
* this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL.
221+
*
222+
* Note: The ability to load this type of file will only be available if the Aseprite File type has been built into Phaser.
223+
* It is available in the default build but can be excluded from custom builds.
224+
*
225+
* @method Phaser.Loader.LoaderPlugin#aseprite
226+
* @fires Phaser.Loader.LoaderPlugin#ADD
227+
* @since 3.50.0
228+
*
229+
* @param {(string|Phaser.Types.Loader.FileTypes.AsepriteFileConfig|Phaser.Types.Loader.FileTypes.AsepriteFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them.
230+
* @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `<key>.png`, i.e. if `key` was "alien" then the URL will be "alien.png".
231+
* @param {object|string} [atlasURL] - The absolute or relative URL to load the texture atlas json data file from. If undefined or `null` it will be set to `<key>.json`, i.e. if `key` was "alien" then the URL will be "alien.json". Or, a well formed JSON object.
232+
* @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings.
233+
* @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas json file. Used in replacement of the Loaders default XHR Settings.
234+
*
235+
* @return {this} The Loader instance.
236+
*/
237+
FileTypesManager.register('aseprite', function (key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings)
238+
{
239+
var multifile;
240+
241+
// Supports an Object file definition in the key argument
242+
// Or an array of objects in the key argument
243+
// Or a single entry where all arguments have been defined
244+
245+
if (Array.isArray(key))
246+
{
247+
for (var i = 0; i < key.length; i++)
248+
{
249+
multifile = new AsepriteFile(this, key[i]);
250+
251+
this.addFile(multifile.files);
252+
}
253+
}
254+
else
255+
{
256+
multifile = new AsepriteFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings);
257+
258+
this.addFile(multifile.files);
259+
}
260+
261+
return this;
262+
});
263+
264+
module.exports = AsepriteFile;

src/loader/filetypes/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
module.exports = {
1212

1313
AnimationJSONFile: require('./AnimationJSONFile'),
14+
AsepriteFile: require('./AsepriteFile'),
1415
AtlasJSONFile: require('./AtlasJSONFile'),
1516
AtlasXMLFile: require('./AtlasXMLFile'),
1617
AudioFile: require('./AudioFile'),
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @typedef {object} Phaser.Types.Loader.FileTypes.AsepriteFileConfig
3+
*
4+
* @property {string} key - The key of the file. Must be unique within both the Loader and the Texture Manager.
5+
* @property {string} [textureURL] - The absolute or relative URL to load the texture image file from.
6+
* @property {string} [textureExtension='png'] - The default file extension to use for the image texture if no url is provided.
7+
* @property {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - Extra XHR Settings specifically for the texture image file.
8+
* @property {object|string} [atlasURL] - The absolute or relative URL to load the atlas json file from. Or, a well formed JSON object to use instead.
9+
* @property {string} [atlasExtension='json'] - The default file extension to use for the atlas json if no url is provided.
10+
* @property {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - Extra XHR Settings specifically for the atlas json file.
11+
*/

0 commit comments

Comments
 (0)