Bunny Vengeance Game Concept

I’ve been working with my buddie Alex on a new game idea, codenamed Bunny Vengeance. We’ve not committed to actually making anything for real yet but I thought I’d share a concept video that Alex put together. I’m hopeful that we’ll at least put together a few rapid prototypes but it really depends on the feedback we receive. So please, let me know what you guys think.

It’s always great to be working with talented people like Alex. He’s a world class animator and if you don’t believe me take a peek at his showreel below. I’m sure you’ll recognise, well, most of his work ๐Ÿ˜‰

Alex has only recently started dabbling in Flash, but it’s seriously cool to see someone who’s worked for the likes of Pixar and DreamWorks applying his skills to the Flash platform. Hopefully we’ll be able to find the time to continue with this project.

Flash Pro CS6 and the Toolkit for CreateJS

Learn how to build rich HTML5 applications with content exported using Flash Professional CS6’s Toolkit for CreateJS.

What you will learn…

  • The fundamentals of the CreateJS suite of JavaScript libraries
  • How to publish Flash Professional CS6 assets for use with CreateJS
  • How to write JavaScript that utilizes your exported content

What you should know…

  • You should be comfortable working with Flash Professional
  • A familiarity with ActionScript or JavaScript is required

The ubiquity of HTML5 makes it the ideal technology for the delivery of rich web-based content across a wide range of devices and platforms. While various JavaScript code libraries and frameworks exist for the benefit of developers, there has been a serious lack of tooling to aid designers wishing to create rich expressive content. This has been particularly problematic for those accustomed to Flash Professional’s powerful illustration and animation capabilities. Just how do you create equivalent content when targeting HTML5?

With the release of Flash Professional CS6, Adobe has solved this problem by providing the Toolkit for CreateJS – an extension that takes animated content created in Flash and exports it to HTML5. Once exported, developers can write JavaScript to manipulate and add interactivity to the content by taking advantage of the popular CreateJS framework.

This tutorial will take you through the entire designer-developer workflow. You’ll learn how to export the contents of a FLA to HTML5, before adding interactivity to it using JavaScript and the CreateJS framework. We’ll be creating an underwater scene complete with animating air bubbles (Figure 1) that rush towards the surface. We’ll also add a little interactivity, allowing the user to pop any of the bubbles by clicking on them. The major difference being that this time we’ll be targeting HTML5 within the browser rather than the Flash runtime.

Figure 1. Designed in Flash but running in HTML5.

Getting Started

You’ll need Flash Professional CS6 to work through this tutorial. A trail version can be downloaded from www.adobe.com/downloads.

The Toolkit for CreateJS is a complimentary extension for Flash Professional CS6 that can be downloaded from www.adobe.com/go/downloadcreatejs. Once downloaded, simply double-click the .zxp file to install it through Adobe Extension Manager CS6. Adobe are committed to updating the toolkit’s capabilities on a quarterly basis, so check the CreateJS Developer Center from time to time for any new versions.

For development work you’ll need a suitable code editor or IDE. I’ll be using Sublime Text 2, a trial version of which can be downloaded from www.sublimetext.com/2.

Finally, a FLA has been prepared for you to work with. Download it from www.yeahbutisitflash.com/downloads/toolkit-for-create-js-tut/bubbles.fla and open it within Flash Professional CS6.

Creating Assets within Flash Professional CS6

Let’s begin by taking a look at the FLA. It contains a mixture of vector and bitmap content that’s used to represent our underwater scene.

Sitting on the stage is a movie clip with an instance name of background. The movie clip itself contains a bitmap that represents the underwater scene’s background image.

The rest of our content doesn’t sit on the stage, but can instead be found in the library. If you move to the Library panel you’ll find a symbol named Bubble that will be used for each of the scene’s bubbles. Double-click the symbol to move to its timeline.

Its timeline consists of 48 frames of animation. It’s a fairly conventional animation that uses classic tweening to skew the bubble, giving the illusion of it changing shape while underwater. The bubble itself consists of vector artwork making it scalable without the loss of fidelity. This is useful as we’d like to add bubbles of varying sizes to the scene at runtime.

In order to add bubble instances at runtime, we’ll need to provide the Bubble symbol with a linkage class name. To do that, simply right-click on the Bubble symbol within the library and select Properties from the context menu (Figure 2). From the Symbol Properties panel, ensure that the Advanced section is expanded and click the Export for ActionScript checkbox (Figure 3). Doing so will provide the Bubble symbol with a default class name of Bubble. It’s this class name that we’ll use within our JavaScript code to dynamically create instances of the bubble at runtime.

Figure 2. Moving to the symbol's Properties panel.

Now click the OK button to close the panel. If an ActionScript Class Warning panel appears, simply press its OK button to dismiss it. The warning panel is simply informing us that the Flash IDE cannot find a class named Bubble and that it will automatically create one for us. This is fine and is exactly what we want.

Figure 3. Adding a class linkage to the Bubbles symbol.

It’s worth bearing in mind that while we associated an ActionScript linkage class to our bubble, when exporting our content to HTML5, this linkage class name will be available to the programmer as a JavaScript class.

With that we’re now ready to export our FLA’s contents to HTML5. First save your work.

Publishing for CreateJS

Publishing to HTML5 is actually very simple and is taken care of by the Toolkit for CreateJS panel. You can open the panel by selecting Window | Other Panels | Toolkit for CreateJS from Flash Professional CS6’s drop-down menu. For easy access, feel free to dock the panel.

The panel (Figure 4) allows you to adjust various publish settings. While we’ll stick to the defaults, some are worthy of our attention before proceeding.

Figure 4. The Toolkit for CreateJS panel.

Near the panel’s bottom-right is the Hosted libs checkbox. After publishing to HTML5, the generated HTML file will require the use of various JavaScript libraries from the CreateJS suite. To save the developer having to download and host these libraries, the HTML file, by default, will use versions of the libraries that are hosted on a remote content delivery network.

There’s also an Include hidden layers checkbox, which is used to export HTML5 for any content sitting on guided layers. While I’d normally encourage you to uncheck this, for this tutorial there’s no need as our FLA has no hidden layers.

The panel also contains various publish paths, including where the generated output files will be written to. By default, the FLA’s root folder is used. Again, this is fine for the purpose of this tutorial.

Now go ahead and click the panel’s Publish button to export your FLA’s content as HTML5. After a brief moment, your default web browser will launch and you’ll see the contents of your FLA’s stage sitting within the browser. While you’d normally expect this content to be running within the Flash Player, this time it’s actually using HTML and JavaScript. You can confirm this by right-clicking within the browser window (Figure 5). There will be no mention of Flash Player anywhere within the context menu.

Figure 5. Look! No Adobe Flash Player.

Effectively you’re looking at an HTML5 representation of the SWF that you’d normally publish from your FLA.

The CreateJS Output Files

At the moment, our HTML doesn’t do much. It simply shows the bitmap image that was sitting on our stage. We’ll address that soon enough by writing some JavaScript to bring our underwater scene to life, but first let’s take a look at what was generated during publication (figure 6).

Figure 6. The files generated by the Toolkit for CreateJS panel.

