Export SWF Animation to NME using Sprite Sheets

Animation is a key to any quality game. The workflow you choose, from design to screen, will not only impact the quality of your end-product, but also the fun you have during development.

I am happy to share a workflow that goes straight from Flash to sprite sheets, and a library for Haxe and NME that takes those sprite sheets and easily places them on-screen. I am very excited about using this process more.

Setup

I have posted the sprite sheet engine I am using on haxelib

haxelib install spritesheet

Inside of the directory, I have included an export directory for use with SpriteLoq. You can either find “nme.meta” in your lib directory after installing “spritesheet”, or you can get a copy of it here. You will want to copy this file to “enabled_export_templates”, where SpriteLoq has been installed on your system. For example, on mine it was at “C:\Program Files (x86)\SpriteLoq”. If you want, you can also remove “corona.meta” from that same directory.

After exporting a sprite sheet from SpriteLoq, you can also use the “Import” command in SpriteLoq to bring it back again. Just import the XML file that is generated from SpriteLoq, and it will repopulate your settings. This is useful if you need to go back and revise an old export, or need to regenerate your sprite sheet after SpriteLoq has been closed.

Sample Project

Once you have SpriteLoq and the “spritesheet” library installed, you can try the sample project. Included in the directory is an FLA with a single animation, the resulting export from SpriteLoq and source code to load, display and animate the shape.

The sprite sheet engine uses a “SpriteSheet” class with data for the image, frames and behaviors, which you can access through an “AnimatedSprite” class. Sprite sheets can be shared among multiple animated sprites, which all have their own timeline. Animated sprites do not have their own timers, so in a frame loop somewhere, you need to update sprites with the “delta time” for their animations.

I decided not to make the animations occur based on absolute real time, because you may decide to freeze objects or pause the entire application. In this way, you can create your own timing offsets to allow for a delta time that creates the animation you are looking for. If objects were based on absolute real time, it would be impossible to pause and resume their animations appropriately.

You do not need to use SpriteLoq in order to take advantage of the sprite sheet engine, but an importer is provided to automate the process from SpriteLoq to your completed SpriteSheet instance in Haxe. The engine is compatible with NME, so you can publish your application to Flash or to C++ targets like Windows, Mac, Linux, iOS, webOS or Android.

Screencast

If you like screencasts, or want to see this for your self, I’ve posted a short screencast that goes from an animation created in Flash, to SpriteLoq to generate the sprite sheets, to Haxe where the sprite sheet engine makes it all come back to life again.

