Working knowledge of using a recent version of Flash Professional
Required Adobe products
The Flash Professional Toolkit for CreateJS (henceforth, just “Toolkit”) is an extension to Adobe Flash Professional CS6 that allows you to publish animated assets for use with the CreateJS suite of open source JS libraries to create rich, interactive experiences for HTML5.
It’s important to note that Toolkit is not an exporter. It is not intended to convert existing projects into HTML5 with a single button press. Instead, it’s designed to facilitate a flexible and productive workflow for building new projects in HTML5, while leveraging existing Flash skills.
This article will take you on a quick A–Z tour of Toolkit and the CreateJS framework by building a simple interactive game. If you want, you can first check out the following video, which gives you a sense of the core Toolkit features, including expected workflows and philosophy behind this technology.
Publish to HTML5 using the Flash Professional Toolkit for CreateJS v1.0 (13:09)
Launch Flash Pro and open the sample FLA. If everything is installed correctly, you can open the Toolkit for CreateJS panel in the Window menu. If it’s not displayed, you are prompted to download the extension and install it (see Figure 1).
Figure 1. Open the Toolkit for CreateJS panel.
Quick tip: In addition to the panel, the extension also installs “Publish for CreateJS” in the Commands menu. You can set up a keyboard shortcut for this command to make it easy to test your work in Flash > Keyboard Shortcuts (OSX) or Edit > Keyboard Shortcuts (Windows).
Next, open the PlatypusGame.fla file included with the demo files. We’ll take a closer look at this file in a moment, but for now run a Test Movie to see the SWF output. You’ll see a terrifying looking platypus launching an aerial attack using a balloon – this is truly the stuff of nightmares!
Now let’s take a quick look at the FLA, and discuss some best practices for authoring content using Toolkit.
On the main timeline, you’ll see three layers, holding the score text field, the platypus, and the background.
Figure 3. Three layers, holding the score text field, the platypus, and the background.
Generally I’d recommend using HTML to display text, because support for text in EaselJS and the HTML5 canvas element is quite limited. In this case, we’re only displaying a single line of simple text, so we’ll leave it in.
Quick Tip: Fonts for text follow the same rules as in CSS. The fonts are not embedded in the published output. Either use web safe fonts, or ensure you make the fonts available in your project using web fonts for CSS.
Double click the background to edit it. This is a pretty simple symbol with static content on three layers. The sky layer contains a simple vector gradient shape. The cliff layer holds a bitmap image. This could have been a vector, but it’s reasonably complex, and has some texture to it that would be hard to reproduce as a vector graphic. Finally, the clouds are all instances of a single cloud symbol that have been transformed and had their alpha value adjusted.
Figure 4. Double click the background to the symbol with static content on three layers.
Labels, sounds, and timeline scripting
Now let’s check out the platypus. This symbol contains the animated content. We’re not going to look at everything, but we’ll discuss a few key elements.
The first layer contains three labels: idle, pop, and fall. Just like in ActionScript, we’ll be able to use these labels to jump to specific frames in the animation using code. Additionally, EaselJS starts frame numbers at 0 whereas Flash starts at 1 (so EaselJS frame numbers are always be one less than what you see in Flash Pro). For these reasons, I recommend that you use frame labels instead of numbers for maximum versatility.
Figure 5. Stick to code that controls the timeline.
The second layer contains a classic tween that rocks a movieclip instance with the platypus idle animation back and forth. While Toolkit (v1.1 and up) supports motion, shape, and classic tweens, I would recommend using classic tweens whenever possible. They are the only type of tween that is retained as a runtime tween, instead of being converted to a frame by frame animation. This saves on filesize, and lets you manipulate the tween dynamically.
There are some restrictions on classic tweens you should be aware of. Specifically, a layer with a classic tween can only contain a single symbol instance for it’s full duration. This is why the pop and fall layer is separated – the symbol changes from PlatypusIdle to PlatypusPop.
The final layer contains a Graphic instance that holds the balloon pop and fall animations. Toolkit fully supports Graphic symbol instances.
Jump to the first frame, and double click on the platypus on the idle layer. This animation shows the ideal approach to character animation using Toolkit. Each body part is a separate symbol instance with a classic tween applied to it. This allows for much shorter publish times, and smaller file sizes than frame by frame animations.
Quick Tip: When creating your content, you have to decide between vector graphics or using bitmaps. Vector animations are generally smaller (for file size), and render a bit more cleanly when rotated, scaled, or positioned off whole pixels, but they use significantly more resources to render (especially on mobile). You can also use bitmap caching strategically on static (non-animated) content, or EaselJS’s SpriteSheetBuilder class on animated content, to get the best of both worlds.
Now that we’ve examined the FLA, let’s take a look at what was generated when we published for CreateJS. Open the output directory (the same folder as the FLA by default), and you’ll see 3 directories and 2 files that have been created:
Figure 7. The output directory includes three directories and two files.
images and sounds
This is where any images and sounds that are used in your project are exported to. Note that there are limitations on what sounds can be exported – see the release notes for more details. You can change these directories in the Edit Settings dialog.
Quick Tip: If you frequently change out images or sounds in your FLA, you might wind up with a bunch of old media in these folders. If you want to ensure you only have the latest copies, you can delete these folders before publishing.
This folder contains the minified CreateJS libraries that are required to run the published content. When you publish, only the libraries you need are included (for example, SoundJS is not included if you don’t have any sound).
Quick Tip: If you check the Hosted Libs option in the Toolkit’s settings dialog, the libraries are loaded from a content delivery network (CDN). This allows them to be cached between different sites using the same version of the libraries.
This is a simple HTML file that Toolkit generates so that you can preview your output in the browser. If you look at the source, you’ll see it’s very straightforward. It imports the required libraries, uses PreloadJS to load any media, then sets up an EaselJS stage pointing at a Canvas element and adds an instance of the root timeline (PlatypusGame) to the stage.
Finally, it sets the framerate on Ticker and adds stage as a listener. This establishes the heartbeat (similar to enterFrame) for the whole animation, updating and redrawing the stage 20 times per second. PlatypusGame.js
This is where the real meat of the output lives. We won’t dig too deeply into this file, but if you scan through it you’ll notice a few things.
Firstly, notice that a lot of work has gone into making the generated code very human readable. This is not a black box export that you can’t easily modify. If you have development experience, you should feel pretty comfortable scanning through the file and editing things manually if needed.
keyword to create instances of the symbols in your library, which can then be added to the display list. This is very similar to how you’d work in ActionScript 3. For example:
var myPlatypus = new Platypus();
Figure 5. Stick to code that controls the timeline.
Quick Tip: Toolkit uses the name specified as the ActionScript 3 class name for export if one is specified (otherwise it uses a name based on the symbol name). Likewise, for the root element it uses the document class name if specified, and falls back to the FLA name otherwise.
Similar to publishing to SWF, only symbols that are referenced from the document stage, or that have a class name specified are included in the published library.
Finally, you might want to take a look at the Platypus class to see how the content is represented. If you look at the end of its definition, you’ll see that it extends (inherits from) the EaselJS MovieClip class. The MovieClip class associates a TweenJS timeline (which handles animation) with an EaselJS Container (which aggregates child display objects).
At the top of the class definition, you’ll see the timeline functions that were generated from the timeline code. Scanning downwards, you’ll see all of the child display objects created and added to the stage, and a number of tweens added to the MovieClip timeline which control animations, play sounds, and call functions.
So, we have a library of reusable symbols – how do we turn this into a game?
Generally, you’ll want to start by creating a new HTML file to work from. We could edit the generated HTML, but by working from a new file we create a nice separation of design and development.
Quick Tip: If you really want to work from the generated HTML, you can uncheck publish HTML in the Settings panel. Toolkit still uses the existing HTML file for previewing, but it no longer overwrites it – just be aware that this means that any new media (images or sounds) is not loaded correctly unless you add them manually.
A designer can work in one (or multiple) FLA(s), and view their work in the generated preview HTML, while the developer works in their own HTML file, and imports the libraries into their projects. Whenever the designer makes a significant change, they can share the new published library and the developer sees the change in their work immediately.
Quick Tip: Very large FLAs can take a while to publish, especially if you have the “multi frame bounds” setting turned on. If this becomes a problem, consider breaking your assets into multiple FLAs, and importing all of the JS libraries into your working project separately.
Open the GameDev.html file in your browser now, and play the game to get a sense of what the functionality is. Our terrifying platypus friends float in from the right, hoping to steal the delicious pastries on the left. You have to pop their balloons before they get there to earn points. There’s obviously a lot that could be added, but I wanted to keep it really simple for this article.
Figure 8. Play the game to get a sense of the functionality.
pImportant: If the game doesn’t seem to be responding to clicks, or is throwing security errors, please read the SECURITY_ERRORS.txt file included with the example.
Quick Tip: One of the strengths of HTML is the ability to combine different APIs and libraries to build a project. For example, when building a game, we (gskinner.com) typically build the game engine using CreateJS, and layer on the surrounding UI with jQuery. CreateJS also has some cool features to make this easier: for example, check out the
DOMElement class in the EaselJS documentation.
Setting up the stage
At the top, you’ll see the init function that gets called in the HTML file’s
onload handler. This function is unchanged from the version in the preview HTML. It grabs a reference to the canvas tag, creates a holder for our image assets, and sets up our preloader. To keep things simple, we’re not doing anything during the preload, but PreloadJS makes it really easy to build a graphical progress indicator if you want one.
Next you’ll see the same handleFileLoad function from the generated HTML. This is just tossing references to all of the images into the images object as they load. Our generated library expects to be able to access them there as needed. The
playSound function is called to play sounds on the published timelines. This makes it easy to change how sounds are managed in your project (for example, if you want to use a library other than SoundJS).
Following that is the handleComplete method. This remains almost identical to what was published, except that now it removes the Platypus instance that was on stage. We’ve also enabled touch interactions on our stage, so this game can be played on an iOS device.
Quick Tip: In a more complex project, you’d likely get rid of the
exportRoot, and add elements to the stage directly. This removes a layer from your display list, which makes elements easier to reference and performs a tiny bit better.
Another important change we’ve made is to change the Ticker listener from
stage to our tick function. This allows us to run a tick method on window, and run some game logic each tick before calling update on stage (similar to putting game logic in an enterFrame event in ActionScript 3).
Quick Tip: I’m keeping things simple here, but generally you should create a class that encapsulates your logic and register a method on it with Ticker , instead of polluting the global (window) scope.
Adding game logic
The tick function is called 20 times per second, and is the heartbeat of the game. Let’s run through the tick function in order.
First, if a random value is less than 0.01 (1% chance) then we create a new platypus, push it into our platypii array, set its display properties, give it a velocity, and add it as a child of the stage. If you’ve written ActionScript 3, this should look very familiar. We also assign handlers for the click and pop events. For the click event, we dig into the platypus’s children to add it to the balloon specifically.
Next, we iterate through each active platypus, apply gravity if it’s falling, and update the x and y position based on its velocity. We also check to see if the platypus is off screen. If it is we remove the evil duckhog from the game and update the score by calling a simple updateScore function that adjusts the score and updates our scoreTxt text field.
Finally, and very critically, we call stage.update(). This tells EaselJS to redraw the scene to our canvas. If we don’t do this, the game runs, but you are unable to see it, because the visuals never update.
We’ve already wired our interaction by adding the click event handler to our platypuses, but we need to handle the event. The handleBalloonClick function manages this interaction. Notice that the handler accepts a single eventObj parameter. EaselJS passes a MouseEvent object to this function which gives us some useful data, including the target display object.
We know the hit came from a balloon, but we’re really interested in the platypus it’s attached to. Just like in ActionScript, we can move up in the display list using the
parent property. Once we have a reference to the platypus, the rest is easy – we just tell it to play its pop animation.
Integrating with the timeline
We can control the timeline using commands like play(), stop(), and gotoAndStop()
. Using timeline scripting we can also have the timeline communicate with our game logic to inform us of significant events. In this case, we’ve included the following timeline code at the end of our pop animation:
This causes the timeline to dispatch a custom event of type “pop” to any listeners. All DisplayObject classes use EventDispatcher to dispatch events.
We’ve assigned handleBalloonPopped to handle this event. It simply flags the platypus as falling. The tick function handles everything else for us.
That’s it! We’ve built a simple HTML5 game using Toolkit for CreateJS and the CreateJS libraries, and it took less than 100 lines of custom code. There’s obviously a lot you could do to extend this game, and we could perform quite a few optimizations to make our graphics render more quickly, but that’s a topic for another article. Hopefully this has introduced you to the basic concepts and workflow you can use to build amazing HTML5 content in Flash Pro.
For more information and documentation on Toolkit for CreateJS visit the Adobe Developer Connection.
For more information and documentation on the CreateJS libraries visit the CreateJS website.
To get the basics on how the Toolkit for CreateJS works, read Using the Flash Professional Toolkit for CreateJS.