You should see that the following two sub-folders and two files were created within your FLA’s root folder:

images – Any bitmap images used by your FLA are kept here.
sounds – Any sound files used by your FLA are kept here.
bubbles.html – An HTML file that is created to allow you to preview your output in the browser.
bubbles.js – This file contains the JavaScript required to represents any symbols sitting on your stage and within the library.

If you’d unchecked the Hosted libs checkbox then a third sub-folder named libs would have been created to house each of the required CreateJS libraries.

What Exactly is CreateJS?

As we’ve just seen, the contents of our FLA’s library are magically represented within a JavaScript file named bubbles.js. But how is this possible?

Well, it’s made possible by CreateJS, which provides a suite of JavaScript APIs that can be used to represent the complex artwork that is created within the Flash Professional IDE. The generated bubbles.js file simply contains calls to these APIs in order to recreate each of your library’s assets.

CreateJS consists of the following libraries:

EaselJS – Enables rich graphics and interactivity with HTML5 Canvas.
TweenJS – A tweening library that integrates with EaselJS.
SoundJS – Provides audio playback functionality.
PreloadJS – Manages and co-ordinates the loading of assets.

When you’re developing your own applications, it’s likely that you’ll make use of the CreateJS suite to further manipulate and interact with the content exported from your FLA.

This tutorial will really just scratch the surface of these powerful libraries but I encourage you to spend as much time as possible exploring the documentation on the official CreateJS website at www.createjs.com.

Understanding the Published JavaScript

Each time you publish using the Toolkit for CreateJS panel, an HTML and JavaScript file will be generated. The HTML file is the entry point and when opened within your browser, will play any content placed on your stage. The JavaScript file, as has already been explained, will contain the actual code necessary to represent that content.

Let’s take a look at that JavaScript file. Open bubbles.js within a text editor and examine the code.

You should notice that an object named lib is created, and that each property of that object is a class that represents a symbol from your FLA’s library. For example, here’s the JavaScript that defines the Bubble movie clip symbol from your library:

(lib.Bubble = function(mode,startPosition,loop) {
  this.initialize(mode,startPosition,loop,{},true);

  // Layer 1
  this.instance_2 = new lib.BubbleVector();
  this.instance_2.setTransform(0,0,0.4,0.4);

  this.timeline.addTween(
    cjs.Tween.get(this.instance_2).to({scaleY:0.4,skewX:3.3},11).to(
    {skewX:-3.1},24).to({scaleY:0.4,skewX:0},12).wait(1));

}).prototype = p = new cjs.MovieClip();
p.nominalBounds = new cjs.Rectangle(-157,-157,314.1,314.1);

The code itself is very readable. You can see an instance of BubbleVector (The BubbleVector class itself is defined earlier in the file) being added to the Bubble movie clip’s timeline:

this.instance_2 = new lib.BubbleVector();
this.instance_2.setTransform(0,0,0.4,0.4);

Followed by the definition of the tweening operations that are to be applied between the timeline’s keyframes:

this.timeline.addTween(
  cjs.Tween.get(this.instance_2).to({scaleY:0.4,skewX:3.3},11).to(
  {skewX:-3.1},24).to({scaleY:0.4,skewX:0},12).wait(1));

Quickly revisit the Bubble movie clip within your FLA’s library. Look at its timeline while reading over the code listed above and it should start to make a lot of sense.

Essentially, everything within your FLA’s library will be accessible via the lib object defined by the bubbles.js file. You can use the new keyword to create instances of these symbols then add them to the display list. Here’s an example:

var myBubble = new lib.Bubble();
stage.addChild(myBubble);

You could be forgiven for thinking that you’re looking at ActionScript, but the two lines of code above are in fact JavaScript. The CreateJS framework does a really great job of providing an API that should feel very familiar to Flash developers.

Take a final look through the code. You should see the following library symbols being declared: bubbles, Bubble, Background, background, and BubbleVector. All can be instantiated and added to your display list using JavaScript. Some are in fact instantiated within bubbles.js and used as child instances. You’ve already seen this in action, with BubbleVector being added to the display list of Bubble.

Understanding the Published HTML

Now that you’ve familiarized yourself with the bubbles.js file, let’s take a peek at the generated HTML file, bubbles.html. It’s within this file that your stage is created and updated.

At the top of the HTML file, you’ll see that the various libraries required from the CreateJS suite are loaded. Additionally, the bubbles.js file, which is the JavaScript version of your FLA’s library, is also included:

<script src="http://code.createjs.com/easeljs-0.5.0.min.js"></script>
<script src="http://code.createjs.com/tweenjs-0.3.0.min.js"></script>
<script src="http://code.createjs.com/movieclip-0.5.0.min.js"></script>
<script src="http://code.createjs.com/preloadjs-0.2.0.min.js"></script>
<script src="bubbles.js"></script>

At the bottom of the HTML file is an HTML5 canvas element, which is used to render your stage:

<body onload="init();" style="background-color:#D4D4D4">
  <canvas id="canvas" width="640" height="480"
   style="background-color:#ffffff"></canvas>
</body>

As you can see from the HTML snippet above, when the page is loaded, an init() function is called. Within this function, any image and sound resources are loaded using the PreloadJS library. If you can remember, our FLA’s stage had a movie clip that contained a bitmap image of our underwater scene. You can see the init() function below with the bitmap’s source path being listed within a manifest array, which is eventually passed to the preloader:

function init() {
  canvas = document.getElementById("canvas");
  images = images||{};
 
  var manifest = [
    {src:"images/background.png", id:"background"},
    {src:"images/flashlogo.png", id:"flashlogo"}
  ];
 
  var loader = new PreloadJS(false);
  loader.onFileLoad = handleFileLoad;
  loader.onComplete = handleComplete;
  loader.loadManifest(manifest);
}

The final chunk of work takes place within the handleComplete() function, which is called once all image and sound resources are loaded:

function handleComplete() {
  exportRoot = new lib.bubbles();
 
  stage = new createjs.Stage(canvas);
  stage.addChild(exportRoot);
  stage.update();
 
  createjs.Ticker.setFPS(30);
  createjs.Ticker.addListener(stage);
}

Three things take place here.

Firstly, a top-level container clip named lib.bubbles is instantiated and assigned to the exportRoot global variable. This container simply holds all the content that was originally sitting on your FLA’s stage.

Secondly, a JavaScript class that represents the stage is instantiated and exportRoot is added as a child. A call to the stage’s update() method forces its content to be drawn to the screen.

Finally, a static Ticker class is used to regulate the frame rate. The stage is added as a listener, which will ensure that its internal tick() method is called on every frame update, forcing a redraw.

You may also have noticed that several global variables are declared at the top of the HTML file:

var canvas, stage, exportRoot;

This permits access to these objects from anywhere within your code. The JavaScript version of your library can be accessed in a similar manner via the global lib object, which was defined within your bubbles.js file.

We’ll make good use of both the lib, canvas and stage objects throughout the remainder of this tutorial.

Getting Ready for Development

Now that you’ve familiarized yourself with the bubbles.js file, I think it’s about time we started writing some code. You could be tempted to simply start adding your JavaScript to the existing bubbles.html file, but there’s a problem with that approach. Every time you make alterations to your FLA and republish, your bubbles.html file will be overwritten.