Check it out here and let me know what you think!

  • kommentz

    What the hell is NME?

  • Peter,

    These are some previous posts that may help:

    http://www.joshuagranick.com/blog/2011/07/14/android-ios-webos-and-more-cross-platform-made-easy/
    http://www.joshuagranick.com/blog/2011/08/06/build-your-own-magazine-viewer-with-haxe-nme/
    http://www.joshuagranick.com/blog/2011/08/19/haxe-nme-screencast-is-now-online/

    NME is a cross-platform framework that makes it possible to create native games and applications for Windows, Linux, Mac, iOS, Android, webOS and Flash. Flash applications are created by generating SWF bytecode, and C++ applications for other targets are created in conjuction with a Flash-compatible API, written in C++.

    The end result is that you have games that are written practically like Flash, but go to mobile, desktop and web targets without writing platform conditional code. Because it is native to each target, it performs very well, and it supports a large number of Flash API features, including network requests, bitmaps, drawing commands, some filters and blend modes, mouse and keyboard events, custom fonts and textfields, etc.

    I have created four mobile games and one Facebook game using NME. In my (anecdotal) experience, NME has performed over three times faster than Adobe AIR on mobile, and has made it possible to access native device features and APIs that were not otherwise available.

    If you have more questions, I would be glad to answer them! NME is free and open-source.

  • Like1

  • dmpost

    Joshua,
    thanks for all your posts and tutorials.You just said “possible to access native device features and APIs”.That’s exactly what I looking for, but cannot find an answer yet.How to access native device features in NME app on Android?

  • Hi dmpost,

    If you would like to access native features for your OS, it might be a feature that belongs in the framework 🙂

    Let me know what you intend to do, and maybe it can be integrated into a cross-platform API as a part of NME. Otherwise, it is possible to use your own code, but I need to sit down and try to create a simple template so you have a nice place to start with writing your own code and plugging it into the system.

    Would you want to write C++ code, or Java code? It should be easy (with an example template) to plug in an extra C++ code library. Extra Java code is a little trickier, but again, depending on what you want, maybe it should become part of the core.

  • dmpost

    Joshua,
    thanks for your readiness to help.

    In fact we just need to know that we can access any native feature, before we start a project. To avoid a risk that we may get stuck on some point.

    We are trying to find a way to make cross-Android-iPhone apps, using haXe and FlashDevelop.

    At first we’ve tried Titanium + haXe => JS,
     with the API – http://lib.haxe.org/p/titanium-api
    see tutorial – http://www.blog.visup.it/2010/10/tech/haxe-titanium-targeting-iphoneipad-and-android
    It’s perfect way to make simple applications.

    But later we’ve found that our application is too slow. So we considering the NME + hxcpp. However the API that we see here is not so big and mobile dedicated, as Titanium – http://developer.appcelerator.com/apidoc/mobile/
    So I see two possible solutions:1. Find a way to access any native feature.
    2. Find a way to create NME/hxcpp module for Titanium
    http://developer.appcelerator.com/blog/2011/07/building-apps-with-modules.html
    http://developer.appcelerator.com/doc/mobile/android/module_sdk

    It would be great if you could help.

    Thanks in advance
    Dmitry

  • Redrumnz

    Thanks Joshua 😀

  • Hi Dmitry,

    Were you trying to make a game, or were you trying to make an application?

    If you want to make an application, (not to dissuade you), you may also consider using a Javascript application framework, using PhoneGap to access the native API. It is possible, even, to use Haxe with these types of projects, so you get code completion and error checking, even though you “writing” Javascript (Haxe code compiled to Javascript for mobile applications)

    I intend this week (if possible) to create my own simple template for extending NME with native features. It shouldn’t be hard to do, and if there are any nuisances about the process, I’d like to improve NME to keep it as simple as possible.

    Until then, if you want you can check out HxGK, which extends NME with iOS Game Center functionality as a separate native plugin:

    http://code.google.com/p/hxgk/

    The source is pretty simple. There are source C files, then there is a C file which “exposes” native methods (in the ExternalInterface.cpp file for this library) and then there is a Haxe class which you can reference in your code, which calls those native methods, when appropriate.

    If what you would like to do can be done from C or C++, this should be easier than if it also requires Java. Depending on the functionality, maybe it should be integrated into the core? For example, if you wanted in-app purchase, I think that should probably be integrated in NME as a core cross-platform API. Why not?

    If you want to toy around with the source, it’s bigger than the HxGK example, but you can check it out from here:

    http://code.google.com/p/nekonme

    You would also need the SDL Static library, named “sdl-static” in the same directory as your checkout of “nekonme”

    http://code.google.com/p/sdl-static
     

    It uses a similar structure. Under /project are all the C files for the native NME library. You can compile it by running “haxelib run hxcpp Build.xml -DANDROID” or “-DIPHONE -DIPHONEOS” or “-DIPHONE -DIPHONESIM” or “-DWEBOS”, etc. Running it without a flag will compile for your current desktop OS. The Haxe files are mostly located under /nme, but there are also template files under /install-tool which are used when building projects.

    You probably want to go the HxGK-style route — clean and separate, but technically speaking, NME is open-source, MIT-licensed, so you can take the source and do what you will, or make contributions.

    And, as I mentioned before, I’m planning on making a ready-to-go template this week, or depending on your needs, we might want to add it as a part of the core. Let me know what direction you think makes sense

  • dmpost

    Joshua,
    we trying to make an application, but Javascript is too slow for it sometimes. Yes, I heard about PhoneGap, we’ve considered many mobile cross platfrom solutions. Titanium looks the best (until you don’t need more platforms than just Android and iOS), because of huge mobile API and native features support (and it works perfectly with haXe/JS).

    I’m sure any templates and tutorials in the native approach will be very helpful.

    As for me, I still think that we need to find a way to access the Titanium API from NME app. Because if we access  native features directly we would depend on the platform, right?In Titanium the same call works in both Android and iPhone.Also I’m not an expert in Java/C++. And prefer to use “native calls” indirectly, using Neko, swhx, Titanium API, etc.Thanks for your attention.

  • What sort of application are you building? Is it more of a game or interactive application, or is it more of a data-driven interface type of application?

    I think that NME is a great solution for games, but it might be tricky to use NME with a lot of native controls. All of your code works with GL surfaces, but in order to mix that with native interfaces, you might have to understand the internals of NME pretty well.

    On the other hand, leveraging HXCPP and not NME, it is possible to write Haxe code and have C++ code compiled. If you wanted to compile C code that is accessible to Haxe, it would be possible to create a native interface without having to write C, but the ease of developing such a solution would probably benefit the person who uses it after it is built, maybe not as much the person who has to build it the first time.

    I had trouble with Titanium being slow, both on the device and to compile. I’m not sure if it has changed?

    If I were to make an application today, I would probably use Javascript. Enyo is nice for tablets (and I hope it is open-sourced soon for more platforms) and Jo seems quick and easy to use, and styles easily with CSS.

    All of this is a little easier with webOS, where the native interface IS Javascript and CSS, so you don’t have the issue of not “blending in” with other applications.

    I assume it would be possible to use Haxe with Titanium, so you could write applications with code completion and such. That could be nice… especially if Titanium makes it possible to call their compiler from a command line, rather than having to push the build button. Not sure that has changed?

    So there definitely are multiple options, and hopefully a good path forward, depending on what you want to build. NME works great, but the downside for applications is that it does not have a UI widget set. If you created a design with Photoshop, however, it would be fairly easy to drop in the images and move forward. That would possibly look very native, but might not emulate the same behaviors, if the native UI is very complex.

    Feel free to ask more questions, I would be very glad to help recommend a good path, based on what your needs are!

  • dmpost

    Thanks,
    I will ask more questions later.

    We making a simple applicaton to test the mobile market. So I keep in mind that we will make more complicated apps in future.
    The first app is a kind of text reader with some specific features.
    Native features we want to access to make the following: – simple file explorer,
     – change view according to device orientation,
     – disable light-off timeout,

    The reader has a mode with rapidly changing text. (where Titanium is slow)

    We have 3 options in Titanium,
    (first two we’ve tried already)
    1. Pure HTML/Javascript in Webview,
    2. App written in Titanium specific Javascript.
    3. Application with native Java/C++ module (here we want to try NME).

    So we will try to make a module with NME and then try other ways you suggest.

    I use Haxe (targeting JS) with Titanium, and write with code completion in FlashDevelop. Always use command line “titanium run –platform=android”
    http://wiki.appcelerator.org/display/guides/Titanium+Command-line+tool

  • Hi Joshua,

    I think there’s an issue within your AnimatedSprite.hx where non looping animation/behaviours end on the wrong frame as the nextFrameIndex is able to exceed the total number of frames in a behaviour and returns frame 0 of the spritesheet which may not be part of the current behaviour.To fix this I’ve added the below code
    if (nextFrameIndex > behavior.frames.length – 1)  nextFrameIndex = behavior.frames.length – 1; // Or perhaps 0 if you want to loop and pause

    Cheers,

    Tim

  • Thanks! I just figured out what was going on.

    The frame index is based on a ratio, for time elapsed compared to the time required to finish the animation. It should not be possible for this to exceed the total number of frames, because there already is a check to make sure that “ratio” never exceeds 1.

    However, it was using an equation of “Math.round (ratio * behavior.frames.length)” to get the index. It should have been using “Math.round (ratio * (behavior.frames.length – 1))”, because the index is a 0-based index. The “nextFrameIndex” value was always one value higher than it was supposed to be. I guess there must be something about the timing of my animation that didn’t allow me to see the problem. Sorry about that!

    I just posted an update to haxelib, so you can update using “haxelib upgrade”

    Thanks again!

  • Wahyudinata Setiawan

    tr

  • Wahyudinata Setiawan

    Tried it, works as advertised 🙂
    How do you add multiple behaviors in the same spritesheets though
    such as hero spritesheet has walk, attack , jump animations

  • You could always define your own definition file, by hand or perhaps with a different sprite tool.

    If you are using SpriteLoq, you can specify multiple behaviors in the same sprite sheet file by converting multiple SWF files at once. You would separate walk, attack and jump into their own SWF files, then select them all when you pack the sprite sheet. This would put them in the same file, but with their own identifiers

  • Bruno Garcia

    This tool looks pretty sweet. I ran the sample swf through the latest version of SpriteLoq, but it only generates a .png and .lua. Is there an option somewhere to make it export the XML?

    EDIT: Nevermind, my nme.meta was in the wrong place!

  • Hah, awesome. Well let me know how it works out!

    I’d love to hear feedback to make the sprite sheet library even better 🙂

  • davidjmcclelland
  • Roman

    Is that good solution for mobile and flash? I think especially about performance, does it use drawTriangles?

  • Instead of blitting each frame, it divides the sprite sheet into separate BitmapData objects, and swaps the data of a single Bitmap each time the character is animated. The last time I created a large game engine, this was much faster than copyPixels or drawTriangles, though it did require some additional memory. It performed fast in Flash and C++.

    I have not performed additional tests, for example, using drawTiles, but the code is open, so if anyone finds performance improvements by adjusting the code base, I would be glad to see what they come up with!

  • The “spritesheet” library supports custom importers, so if there is another sprite sheet tool that you like, please free to make (and share) an importer so we all have more choices 🙂

  • Will this ever work with the HTML5 target? About a year ago I built an HTML5 app using haxeJS, jQuery and easelJS, and having native spritesheets in haXe would have been quite helpful. 🙂

  • I just tried it here and it worked 🙂

    I just had to replace ApplicationMain.getResource in line 30 with Assets.getText. This sample was written before the nme.Assets class was in place

  • Ciprian Caba

    Hi,

    I have an issue when I am trying to work with multiple spritesheets. It fails when I am trying to create the 6th animation.

    I have attached a copy of the project, including the error log. I am compiling with the latest release version of nme.

    Everything works on flash and cpp, but the problem appears when I am trying to run on my Galaxy S2.

    The project: http://wtrns.fr/LV9Fre59-ewWCA

    Thanks for any help,
    Ciprian

    UPDATE: Changing to svn hxcpp from http://code.google.com/p/hxcpp fixes this
    just run “haxelib dev hxcpp path/to/svn/checkout”

  • Nikolas

    +1

  • I’ve pinged Hugh to see if HXCPP is ready for a new haxelib release. It sounds like that would help 🙂

  • KKK

    Works as HTML5 in Safari, in Chrome doesn’t. Is it a good idea to use Haxe NME to write small arcade games for mobile browsers?

  • NME handles the C++ and publishing for the Flash target, but HTML5 is provided with Jeash. I am impressed with all that Jeash is able to do, but more help may be needed to make it as seamless as possible.

    If you haven’t seen it already, Jeash has been added to GitHub:

    https://github.com/grumpytoad/jeash

    If you’re interested in HTML5 output, I would recommend that you check out what Jeash has to offer now, and to also consider if you’re interested in helping if you find ways it could be stronger.

    There is also the method of using the “swf” library for SWF assets, which works in Flash and C++, currently. I think it could work in JavaScript if we implemented ByteArray.uncompress in Jeash

  • Terence Chong

    Hi Joshua, I download your example and tried to export as html5 but nothing shows up on IE/firefox. Will really appericiate if help can be give. Thank you.

  • Vishesh Likhitkar

    can u please post a tutorial about using spritesheet library without a specific tool?
    i have a spritesheet image, i can probably write a small xml document with framenumber position and size information

    but how do i use this information with ure library?

    (bitmap = “path/image.png”)
    (frame1=”0,0,32,32)
    (frame2=”0,32,32,32)
    etc….

    load this and proceed with the rest….

    btw im using the normal brackets instead cuz when im posting this, the code is vanishing

  • I had a behaviour with 3 frame. It seemed to spend 25% of time on frame 0, 75% frame 1, 25% frame2 – to fix this i changed AnimatedSprite.hx:120 to:

    currentFrameIndex = Math.floor (ratio * (behavior.frames.length));

    should this make more sense in general? seems to work here

  • John Stejskal

    how to get this extension to work? The example project throws errors. Can we get an updated example project?

  • Mpoint

    Hello Joshua,

    is there somewhere an updated example on how to use the spritesheet class now in OpenFL / Haxe3 or do you have some quick hints…. I got myself the Animo Spritesheet importer (from Lanica, which bought the original SpriteLoq – software) and want to use it now in a similar manner as it was possible with the Spritesheet library under NME…

    Cheers & thanks in advance,
    Marcus