Let’s get round this problem by creating a new HTML file to work from. Simply create a duplicate copy of the bubbles.html file and rename it BubblesDev.html. Test your BubblesDev.html file by opening it within a web browser. From now on, when developing, this is the file that you’ll use when testing your latest changes.

With that done we can finally start writing the JavaScript required to bring our underwater scene to life.

Creating a Main Loop

Every application requires a main loop. A main loop should be executed on every frame update and is an ideal location for handling an application’s high-level logic. To achieve this, we’ll create a custom tick() function for the static Ticker class to call, as opposed to it calling the stage’s internal tick() function. Think of this function as your stage’s ENTER_FRAME event handler.

Open BubblesDev.html within your text editor and add the following at the end of its script block:

function tick() {
  stage.update();
}

We’ll add more code to this function as we progress but for the time being it simply forces the stage to be redrawn.

We’ll also need to make a slight alteration within the file’s handleComplete() function. Change its final line of code from:

createjs.Ticker.addListener(stage);

to:

createjs.Ticker.addListener(window);

This will ensure that your custom tick() function is called instead of the stage’s.

Adding a Bubble

Although we now have a custom main loop, if you run BubblesApp.html within the browser, you won’t actually see anything different yet. Let’s rectify this by adding a bubble from our library onto the stage.

Add the following function at the end of your JavaScript block:

function setupBubbles() {
  var bubble1 = new lib.Bubble();
  bubble1.x = canvas.width / 2;
  bubble1.y = canvas.height / 2;
 
  stage.addChild(bubble1);
}

Its code should look fairly familiar and isn’t that dissimilar to the equivalent ActionScript. First off, an instance of the library’s Bubble symbol is created using the new keyword. Then the bubble1 instance is positioned in the center of the stage.

To center the bubble, we need to know the stage’s width and height. Unfortunately the global stage object does not provide width and height properties. However, we can retrieve this information from the global canvas object instead – this is the HTML5 canvas element that is used to represent our stage.

Finally, with the bubble’s position set, it is added to the stage’s display list using the stage object’s addChild() method.

Now all that’s required is to call the setupBubbles() function from a suitable location within your code. Add the call to the end of your handleComplete() function:

  createjs.Ticker.setFPS(30);
  createjs.Ticker.addListener(window);
 
  setupBubbles();
}

Now save your BubblesDev.html file and refresh your browser window. You should see an instance of the Bubble movie clip animating in the center of the stage (Figure 7). It really is quite impressive. You’re actually looking at a full HTML5 representation of your symbol’s vector artwork and timeline animation.

Figure 7. An HTML5 representation of your bubble movie clip.

Adding Another Bubble

Just like ActionScript, your CreateJS display objects can be scaled horizontally and vertically using the scaleX and scaleY properties. Let’s place a second bubble on the stage, and also apply a scale factor to both it and the previous bubble.

Figure 8. Positioning and scaling bubble instances.

While we’re at it, let’s also use each bubble’s width to position it away from the center of the stage. We’ll push the first bubble over to the left and the second bubble to the right (Figure 8). Make the following alterations to your setupBubbles() function:

function setupBubbles() {
  var bubble1 = new lib.Bubble();
  bubble1.scaleX = bubble1.scaleY = 0.6;
  bubble1.x = canvas.width / 2 - (bubble1.nominalBounds.width * bubble1.scaleX);
  bubble1.y = canvas.height / 2;
 
  var bubble2 = new lib.Bubble();
  bubble2.scaleX = bubble2.scaleY = 0.4;
  bubble2.x = canvas.width / 2 + (bubble2.nominalBounds.width * bubble2.scaleX);
  bubble2.y = canvas.height / 2;
 
  stage.addChild(bubble1);
  stage.addChild(bubble2);
}

The JavaScript above scales the first bubble to 60 percent of its original size. It then measures the width of the bubble, and pushes the bubble to the left of the stage’s center by that amount. Here are the two lines of code from the listing above that accomplish this:

bubble1.scaleX = bubble1.scaleY = 0.6;
bubble1.x = canvas.width / 2 - (bubble1.nominalBounds.width *  
  bubble1.scaleX);

If you look closely you’ll notice that obtaining the bubble’s width isn’t as straightforward as you might expect. CreateJS’s display objects do not possess a width or height property. This is because calculating a display object’s bounds can be very expensive, especially when dealing with complex vector shapes or containers with transformations on children.

We can however, manually perform these calculations for our bubble instances thanks to the fact that our bubble’s original dimensions are available via a nominalBounds property. Here’s the code used to calculate the width of the first bubble after it has been scaled:

bubble1.nominalBounds.width * bubble1.scaleX

It’s hardly rocket science. The bubble’s original width is obtained from the nominalBounds.width property, and is then multiplied by the bubble’s current scale factor. In order for this to work, you must remember to apply the new scale factor first, before performing the calculation.

A similar procedure is performed for the second bubble, only it’s scaled by 40 percent then moved to the right of the stage’s center.

We’ll make use of the scaleX, scaleY, and nominalBounds properties again later on in this tutorial.

Creating a Custom Bubble Class

In order to create a convincing underwater scene, we’re going to need a considerable number of bubbles. Also, we’ll need to size each bubble, continually monitor and update its position to provide movement, and also apply some alpha transparency to give the illusion of distance.

To manage all this, it makes sense to encapsulate our bubble code within its own custom class, otherwise the BubblesDev.js file could become quite messy. We can do this by extending EaselJS’s Container class and placing your library’s bubble within it.

Create a new file and name it Bubble.js. Add the JavaScript shown below to your file and save it.

function Bubble(scale, speed, alpha) {
  this.initialize();
 
  this.bubble = new lib.Bubble();
  this.addChild(this.bubble);
}
Bubble.prototype = p = new createjs.Container();

We’ll add some more functionality to this class in a moment but first let’s explore what’s currently there.

The class’ constructor is defined by the Bubble() function and accepts three parameters. The first is a scale factor used to size the bubble; the second will be used to assign a vertical speed to the bubble; and the third represents the amount of alpha transparency to be applied. Essentially all three are used to customize each of the scene’s bubbles, ensuring that there is plenty of variety. Your class currently doesn’t make use of any of these parameters yet, but we’ll get onto that in a moment.

Inside the constructor, we perform two important tasks. The first is to call the initialize() method, which is inherited from EaselJS’s Container class. The second is to create an instance of the library’s Bubble symbol and add it to the container’s display list.

For the time being, our custom Bubble class doesn’t really give us any advantage over lib.Bubble. Let’s address that by adding some additional functionality to it. We’ll start by fleshing out the constructor function.

Add the following code at the end of the constructor function:

// Set the scale, speed and alpha.
this.scaleX = this.scaleY = scale;
this.speed = speed;
this.alpha = alpha;

The code snippet above takes each of the three parameters and sets various properties of the class. The first sizes the custom bubble by setting its scaleX and scaleY properties. The second declares and sets a member variable named speed, which will be used to move the bubble upwards on each frame update. The third sets the bubble’s alpha property.

Let’s now create a custom width and height property for the bubble using the nominalBounds property we covered earlier. Add the following two lines of JavaScript to your constructor.

// Store the bubble's dimensions.
this.width = this.bubble.nominalBounds.width * scale;
this.height = this.bubble.nominalBounds.height * scale;

Finally, we need to place the bubble on the stage. We’d like a random position for each bubble, so let’s add a few more lines of code at the end of the constructor to do that:

// Setup the bubble's initial position.
this.x = -(this.width / 2) + ((canvas.width + this.width) * Math.random());
this.y = -(canvas.height / 2) + ((canvas.height * 2) * Math.random());

The bubble will now be placed randomly on the stage, and can even appear above and below the stage area. This will be ideal for creating a realistic spread of bubbles in our underwater scene.

The final piece of functionality we’d like to add is the ability to move the bubble vertically upwards. We can achieve this by writing a method that updates the bubble’s position each time it is called. Add the following update() method at the end of your Bubble.js file:

Bubble.prototype.update = function() {
  this.y -= this.speed;
  if(this.y < -(this.height / 2))
  {
    this.x = -(this.width / 2) + ((canvas.width + this.width) *
      Math.random());
    this.y = canvas.height + (this.height / 2) + (this.height *
      Math.random());
  }
}

As you can see, it uses your class' speed member variable to change the bubble's y-position. The remainder of the code checks to see if the bubble has moved off screen. If it has then it's randomly positioned below the stage, ready to float back in. This update mechanic helps to ensure that there's a continuous flow of bubbles by re-using a bubble once it has drifted above the stage's visible area. Also, notice that we use the width and height properties that were created in the constructor throughout our update() method.

Testing your Custom Bubble Class

Before moving on, save your Bubble.js file and move back to BubblesDev.html. Let's update its setupBubbles() function to use your custom Bubble class rather than creating a bubble instance directly from the global lib object.

First, include your Bubble.js file by adding the following highlighted line within the BubblesDev.html file:

<script src="http://code.createjs.com/easeljs-0.5.0.min.js"></script>
<script src="http://code.createjs.com/tweenjs-0.3.0.min.js"></script>
<script src="http://code.createjs.com/movieclip-0.5.0.min.js"></script>
<script src="http://code.createjs.com/preloadjs-0.2.0.min.js"></script>
<script src="bubbles.js"></script>
<script src="Bubble.js"></script>

We'll also need to declare a global variable to hold a reference to our custom bubble instance. Add the following highlighted line of code directly underneath the other global variable declarations:

<script>
var canvas, stage, exportRoot;
var bubble;

Now within setupBubbles(), remove the previous code you'd written and replace it with the following:

function setupBubbles() {
  bubble = new Bubble(0.5, 4, 0.75);
  stage.addChild(bubble);
}

The code above will create a bubble instance that is scaled by 50 percent, has a vertical speed of 4 pixels per second, and has its alpha value set to 75 percent opacity.

To actually move the bubble instance we'll need to call its update() method from within our application's main loop. Add a line of code within the tick() function to do this:

function tick() {
  stage.update();
  bubble.update();
}

Save your file and then refresh your browser window. You should see an instance of your custom bubble drifting up the screen. Once it has moved off the top of the screen, it will re-appear at the bottom.

By creating a custom Bubble class, we have kept its internal workings hidden from our BubblesDev.html file. Scan back through the HTML file and look at how little code is required to get a single bubble instance up and running.

Now we need to get this working for multiple Bubble instances.

Adding Multiple Bubbles

Let's put the finishing touches to our code by instantiating multiple bubbles to give a greater sense of realism and depth to our underwater scene. We'll do this by creating four layers of bubbles stacked on top of one another. The farthest back layer's bubbles will be the smallest, with the top most layer's bubbles being the largest.

To achieve this we'll use an array to hold all the bubbles. Within your BubblesDev.html file, declare the following highlighted global variable:

var canvas, stage, exportRoot;
var bubble;
var bubbles;

While you're at it, remove the bubble global variable that's highlighted below as we will no longer have a need for it:

var canvas, stage, exportRoot;
var bubble;
var bubbles;

Now write a function that creates the first layer of bubbles. These bubbles will be the smallest and will have relatively low speeds to give the impression that they are far off in the distance. The speed, size, and opacity of each bubble will also be random to add a little more variety and realism. Here's the code:

function setupSmallBubbles() {
  var BUBBLES = 25;
  var SCALE = 0.2;
  var SCALE_VARIANCE = 0.1;
  var SPEED = 1.3;
  var SPEED_VARIANCE = 1.0;
  var ALPHA = 0.2;
  var ALPHA_VARIANCE = 0.2;
 
  var bubble;
  for(var i = 0; i < BUBBLES; i++)
  {
    bubble = new Bubble(
      SCALE + (Math.random() * SCALE_VARIANCE),
      SPEED + (Math.random() * SPEED_VARIANCE),
      ALPHA + (Math.random() * ALPHA_VARIANCE)
    );
    bubbles.push(bubble);
    stage.addChild(bubble);
  }
}

As you can see, each bubble is instantiated then added to the bubbles array and to the stage's display list.

Now move back to the setupBubbles() function and replace its existing code with the following:

function setupBubbles() {
  bubbles = [];
  setupSmallBubbles();
}

Now all that's left to do is to update each bubble's position within your update loop. Make the following changes to the tick() function allowing it to walk through your array of bubbles and call each one's update() method:

function tick() {
  stage.update();
  for(var i = 0; i < bubbles.length; i++)
  {
    bubbles[i].update();
  }
}

Save your latest changes and test your code by refreshing your browser. You should see 25 randomly sized bubbles drifting up the screen.

Adding the remaining three layers is easy. We'll need to write a setupMediumBubbles(), setupLargeBubbles() and setupSmallBubbles() function. Each will create slightly larger and faster moving bubbles than the previous. Here's the code for each function:

function setupMediumBubbles() {
  var BUBBLES = 12;
  var SCALE = 0.3;
  var SCALE_VARIANCE = 0.1;
  var SPEED = 1.9;
  var SPEED_VARIANCE = 1.1;
  var ALPHA = 0.4;
  var ALPHA_VARIANCE = 0.3;
 
  var bubble;
  for(var i = 0; i < BUBBLES; i++)
  {
    bubble = new Bubble(
      SCALE + (Math.random() * SCALE_VARIANCE),
      SPEED + (Math.random() * SPEED_VARIANCE),
      ALPHA + (Math.random() * ALPHA_VARIANCE)
    );
    bubbles.push(bubble);
    stage.addChild(bubble);
  }
}
 
function setupLargeBubbles() {
  var BUBBLES = 6;
  var SCALE = 0.5;
  var SCALE_VARIANCE = 0.2;
  var SPEED = 3.1;
  var SPEED_VARIANCE = 1.5;
  var ALPHA = 0.7;
  var ALPHA_VARIANCE = 0.3;
 
  var bubble;
  for(var i = 0; i < BUBBLES; i++)
  {
    bubble = new Bubble(
      SCALE + (Math.random() * SCALE_VARIANCE),
      SPEED + (Math.random() * SPEED_VARIANCE),
      ALPHA + (Math.random() * ALPHA_VARIANCE)
    );
    bubbles.push(bubble);
    stage.addChild(bubble);
  }
}
 
function setupHugeBubbles() {
  var BUBBLES = 1;
  var SCALE = 1.0;
  var SCALE_VARIANCE = 0.2;
  var SPEED = 6;
  var SPEED_VARIANCE = 6;
 
  var bubble;
  for(var i = 0; i < BUBBLES; i++)
  {
    bubble = new Bubble(
      SCALE + (Math.random() * SCALE_VARIANCE),
      SPEED + (Math.random() * SPEED_VARIANCE)
    );
    bubbles.push(bubble);
    stage.addChild(bubble);
  }
}

Once written, all three functions should be called from within your setupBubbles() function. Here's how the final version of the function should look:

function setupBubbles() {
  bubbles = [];
  setupSmallBubbles();
  setupMediumBubbles();
  setupLargeBubbles();
  setupHugeBubbles();
}

Once again, save your changes and refresh the browser. You'll now see all four layers of bubbles smoothly moving up the screen.

Adding Interaction

As a final exercise, let's add some interactivity, allowing the user to pop a bubble by clicking on it. We'll add this functionality directly to your custom Bubble class. Open Bubble.js into your text editor and place the following lines of code at the end of its constructor function:

// Setup an onPress event handler.
this.bubble.onPress = this.bubbleClicked;

The onPress event is triggered when the user presses their mouse over the bubble. In response to the onPress event, a method named bubbleClicked() will be called to handle it.

Add the bubbleClicked() method to the end of your Bubble.js file:

Bubble.prototype.bubbleClicked = function(e) {
  e.target.visible = false;
}

When the onPress event is triggered it passes an event object to its designated event handler. In our case, the event object will be passed to our bubbleClicked() method. From this event object we can obtain a reference to the target instance that the event was fired from. In other words, we can obtain a reference that points back to the bubble instance that was clicked. This is ideal as it allows us to hide the bubble from view, giving the illusion that it has burst.

As a final step, we'd like the bubble to eventually become visible again. Add the following highlighted line of code to the Bubble class' update() method to do this:

Bubble.prototype.update = function() {
  this.y -= this.speed;
  if(this.y < -(this.height / 2))
  {
    this.x = -(this.width / 2) + ((canvas.width + this.width) * Math.random());
    this.y = canvas.height + (this.height / 2) + (this.height * Math.random());
    this.visible = true;
  }
}

The bubble will now become visible again when it has wrapped back round to the bottom of the screen. This ensures that we continue to have a stream of visible bubbles over time.

Now save your changes and view the final version of your underwater scene within your browser. Click on the bubbles to pop them. Take a look at the code in Listing 1 to see the final version of the BubbleDev.html file. You can also see the final version of the Bubble.js class in Listing 2.

Final Statement

Hopefully this introduction to CreateJS and JavaScript, will give you the confidence to create and deliver high-quality HTML5 content, while taking advantage of Flash Professional as a design tool. JavaScript may not possess many of the language features of ActionScript 3, but with the right libraries at hand you can write extremely sophisticated web-based content that will run across a wide range of desktop and mobile browsers. And to be honest, writing rich, interactive games and applications is always a lot of fun no matter what technology you opt to use.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CreateJS export from bubbles</title>
 
<script src="http://code.createjs.com/easeljs-0.5.0.min.js"></script>
<script src="http://code.createjs.com/tweenjs-0.3.0.min.js"></script>
<script src="http://code.createjs.com/movieclip-0.5.0.min.js"></script>
<script src="http://code.createjs.com/preloadjs-0.2.0.min.js"></script>
<script src="bubbles.js"></script>
<script src="Bubble.js"></script>
 
<script>
var canvas, stage, exportRoot;
var bubbles;
 
function init() {
  canvas = document.getElementById("canvas");
  images = images||{};
 
  var manifest = [
    {src:"images/background.png", id:"background"},
    {src:"images/flashlogo.png", id:"flashlogo"}
  ];
 
  var loader = new createjs.PreloadJS(false);
  loader.onFileLoad = handleFileLoad;
  loader.onComplete = handleComplete;
  loader.loadManifest(manifest);
}
 
function handleFileLoad(o) {
  if (o.type == "image") { images[o.id] = o.result; }
}
 
function handleComplete() {
  exportRoot = new lib.bubbles();

  stage = new createjs.Stage(canvas);
  stage.addChild(exportRoot);
  stage.update();

  createjs.Ticker.setFPS(30);
  createjs.Ticker.addListener(window);

  setupBubbles();
}
 
function tick() {
  stage.update();
  for(var i = 0; i < bubbles.length; i++)
  {
    bubbles[i].update();
  }
}
 
function setupBubbles() {
  bubbles = [];
  setupSmallBubbles();
  setupMediumBubbles();
  setupLargeBubbles();
  setupHugeBubbles();
}
 
function setupSmallBubbles() {
  var BUBBLES = 25;
  var SCALE = 0.2;
  var SCALE_VARIANCE = 0.1;
  var SPEED = 1.3;
  var SPEED_VARIANCE = 1.0;
  var ALPHA = 0.2;
  var ALPHA_VARIANCE = 0.2;
 
  var bubble;
  for(var i = 0; i < BUBBLES; i++)
  {
    bubble = new Bubble(
      SCALE + (Math.random() * SCALE_VARIANCE),
      SPEED + (Math.random() * SPEED_VARIANCE),
      ALPHA + (Math.random() * ALPHA_VARIANCE)
    );
    bubbles.push(bubble);
    stage.addChild(bubble);
  }
}
 
function setupMediumBubbles() {
  var BUBBLES = 12;
  var SCALE = 0.3;
  var SCALE_VARIANCE = 0.1;
  var SPEED = 1.9;
  var SPEED_VARIANCE = 1.1;
  var ALPHA = 0.4;
  var ALPHA_VARIANCE = 0.3;
 
  var bubble;
  for(var i = 0; i < BUBBLES; i++)
  {
    bubble = new Bubble(
      SCALE + (Math.random() * SCALE_VARIANCE),
      SPEED + (Math.random() * SPEED_VARIANCE),
      ALPHA + (Math.random() * ALPHA_VARIANCE)
    );
    bubbles.push(bubble);
    stage.addChild(bubble);
  }
}
 
function setupLargeBubbles() {
  var BUBBLES = 6;
  var SCALE = 0.5;
  var SCALE_VARIANCE = 0.2;
  var SPEED = 3.1;
  var SPEED_VARIANCE = 1.5;
  var ALPHA = 0.7;
  var ALPHA_VARIANCE = 0.3;
 
  var bubble;
  for(var i = 0; i < BUBBLES; i++)
  {
    bubble = new Bubble(
      SCALE + (Math.random() * SCALE_VARIANCE),
      SPEED + (Math.random() * SPEED_VARIANCE),
      ALPHA + (Math.random() * ALPHA_VARIANCE)
    );
    bubbles.push(bubble);
    stage.addChild(bubble);
  }
}
 
function setupHugeBubbles() {
  var BUBBLES = 1;
  var SCALE = 1.0;
  var SCALE_VARIANCE = 0.2;
  var SPEED = 6;
  var SPEED_VARIANCE = 6;
 
  var bubble;
  for(var i = 0; i < BUBBLES; i++)
  {
    bubble = new Bubble(
      SCALE + (Math.random() * SCALE_VARIANCE),
      SPEED + (Math.random() * SPEED_VARIANCE)
    );
    bubbles.push(bubble);
    stage.addChild(bubble);
  }
}
</script>
</head>
 
<body onload="init();" style="background-color:#D4D4D4">
  <canvas id="canvas" width="640" height="480" style="background-color:#ffffff">
  </canvas>
</body>
</html>

Code Listing 1. Final version of the BubblesDev.html file.

function Bubble(scale, speed, alpha) {
  this.initialize();

  this.bubble = new lib.Bubble();
  this.addChild(this.bubble);

  // Set the scale, speed and alpha.
  this.scaleX = this.scaleY = scale;
  this.speed = speed;
  this.alpha = alpha;

  // Store the bubble's dimensions.
  this.width = this.bubble.nominalBounds.width * scale;
  this.height = this.bubble.nominalBounds.height * scale;

  // Setup the bubble's initial position.
  this.x = -(this.width / 2) + ((canvas.width + this.width) * Math.random());
  this.y = -(canvas.height / 2) + ((canvas.height * 2) * Math.random());

  // Setup an onPress event handler.
  this.bubble.onPress = this.bubbleClicked;
}
Bubble.prototype = p = new createjs.Container();

Bubble.prototype.update = function() {
  this.y -= this.speed;
  if(this.y < -(this.height / 2))
  {
    this.x = -(this.width / 2) + ((canvas.width + this.width) * Math.random());
    this.y = canvas.height + (this.height / 2) + (this.height * Math.random());
    this.visible = true;
  }
}

Bubble.prototype.bubbleClicked = function(e) {
  e.target.visible = false;
}

Code Listing 2. Final version of the Bubble.js class.

How To Make Better Games

I don’t get out anywhere near enough these days, so my boss sent me off to the Edinburgh International Technology Festival. I must admit, there was a great mix of presentations over the two days, but it was the gaming related talks that I found of most interest, and I’d like to share some of what I learned.

Over the last year or so at WeeWorld, we’ve become increasingly focussed on mobile games development, and I was curious to see if our approach to development was at all similar to what others do. So I was pleasantly surprised to hear from CEO of Denki, Colin Anderson, who gave a great overview of the process that they used when writing their hit iOS game, Quarrel. Reassuringly, it looks like my current project is following a similar path to Denki’s. There was also a huge number of great points from the many other speakers, which I’ll attempt to summarise along with Colin’s suggestions.

90% of games revenue is generated by less than 10% of releases

It’s a sobering thought, but the reality is that very few games actually make any money. There’s nothing more frustrating than spending 6-9 months writing a game that doesn’t sell. Even simple games are expensive to make, so it’s important that you do everything in your power to ensure you create a game that stands a fighting chance of actually recouping it’s costs and then some.

Find fun first

It may seem obvious, but when you hit upon an idea you have to make sure that its core element is fun. Be it in the real world or digital, making games starts with play. It’s a concept we’re all familiar with, as playing and having fun is something we all did as children. And we all invented our own games by making up rules as we played. Of course, some attempts were more successful than others, but games that didn’t engage or entertain us were quickly discarded and forgotten about.

Creating video games is really no different. Latch onto a simple concept that’s fun and then apply some rules. And remember, your ultimate goal is to design something for other people. So don’t be selfish; invent with others in mind. And if your idea isn’t fun from the beginning, then it probably never will be.

Fail fast but fail small

The quality of your game doesn’t guarantee success but it’s safe to assume that the better your game, the more chance it has of succeeding. Therefore, if it looks like you’re working on a stinker then it’s better to know this as soon as possible and move onto a different idea. Again think back to when you were a kid. You ever spend months refining a game idea that wasn’t working? Of course not, kids are pretty unforgiving and just quickly move onto something else. Games developers really should do the same.

Companies such as Denki takes this very approach. They evaluate their project at various key points and identify as early as possible whether or not their idea is worth continuing with. Here’s roughly how Denki went about developing Quarrel for iPhone:

  1. Started with a simple concept image and statement.
  2. Produced concept art
  3. Developed an internal prototype
  4. Developed an external prototype
  5. Game production

This approach provides ample opportunity to bail out if the idea isn’t working. Early steps in the process are fairly inexpensive compared to the later steps and also take considerably less time to complete.

I’m a great believer in rapid prototyping so it was great to see Denki working on two prototypes of Quarrel before committing to the final game. How a player will interact with your game in the real world will be entirely different to what they will do in your head. This point alone makes prototyping critical as you can relatively quickly determine whether it’s worth continuing with your idea. It also gives invaluable feedback that can be used to improve the final game or a second prototype if you choose to continue.

Creatives love to talk more than they like to listen

An audience member had stated that he’d worked with many excellent creative directors over the years, and that not one of them had managed to create a decent game. Speaker, Mark Sorrell, responding to this by saying rather controversially that “Creatives love to talk more than they like to listen”. There’s a lot of truth in what Mark said, but I think it extends to all of us.

It’s really important that you aren’t precious with your ideas. If something isn’t working then don’t be afraid to drop it, or at the very least attempt to change it. Of course, when you’re so close to a project, it’s not always easy to tell if something isn’t working, that’s why you really need to listen to others. You’ll get nowhere if you, or your team, decides to work in isolation.

At WeeWorld we’ve been making changes to our prototypes based on invaluable user feedback. For our earlier prototype that feedback was purely from those within the company. However, we’ve gradually opened that up to external play testers, which has lead to significant changes being made.

User testing is vital, but you still need to make sure you take that feedback on board. It’s all too easy to collect valuable information from user testing and then simply ignore it because it will lead to more work. You also need to learn how to sift through the noise. This is particularly important when you have performed a large number of user tests. You’ll need to focus and identify the common complaints rather than trying to address everything.

Ultimately don’t be afraid to admit when an idea of your own isn’t working. The worst thing you can do is push through an idea that negatively impacts a project. I know it sounds like common sense, but it’s something that most of us are guilty of.

It’s not about ideas. It’s about teams

This may sound surprising, but a project’s success is based more on the team that work on it rather than the idea. If you don’t believe me then ask Pixar’s John Lasseter who firmly believes in the power of team work and the importance of having the right people within your team. I also think it was Lasseter who also said he’d rather work with an A team with a B idea, than a B team with an A idea.

Angry Birds is a great example of this. The concept isn’t new and has been done so many times before, but the team at Rovio took the concept and expertly crafted it into something more. A less talented team may not have been able to apply the same level of execution and creativity to it.

It’s amazing what a great team can do with a relatively simple and straightforward game concept.

Conclusion

So there you have it, plenty of food for thought. To be honest what I’ve covered here is only a fraction of what was covered during the gaming session at the Edinburgh International Technology Festival. I’m sure however that even these morsels can help your write better games.

So does this mean that my current project will go onto be a success? Of course not, but through rapid prototyping, user testing, and working in a great team environment, we have at least guaranteed that what we have now is significantly better than what we started with. And believe it or not, many companies who don’t follow these simple guidelines won’t be guaranteed of that, and will instead choose to work blind for their project’s duration.

One More ‘Lost’ Recipe

There are many technical challenges when moving from desktop to mobile but the first thing that usually catches newbies out is the increased pixel density of compact mobile screens. When writing Flash iOS Apps Cookbook, pixel density was something I’d addressed in Chapter 4, Porting Flash Projects to iOS. However after reading the feedback from my technical reviewers and from various discussions with my editor, I decided to remove the material from the book. Basically, the content didn’t fit well within the book’s cookbook format, and it was felt that the recipe wasn’t practical enough for the readers.

If you’re new to mobile development then you should find the material valuable, which is why I’ve decided to make the original recipe available. Enjoy.

Understanding Pixel Density

While iOS devices have a smaller physical screen size compared to desktop monitors, they have a much higher pixel density. Pixel density is typically measured in pixels per inch (PPI) and indicates the amount of detail that can be shown on a screen. The higher the pixel density, the greater the detail that can be shown within a square inch. For example, while both the iPhone 3GS and iPhone 4 have the same physical screen size, the iPhone 4 has a superior pixel density, allowing it to display twice the number of horizontal and vertical pixels.

Pixel density can have a serious impact on your existing UI. Text may become illegible and users will typically find it difficult to interact with UI components such as buttons when using a smaller and more compact screen. Flash content designed to be viewed on a monitor will need to be re-designed for the screen resolutions of the iOS devices you decide to target. The pixel density of these devices should be a key consideration when doing this.

Whether you’re designing using an image editor such as Adobe Photoshop or authoring within Flash Professional, your desktop monitor’s lower pixel density can mislead you. Therefore it’s critical you frequently check your designs on target devices rather than relying solely on your monitor.

The easiest way to do this is to copy images to a device before viewing them at full-screen within its photo gallery. For this recipe however, we’ll write a very simple iOS app in Flash to let you view your artwork – it’s important you become comfortable editing content within Flash on a stage that looks physically larger than your target device’s screen. This recipe should help you with that.

Flash iOS Apps CookbookThis tutorial is a previously unreleased recipe from Flash iOS Apps Cookbook and supplements the content found in Chapter 4, Porting Flash Projects to iOS.
Flash iOS Apps Cookbook provides the recipes required to build native iOS apps using your existing knowledge of the Flash platform. Whether you want to create something new or simply convert an existing Flash project, the relevant steps and techniques are covered, helping you achieve your goal.

Getting Ready

An FLA and various graphics resources have been provided. Download this recipeโ€™s accompanying source bundle and use it as a starting point.

Open chapter4/recipe8/recipe.fla into Flash Professional. The FLA may appear empty but its AIR for iOS settings have already been applied, saving you the time and effort when you eventually need to build and deploy the recipe to a device.

How to do it…

Four concept images have been provided for your use.

  1. Select File | Import | Import to Library. From the Import to Library panel, browse to chapter4/recipe8/resources.
  2. Select the following files: game.png, loading.png, menu.png and paused.png. Click Open. All four images will be loaded and imported into your library.
  3. Create a keyframe for each image on Layer 1 of the timeline. Do this by selecting Insert | Timeline | Keyframe (F6) from the drop-down menu, three times.
  4. Move to frame 1 and drag loading.png from the library onto the stage. Using the Properties panel, set the bitmap’s x and y positions to 0.
  5. On frame 2, drag menu.png onto the stage and set its x and y positions to 0.
  6. Drag, game.png to frame 3 and paused.png to frame 4. Position both at (0,0) on the stage.
  7. Within the library, click on game.png, then hold Shift and click on paused.png to select all four bitmaps. Now right-click on one of the highlighted symbols and select Properties from the context menu.
  8. From the Editing Properties for 4 Bitmaps dialog box, select Lossless (PNG/GIF) from the Compression field’s drop-down box. Click the panel’s OK button.
  9. You now have four concept images laid out across your main timeline. Now all that’s needed is some ActionScript to allow you to move between the frames whenever the screen is tapped. Save the FLA.
  10. Create a document class for your FLA. Name the class Main and add the following code to it:
    package {
      
      import flash.display.MovieClip;
      import flash.events.MouseEvent;
      
      public class Main extends MovieClip {
            
        public function Main() {
          stop();
          stage.addEventListener(MouseEvent.CLICK,
            screenPressed);
        }
            
        private function screenPressed(e:MouseEvent):void {
          if(currentFrame == totalFrames)
          {
            gotoAndStop(1);
          }
          else
          {
            nextFrame();
          }
        }
      }
    }

    The above code is straightforward. The timeline is initially stopped on the first frame, with the playhead being moved on by one frame every time the stage receives a CLICK event. Once the end of the timeline is reached, the playhead is moved back to the start of the timeline, allowing the user to cycle through the images again.

  11. Save the class and when prompted name the file Main.as.
  12. Test you FLA using ADL (Control | Test Movie | in AIR Debug Launcher (Mobile)) to ensure there are no compiler errors. Finally publish your app for iOS.
  13. The FLA will be compiled and a file named c4-r8.ipa will be created. Deploy the file to your device and test it.

How it works…

With the app you’ll be able to cycle through the images by tapping the screen. As you examine the images, compare their physical size on your device with the versions sitting on the stage within Flash Professional. It’s unlikely that they’ll match.

Depending on your monitor’s current screen resolution and pixel density you’ll typically find that the stage is larger than your iOS device’s physical screen. This is especially true when working with the Retina display found on iPhone 4, 4th generation iPod touch, and iPad 3.

To further illustrate the point, change your stage size to match the iPhone 4’s screen resolution of 640×960. Import chapter4/recipe8/resources/menu@2x.png and swap one of the existing bitmaps on the stage with it. menu@2x.png is an image specifically designed for the iPhone 4’s screen resolution. It will most likely look huge sitting on your stage, but when deployed to an iPhone 4 the image will fit exactly within the iPhone’s 3.5-inch diagonal screen.

There’s more…

Now let’s talk about some other pieces of general information that are relevant to this recipe.

Adding additional images to the example app

You can easily add additional images to this recipe’s example app. Simply import the images to your library; create a keyframe for each new image; and drag the images onto the stage. No code changes are required.

Information density

Closely related to pixel density is information density, which describes the compactness of a user interface in terms of the amount of information.

Given the reduced size of mobile phone screens, you should consider how much information you can realistically display legibly. In most circumstances it will be significantly less than a desktop version of your application, even if the screen resolution of the iOS device you’re targeting is greater than the pixel dimensions of your desktop version.

Remember, mobile devices are often used on the move and under varying lighting conditions making it difficult to identify important information. When porting existing Flash applications to iOS you should redesign your UI to convey only the most important information to the user. Try reducing the amount of explanatory text, simplifying labels and maximizing the space between UI elements.

Additional information can be found within Apple’s iOS Human Interface Guidelines at developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/MobileHIG.

Copying images to the photo gallery

One of the quickest ways to test your designs is to simply copy them onto an actual device using iTunes.

First, ensure that the images you’re copying match the device’s screen resolution. Connect your device to your computer via USB and when iTunes launches, select your device from the DEVICES section. Click the Photos tab within the iTunes browser. From this page, click the Sync Photos from checkbox and select the folder where your images live. Once you’re ready, click the Apply button and the images will be copied to your device.

Once copied, move to the Photos app on your device and view your images in full-screen.

See also

AIR 3.4 Public Beta

I really must applaud Adobe for their really quick turnaround times for the AIR SDK. The public beta of AIR 3.4 is now available and includes some great new features. Being quite heavily focussed on iOS development myself, I’m delighted to see the following inclusions:

  • Direct AIR deployment using ADT (without iTunes)
  • Push Notifications for iOS
  • Ambient AudioPlaybackMode
  • iOS 5.1 SDK Support

My favourite feature is direct deployment, which is a real time saver. It’s great simply being able to install directly to your iOS device via a USB cable without having to go through iTunes or the iPhone Configuration Utility. It’s particularly useful when you’re performing small incremental changes with interpreter mode builds. Compiling and deploying your changes to the device takes only a few seconds now.

Another really exciting feature is support for Push Notification on iOS. Its inclusion seems like a real turn around for Adobe as they are clearly targeting a single platform (iOS), which in many respects goes against Adobe’s cross-platform goal. The API however looks generic enough that I’m guessing we’ll see support for notifications on Android eventually.

Perhaps the biggest new feature, and one developers have been crying out for, is the inclusion of ActionScript Workers. Yeah that’s right, ActionScript developers can now concurrently run background worker tasks in order to leverage more machine resources and avoid things like UI freeze. At the moment, Workers are restricted to the desktop.

For a full list of new features head on over to Adobe Labs and give the 3.4 SDK a spin.

Software Developer’s Journal

If you’ve noticed that my blogging has been less frequent the last few months, it’s because I was approached by Software Developer’s Journal magazine about taking on co-editing duties for their July issue. To be perfectly honest, I’d no previous experience as an editor but thought it would be a good opportunity to learn something new, and hopefully get to meet some new people.

I opted for a series of articles that would take Flash developers out of their comfort zone and explore two different areas that are a concern to them. The first of course is HTML5 and its relentless march towards ubiquity on the web. The second was gaming, which Adobe is now pushing Flash and AIR towards.

HTML5 is a controversial issue for many Flash developers but there’s a growing realisation that the days of getting by on ActionScript alone are over. So I opted for a few articles that were JavaScript heavy. The first helps ActionScript developers adapt their knowledge to JavaScript, while another detailed Flash Professional CS6’s support for the CreateJS framework, allowing designers to export timeline animations to HTML5. I also decided to explore other HTML5 alternatives to Flash Professional by providing another JavaScript heavy tutorial that focussed on using Adobe Edge to create interactive animations.

Moving back to Flash itself, I thought it would be a good idea to cover a few popular topics. The last few releases of Adobe AIR have made it a serious candidate for the creation of mobile and tablet games. While the AIR SDK certainly provides a rich API there are certain mobile-specific APIs that it currently doesn’t provide. Thankfully this is where AIR Native Extensions come in, allowing developers to extend AIR’s SDK to include features that aren’t provided out of the box. Unfortunately writing your first native extension isn’t easy, which is why I was delighted to be able to include the first of a two part tutorial detailing how to do just that.

Another hot topic at the moment is the Starling Framework, which allows for the creation of GPU-accelerated 2D graphics within your Flash games. I was fortunate enough to get the opportunity to interview Starling’s creator, Daniel Sperl, who provides some wonderful insight into Starling’s development and also provide some practical advice for developers wishing to utilize it. The final article took a look at Flash’s SWF file format, explaining what it all means and pointing you to some interesting tools that would help you get your hands dirty with some low level binary SWF manipulation.

I was extremely fortunate to find some fantastic developers who were willing to contribute these articles, and I genuinely learned a huge amount from working with them. So a huge shout out to the following individuals in no particular order: Ian Beveridge (@izb), David Wagner (@kaeladan), Daniel Albu (@danielalbu), Chris Gannon (@chrisgannon), Richard England (@englandrp), Daniel Sperl (@PrimaryFeather).

Flash Rocks

We use Flash a heck of a lot at WeeWorld. In fact, thanks to all those gorgeous vector graphics that Flash is so brilliant at, we don’t necessarily need to limit ourselves to a computer monitor. As part of a recent office refurbishment we decided to scale-up all our fantastic vector artwork, send it off to a printers, and stick the end result on our walls. And as you can see from the photos below, it looks fantastic!

Being greeted by a wall full of WeeMees really brightens your day.

I’m always amazed by what our artists can produce with Flash Professional. There’s an incredible amount of detail in each of the outfits they create, and sometimes that detail’s lost on a screen. So it’s great knowing that any visitors will be greeted by insanely high-quality WeeMee representations of every single person in our Glasgow office.

Like my WeeMee's Flash t-shirt? Pity I don't have one for real. Hint hint Adobe ๐Ÿ˜‰

Yup, Flash rocks!

Author Interview

I’m delighted to announce that an interview with my good self has been published on Packt Publishing’s Author Website. I talk about the writing process for my book and give some handy tips for anyone who’s thinking of writing their own book. Oh and a big thank you to my buddy Dave for taking the photograph of me that made it into the article.

Anyway, enjoy!

Aqualibrium, Matching Set, and Speedy Cups

Here’s three games all worth a look. I’ll be honest, Flash was only used in one of them but the other two were created by developers who know the Flash platform pretty well.

Speedy Cups

We’ll start with the Flash one. Developed by ShortCut Studio, this fun little game has you keeping track of the cup that has the ball underneath it. With only three cups on the table it might sound easy, but you’ll need the eyes of a hawk if you want to progress through the levels. With some funky music, a good sense of pace, and some really nice artwork, Speedy Cups shows how a simple game concept can be easily created using Adobe AIR and deployed across multiple handsets. Speedy Cups is free and can be downloaded from Apple’s App Store, and Google Play.

Matching Set

I’ve written about Dave Wagner before and it’s great to see him getting his first iOS game out there. Matching Set is a fast-paced pair matching game where you connect as many tiles as you can. Expertly executed and maddeningly addictive, you’ll find yourself coming back to this one time and again. Matching Sets is written in Objective-C, but if you’re curious there’s also, Rivers of Olympus, which is similar but written in ActionScript. Worth downloading both to see how they compare. If you can only purchase one then get Dave’s coz he’s a good friend and deserves your gaming time ๐Ÿ˜‰

Aqualibrium

My buddie Alex is a hardcore C engineer, and like Dave knows mobile devices inside out. In his spare time, Alex bashes together Xbox LIVE indie games. His latest is the rather excellent Aqualibrium, which is a port of the 32-bit Acorn Archimedes game called Cataclysm. The game has you attempting to save your submerged ship (the Orcna) from flooding by redirecting water into escape pipes. It’s great fun and you get to fly a jetpack too! If you’re a fan of old retro games then you’ll feel right at home with Aqualibrium.