logo
468x60-2-495


  • Home
  • Privacy Policy
  • About
search
top
Oct 26, 2011 Posted on Oct 26, 2011 in Hints and Tips | 10 comments

Create a Microphone-Controlled Flash Game: Design

This entry is part 1 of 1 in the series Create a Microphone-Controlled Flash Game

In this two-part mini series, you’ll learn how to create a Flash spaceship game, where the main control is via the microphone: shout louder to make your ship fly higher, to try to avoid the obstacles that appear on the screen. In this first part, we’ll focus on the design of the game, by drawing the main game objects and putting together the (mouse-controlled) menu and screen interface.


Final Result Preview

Here’s a look at the design of the game, which we’ll be putting together:


Creating the Graphics

Don’t like ads? Download the screencast, or subscribe to Activetuts+ screencasts via iTunes!

In this section, we’ll draw our game’s main graphical objects: a spaceship, a laser beam, a diamond, a meteor, a planet, and a star – all in the pixel art style seen in the SWF above, and all using Flash Pro.


Designing the Menus and Screens

Don’t like ads? Download the screencast, or subscribe to Activetuts+ screencasts via iTunes!

Here, we’ll create our menu interface, help screen, game over screen, and HUD.

Links mentioned in the video:

  • Abstract Font
  • Installing Fonts in Windows
  • Installing Fonts for the Macintosh

(Apologies for the weirdness that appears at around the 8:20 mark!)


Coding the Menu Interface

Don’t like ads? Download the screencast, or subscribe to Activetuts+ screencasts via iTunes!

Now that we have all of the graphical elements, we’ll write the code to make our menus interactive, and handle the navigation between screens.

More info on AS3 Events: Taking a Closer Look at the ActionScript 3.0 Event Framework.

Check back in a couple of weeks for the second part of the series, where you’ll learn how to program the actual game mechanics – including the microphone-based interaction!



View full post on Activetuts+

banner ad

10 Responses to “Create a Microphone-Controlled Flash Game: Design”

  1. Daniel Apt says:
    October 26, 2011 at 5:47 pm
    This entry is part 1 of 1 in the series Create a Microphone-Controlled Flash Game

    In this two-part mini series, you’ll learn how to create a Flash spaceship game, where the main control is via the microphone: shout louder to make your ship fly higher, to try to avoid the obstacles that appear on the screen. In this first part, we’ll focus on the design of the game, by drawing the main game objects and putting together the (mouse-controlled) menu and screen interface.


    Final Result Preview

    Here’s a look at the design of the game, which we’ll be putting together:


    Creating the Graphics

    Don’t like ads? Download the screencast, or subscribe to Activetuts+ screencasts via iTunes!

    In this section, we’ll draw our game’s main graphical objects: a spaceship, a laser beam, a diamond, a meteor, a planet, and a star – all in the pixel art style seen in the SWF above, and all using Flash Pro.


    Designing the Menus and Screens

    Don’t like ads? Download the screencast, or subscribe to Activetuts+ screencasts via iTunes!

    Here, we’ll create our menu interface, help screen, game over screen, and HUD.

    Links mentioned in the video:

    • Abstract Font
    • Installing Fonts in Windows
    • Installing Fonts for the Macintosh

    (Apologies for the weirdness that appears at around the 8:20 mark!)


    Coding the Menu Interface

    Don’t like ads? Download the screencast, or subscribe to Activetuts+ screencasts via iTunes!

    Now that we have all of the graphical elements, we’ll write the code to make our menus interactive, and handle the navigation between screens.

    More info on AS3 Events: Taking a Closer Look at the ActionScript 3.0 Event Framework.

    Check back in a couple of weeks for the second part of the series, where you’ll learn how to program the actual game mechanics – including the microphone-based interaction!


  2. Dru Kepple says:
    October 26, 2011 at 6:17 pm

    Twice a month, we revisit some of our readers’ favorite posts from throughout the history of Activetuts+. This week’s retro-Active tutorial, first published in October 2010, is an introduction to object-oriented programming in AS3. Don’t forget to check out the other AS3 101 tutorials!

    Object-Oriented Programming is a bit of a hot topic. More and more programming languages are cropping up that support it (Ruby, for example), and more and more languages that previously didn’t support Object-Oriented Programming (OOP for short) have been released with versions that do, like PHP and ActionScript. Some languages only work if you utilize the whole OOP thing to begin with, like Java and Objective-C.

    It’s actually been around for a long time, but came into the limelight in the 1990′s primarily due to its advantages with programming GUIs and the rise of C++ and Objective-C. Wikipedia has an interesting section on the history of OOP, which is a great place to start learning.


    Introduction

    If you’re new to Object-Oriented Programming, you have a bit of a learning curve ahead of you. However, embracing this technique isn’t just the “in” thing to do; it can decrease your development time while also decreasing the number of bugs in your code. It keeps you organized and prevents needless duplication. But perhaps more compelling than those lofty promises is the fact that Adobe has certainly put all of their weight behind the concept of OOP when it comes to ActionScript. ActionScript 1 was not Object-Oriented at all, and AS 2 was only Object-Oriented as a developer convenience. In contrast, AS 3 supports full-bore Object-Oriented features, and if anything, will only do more so in the years to come. So, if you like programming Flash and don’t want to get left behind, it would do you well to adopt OOP as a way of life.

    In this tutorial we will gradually introduce the some of the core concepts involved in Object-Oriented Programming. The final product coming out of Flash will be a bit lackluster, but this is just Part 1. You will see some practical explorations of OOP techniques, even if this tutorial isn’t really about building a specific project.

    You will, however, learn to make a reusable button which can be used in cases where a quick-and-dirty button is required, or even, with modification, as a key element to your next project.


    Step 1: The Big Question

    So what is this Object-Oriented Programming all about?

    First, let me explain what it is not. Object-Oriented Programming (or OOP for short) is not the only or even necessarily the best way to program in ActionScript 3. There seems to be a myth floating around ever since ActionScript 3 debuted that, in order to use AS3, you need to use OOP.

    While it’s true that AS3 is much better-suited to OOP than AS2 was, and that you are encouraged to move in that direction, it’s not true that you have to learn to write classes and instantiate objects in order to build real applications in Flash. If you’ve followed the AS3 101 series up until now, you may have noticed that every line of ActionScript 3 that we wrote in the process was in the script panel, not a class file. This should help illustrate that it’s perfectly acceptable to not utilize OOP as you work in Flash.

    That being said, ActionScript 3 really does shine when you start to embrace OOP. And not just AS3, but any language that supports OOP can be utilized more effectively when OOP techniques are engaged. This is because OOP is really just a technique – a big, complex technique with lots of options to consider, but still, just a technique – and not a mandate. And it is a great technique, one that you should start mastering. And that’s why you’re here, right?


    Step 2: Classes and Objects

    Object-Oriented Programming really boils down to two fundamental units: classes and objects. The two are intrinsically related: a class begets an object.

    Think of a class as a blueprint of a house, and an object as an actual house. The blueprint is more of a schematic for what the house will be like, not an actual house. When you write object-oriented code, you write the blueprints, the classes. Your code then creates the objects from these classes when it runs.

    A blueprint can also be re-used to create more than one house. In certain housing developments, you can see this in action; a cost-saving technique that pays the architect for one blueprint, but generates several houses from that blueprint. These houses are all unique entities, and what goes on in one house is isolated from what goes on in another house. However, they share a lot of features in common, such as the layout of the plumbing and the electrical wiring, or where the stairs are located. The houses may all have a front door at the same location, but one house might have a metal door painted red, and another house might have an unpainted wooden door with a knocker.

    A class, similarly, can create more than one object. These objects are all of the same type, but are all unique entities, like the houses. Again, they share many common features, but maintain separate identities. An object that loads data from an external source would have, as a common feature, the ability to load data and dispatch a complete event when it is ready. However, one instance of this loader would have a unique characteristic that loaded data from one URL, while another instance would load data from a different URL.

    The term instance is a word that describes an object. When an object is created from a class, it is said to be instantiated, and thus an instance of the class is born. The word object is typically synonymous with instance.

    If the terminology is troubling you, keep in mind the Library Symbol/Instance relationship that’s been around since Flash 1. A symbol is a single item in the library. An instance is a particular manifestation of that symbol. There can be more than one instance of a given symbol, and changes to a single symbol’s artwork will change all instance of that symbol. Yet each individual instance can maintain some unique properties, like position, rotation, color transformation, filters, and scale (to name but a few). This is directly analogous to class and objects (instances). In fact, it’s more than just analogous, as we’ll see in the next installment of this series.


    Step 3: Meet the Document Class

    Well, let’s jump in, shall we? I think the best way to get your feet wet in OOP AS3 is to become familiar with the document class. The document class is a class like any other in AS3, except that it has a very special relationship with a Flash file. It is the class that represents the SWF that you publish. The document class gets instantiated when the SWF starts up. This is analogous to the idea of a “main” function if you have a background in C, or the “main” method of the main class in Java.


    Step 4: Make a Project Folder

    Let’s make a document class, which will act as a basis for steps later in this tutorial. To do so, first create a folder on your filesystem that will house this particular project.

    Now make a Flash file (ActionScript 3.0), and save it to this folder. The name isn’t terribly important, but I’ll be naming mine MeetTheDocumentClass.fla


    Step 5: Document Class Text File

    Now you need to make a text file. You can use Flash CS3+ for this, or you can use Flex/Flash Builder, or you can use any other capable text editor, really. FlashDevelop is a great (and free) choice, if you’re on Windows. There are many choices in text editors, and there are no right answers (although, as I tell my students, there is one wrong answer. The text editor built into Flash CS3/4 is actually quite abysmal, and the sooner you embrace that fact the sooner you’ll enjoy coding in a real editor). Personally, I’m fond of TextMate, but keep in mind that what matters is the text within the file.

    All that being said, create a new file in the editor of your choosing (if you’re using Flash CS3+, go to the File menu, choose New, and then choose ActionScript File from the list. If you’re not, then I assume you’re familiar enough with your editor to be able to do this without direction from me).

    Save this file as DocumentClass.as in the same folder as your Flash file. This is important: the location and the name matter very much. The name doesn’t have to actually be “DocumentClass.as” but it’s what I’ll be using and to prevent confusion, I recommend you just do what I do. The name can be anything you want (more or less), but my point is that the name plays an important role in AS3 OOP, so be paying attention. Same deal with the location of the file; technically it can be anywhere but for convenience just follow my lead. More options will be revealed by the end of this series.

    To summarize, here’s my project folder as it stands:


    Step 6: Write the Document Class

    You are now faced with an empty file. If you’ve ever suffered writer’s block (I have, which regular readers might have guessed…), you can be comforted in the fact that the first thing you need to write is actually boilerplate. You’ll need to write the following:

    package {
    	import flash.display.MovieClip;
    	public class DocumentClass extends MovieClip {
    		public function DocumentClass() {
    
    		}
    	}
    }

    Wow, what is all that? Well, it’s a bit more than we need to explain right now. I’ll just point out a few places of interest.

    First, note that the package wraps up the entire thing. Don’t worry about what this is right now, just remember that it needs to be there, and the class needs to be contained within it.

    Second, we have an import statement. You may not have seen a line of code like this before; if you’ve stuck to coding in the Script panel up until now and haven’t made use of third-party ActionScript libraries, you’ve never needed to write an import statement. In OOP-world, each class needs to import the various classes it needs in order to do its thing. More on imports later.

    Third, the next “wrapper” is the class itself. You can see the keyword “class” in the third line. The anatomy of this line is more than we need right now, just note that the word following the word “class” is the name of the class. You may have noticed that the name I used is the same as the name of the file, sans extension. This is not a coincidence. For classes to work in AS3, the name of the class must match the name of the file. Don’t forget that.

    We’ll come back to the “extends MovieClip” bit in the next tutorial. For now, just know that this bit is required for a document class (you can also extend Sprite, a la “extends Sprite“, if you don’t need the timeline, and if you change the import line to “import flash.display.Sprite;“)

    Finally, we have the constructor.


    Step 7: The Constructor

    In the previous example, there is an (almost) normal function defined within the class. Almost normal, except for that “public” in front, and the missing datatype. Again, don’t worry about “public” for now, that’ll come in time. However, note the name of the function. That’s right, it’s the same as the file and as the class name. Hopefully you’re not overly paranoid, because this isn’t a conspiracy. It’s just the way things work. By naming the function with the same name as the class, we create a special function called the constructor. The constructor gets executed during instantiation. Hopefully you’re keeping up with the new terminology, because we just used two new terms in the same sentence. nerdCred++;

    An object will be able to have other functions in it, which you are welcome to define, but the constructor is the only function that gets called automatically during instantiation. The constructor, therefore, is where you would want to put code that should execute to get an object ready for initial use. For example, if you’re writing a class for an object whose job it will be to load some XML, parse it, then load thumbnail images based on that data, you might want to create a URLLoader, set up its event listener, and perhaps even start loading, all when you create the object. That logic could then go into the constructor.


    Step 8: Hello, World!

    As a practical example, we’ll do a little “Hello World” program. We won’t simply trace the words to the Output panel, no, that’s a little mamsy and definitely too pamsy. We’ll create a TextField, add it to the stage, and put some text into it. Expand your DocumentClass.as file to look like this (changes are in bold):

    package {
    	import flash.display. MovieClip;
    	import flash.text.TextField;
    	public class DocumentClass extends MovieClip {
    		public function DocumentClass() {
    			var tf:TextField = new TextField();
    			addChild(tf);
    			tf.text = "Hello World";
    		}
    	}
    }

    Note that in addition to the three lines added to the constructor, there is now an extra import line in anticipation of the TextField.

    We could obviously take it further, positioning and styling the text, and you’re welcome to do that on your own, but for now this serves the purpose. This code creates a text box with the words “Hello Word” in it, and displays it on stage. Except for one thing: The Flash file doesn’t know that it’s supposed to have a document class. If you try to run your Flash file now, you’ll get an empty window. Let’s fix that next.


    Step 9: Assigning a Document Class

    As mentioned at the end of the last step, the Flash file (MeetTheDocumentClass.fla in my case) doesn’t yet know that it has a specific document class associated with it. Technically, it does have a document class, only the document class is just plain old MovieClip, so it’s not going to do much.

    It’s good to know that, but what we really want right now is to let this Flash file know where the DocumentClass.as file we just wrote is. To do that, first make sure nothing is selected (you can click anywhere on the stage where there isn’t a visual asset, or you can choose Edit > Deselect All, or press Command-Shift-A or Control-Shift-A).

    Next, open up the Properties panel. If you’ve successfully deselected everything, the Properties panel should say “Document” at the top

    Now, where it says “Class:” under the “Publish” section of the Properties panel, type in “DocumentClass” (or whatever name you used for your version of the class, if you insist on forging your own path). Note that this is without the “.as” – it’s just the class name, not the file name.

    If you’ve followed along with the directions so far, you should be able to press Return/Enter and all will be well. If somehow you got the class name wrong, or didn’t save the files in the same folder, you won’t get an error when you publish. You should have gotten this error when typing in the class name:

    If you ignored it, or didn’t see it because you had previously checked that “Don’t show again” option, then the SWF will publish without error, but you’ll get a plain white screen. If this happens, double-check the class name that you’ve entered into the Properties panel.

    Once the document class is properly hooked up, you can verify that by clicking the little pencil icon next to the document class text field in the property panel. This will open up the file in Flash CS3+ for editing. Not that I’d recommend keeping it there, but verifying that you’ve got the right file can be a helpful troubleshooting tip.

    Once everything checks out, go ahead and test your movie. You should see a plain window with the words Hello World in it:


    Step 10: Properties

    At this point, you are set up to put your application logic into the document class and start making a more interesting SWF. However, you will likely need more than just the constructor function to make said interesting SWF. Usually you need to create other objects, stick them in variables, use functions to listen for events and have these things interact in a meaningful way. Of course, in OOP you have such things as variables and functions, only they properly go by different names: properties and methods (we’ll tackle methods in the next step).

    Properties are, at their essence, simply variables. There is a slight difference between a property and a variable, though. It’s subtle, and we’ll have to illustrate it with an example, but we have some ground to cover before we get there.

    First, a property is written identically to a variable, with two caveats. Here’s an example:

    private var tf:TextField;

    The first caveat should be obvious: there’s a big old “private” in front of the var keyword. “private” is similar to the “public” I asked you to ignore a few steps ago. I’m going to ask you to continue ignoring it. We won’t get to those until the next tutorial.

    The second caveat won’t be obvious, because the snippet is out of context. This is more appropriate:

    public class DocumentClass extends MovieClip {
    	private var tf:TextField;
    	public function DocumentClass() {
    		// ...
    	}
    }

    Notice the position of the property in relation to the structure of the class. The constructor function and the property are both at the same “level” and “belong” directly to the class (they are both nested into the class directly). This characteristic makes the variable a property (despite being declared by using the var keyword).

    In contrast, the variable named “foo” in the snippet below is merely a variable:

    public class DocumentClass extends MovieClip {
    	private var tf:TextField;
    	public function DocumentClass() {
    		var foo:String = "bar";
    	}
    }

    Why? Because it’s “owned” by the function, not by the class. When an variable or function gets declared within the confines of curly braces (which is technically every time), it exists for only as long the thing represented by the curly braces exists. So – and here is the subtle distinction – the property “tf” exists so long as the object “DocumentClass” is around, and “belongs” to a DocumentClass object, but the variable “foo” exists only as long as the function containing it runs, and ceases to exist once the function finishes executing.

    There are, naturally, exceptions to that “curly brace” rule. Loops, for instance, don’t affect the scope of a variable declared within, so take that rule with a grain of salt. You won’t find it mentioned in programming books.

    You might be asking,

    but wait, doesn’t the function exist in the object at the same level as the property? Doesn’t it exist just as permanently as the property, and therefore wouldn’t the variable inside the function exist as well?

    You have a point, however, the distinction is that the potential to run a function exists within the object, while the actually running function exists only at the moment it gets called. The variable gets created during the run, and therefore ceases to exist once the run is done. I did say the distinction was subtle. But it is important, as we’ll see soon.


    Step 11: Methods

    Before we get to that, I need to extrapolate what we just learned to functions and methods. Basically, methods are just functions that belong to an object, like the constructor function, only they aren’t elevated to any special status. Here, we added another method:

    public class DocumentClass extends MovieClip {
    	public function DocumentClass() {
    		// ...
    	}
    	public function onButtonClick(e:MouseEvent):void {
    		trace("click");
    	}
    }

    Now, onButtonClick() is a pretty familiar function, except for that pesky public at the beginning. Once again, put that off. Otherwise, you should recognize this as a regular function. The only difference is that the same concept of “ownership” applies to methods as it does to properties, versus regular variables and functions. Finally, let’s explore this with a working example.

    In your DocumentClass, we’ll flesh out the snippets we’ve seen. Make your class look like this:

    package {
    	import flash.display. MovieClip;
    	import flash.text.TextField;
    	import flash.events.MouseEvent;
    
    	public class DocumentClass extends MovieClip {
    
    		private var tf:TextField;
    
    		public function DocumentClass() {
    			tf = new TextField();
    			addChild(tf);
    			tf.text = "Hello World";
    
    			stage.addEventListener(MouseEvent.CLICK, onButtonClick);
    		}
    
    		private function onButtonClick(e:MouseEvent):void {
    			tf.text = "Hey, you clicked!";
    		}
    
    	}
    }

    Notice the changes and additions: We’ve added a property called “tf“. In the constructor, we still create a TextField, but instead of creating the variable in the constructor like we did before, we simply use “tf” – the property. Our TextField is now stored in the property instead of a variable.

    We also added a click listener to the stage (no, the stage isn’t really a button, but in this case it saves us from having to create a MovieClip to act as a button). And that listener is a method called onButtonClick(), and other than being a method instead of a function, it’s identical to any other event listener.

    What this method does is significant: it replaces the text in the textfield with another string. This can only happen if tf retains it value over time. If the movie worked, then we know tf still references the TextField created in the constructor, even though several seconds probably passed between the creation of the TextField and the re-population of it.


    Step 12: Exploring Scope

    Now, if you remove the property and return the TextField creation to be a variable, you actually won’t even be able to test it, as the compiler will give you an error saying it couldn’t find a property called tf. That is, this code:

    package {
    	import flash.display.MovieClip;
    	import flash.text.TextField;
    	import flash.events.MouseEvent;
    
    	public class DocumentClass extends MovieClip {
    
    		//private var tf:TextField;				//we have removed this line!
    
    		public function DocumentClass() {
    			var tf:TextField = new TextField();
    			addChild(tf);
    			tf.text = "Hello World";
    
    			stage.addEventListener(MouseEvent.CLICK, onButtonClick);
    		}
    
    		private function onButtonClick(e:MouseEvent):void {
    			tf.text = "Hey, you clicked!";
    		}
    
    	}
    }

    Produces this error:

    What happened? Well, in ActionScript, a variable created in one function exists for the duration of the function (which is over a few lines later), and is gone once the second function runs. So if we create a variable tf in the constructor function and try to use it in the onButtonClick() function, we have a problem. tf no longer exists when onButtonClick() runs.

    However, properties persist throughout the life of an object, so if we store the TextField in a property instead of a variable, we have access to that TextField in other functions, at pretty much any time.

    In this context, variables are sometimes referred to as local variables because they are local to the function.

    And this is the subtle point that started this marathon step. Hopefully it sunk in, because I find this point to be the cause of many “gotchas” for beginning OOP students.

    Keep in mind that there is more going on with properties, methods, persistence and references. I feel I’ve belabored the point enough, and won’t be doing you any favors by dissecting the finer points of references and delaying other essential knowledge.


    Step 13: About That Button…

    OK, in the last step I skipped the creation of a button and just used the stage as a clickable area. We’ll change that, but not because clicking on the stage is wrong (it isn’t, in certain circumstances), but because we can create a Button class to further explore OOP.

    Our goal will be to create a Button class, from which we can create multiple Button objects. Each Button object will have some core functionality that is universal across buttons:

    • Hover and normal states
    • The cursor turns to a hand icon
    • A graphic background with a text label

    At the same time, there will need to be things unique to each button:

    • The text of the label
    • The click action
    • The position of the button

    We’ll look at what it takes to create a second class involved in your project and incorporate these requirements as we go.


    Step 14: Create a Button Class

    We’ll create a class that, when instantiated, draws a rectangle, puts text into a label, handles roll overs and outs, and can respond to clicks. Start by creating a new text file in your text editor. Save it as “Button101.as” in the same folder as your Flash file. This is important. Don’t mess it up! I’m serious.


    Step 15: Write the Boilerplate

    In your new file, start stubbing in the class boilerplate:

    package {
    	import flash.display.Shape;
    	import flash.display.Sprite;
    	import flash.events.MouseEvent;
    	import flash.text.TextField;
    	import flash.text.TextFormat;
    
    	public class Button101 extends Sprite {
    
    		public function Button101() {
    
    		}
    
    	}
    }

    Step 16: Add Some Properties

    Next we’ll add some properties to hold the background shape and the label:

    	// ...
    	public class Button101 extends Sprite {
    
    		private var bgd:Shape;
    		private var labelField:TextField;
    
    		public function Button101() {
    		// ...

    The bgd property will hold a reference to a Shape which we’ll draw programmatically to be a filled rectangle, and add as a child of the Sprite.

    The labelField property will hold a reference to a TextField which we’ll create with code, as well, and use to display a text label on top of the background.


    Step 17: Add the Logic

    And now we’ll pop in the actual logic. For the constructor:

    public function Button101() {
    	bgd = new Shape();
    	bgd.graphics.beginFill(0x999999, 1);
    	bgd.graphics.drawRect(0, 0, 200, 50);
    	addChild(bgd);
    
    	labelField = new TextField();
    	labelField.width = 200;
    	labelField.height = 30;
    	labelField.y = 15;
    	var format:TextFormat = new TextFormat();
    	format.align = "center";
    	format.size = 14;
    	format.font = "Verdana";
    	labelField.defaultTextFormat = format;
    	addChild(labelField);
    
    	addEventListener(MouseEvent.ROLL_OVER, onOver);
    	addEventListener(MouseEvent.ROLL_OUT, onOut);
    
    	mouseChildren = false;
    	buttonMode = true;
    }

    That’s a lot of code, but it’s nothing surprising for the most part. We’re creating a new Shape and drawing a rectangle to into it. Then we create a TextField, set it up with some basic formatting. Next up, we add some rollover and rollout events (the listeners for which we’ll add in the next step). Finally we set some properties to make the object behave more like a button.

    The only part that might be causing confusion is the call to addChild(), and where the mouseChildren and buttonMode properties came from. I’ll ask you to yet again wait for a more complete answer, as that will come in the next installment, but it has a lot to do with the “extends Sprite” we wrote earlier.


    Step 18: Add Some Methods

    Now, we can continue working on our class. After the constructor, create a function called setLabel:

    public function setLabel(label:String):void {
    	labelField.text = label;
    }

    And finally, create the two event listeners:

    private function onOver(e:MouseEvent):void {
    	bgd.alpha = 0.8;
    }
    private function onOut(e:MouseEvent):void {
    	bgd.alpha = 1;
    }

    The final code should look like this:

    package {
    	import flash.display.Shape;
    	import flash.display.Sprite;
    	import flash.events.MouseEvent;
    	import flash.text.TextField;
    	import flash.text.TextFormat;
    
    	public class Button101 extends Sprite {
    
    		private var bgd:Shape;
    		private var labelField:TextField;
    
    		public function Button101() {
    			bgd = new Shape();
    			bgd.graphics.beginFill(0x999999, 1);
    			bgd.graphics.drawRect(0, 0, 200, 50);
    			addChild(bgd);
    
    			labelField = new TextField();
    			labelField.width = 200;
    			labelField.height = 30;
    			labelField.y = 15;
    			var format:TextFormat = new TextFormat();
    			format.align = "center";
    			format.size = 14;
    			format.font = "Verdana";
    			labelField.defaultTextFormat = format;
    			addChild(labelField);
    
    			addEventListener(MouseEvent.ROLL_OVER, onOver);
    			addEventListener(MouseEvent.ROLL_OUT, onOut);
    
    			mouseChildren = false;
    			buttonMode = true;
    		}
    		public function setLabel(label:String):void {
    			labelField.text = label;
    		}
    		private function onOver(e:MouseEvent):void {
    			bgd.alpha = 0.8;
    		}
    		private function onOut(e:MouseEvent):void {
    			bgd.alpha = 1;
    		}
    	}
    }

    One thing that is very important is to make sure your methods are declared at the class level. This is another rookie mistake: sometimes people don’t pay attention to where their curly braces start and stop, and end up nesting what should be a method (that is, declared at the “root level” of the class) inside another method. This effectively turns a method (which should persist for the life of the object) into a local function (which only persists for the life of the running method in which it was declared).

    Hopefully compiler errors will notify you of such a mistake, but the error itself might be cryptic. It would say “1114: The public/private/protected/internal attribute can only be used inside a package.” If you get that, check the nesting level of your methods. Another thing to help prevent these errors is to pay careful attention to whitespace and indentation. A “real” text editor can help you with this, but just make sure all of your method declarations are at the same indentation level (typically two tab stops).

    What we have now is a class ready roll, which, when instantiated, will create a customized display object that has a gray rectangle with a label. The label can be set using a method and the button will automatically respond to mouse roll overs and roll outs. All we need to do is actually instantiate it.


    Step 19: Create a Button

    Step back to your document class, and we’ll add a button to the movie. This will be pretty easy compared to the previous step.

    First, we’ll add a new property to hold the button. Stick it below the line with your existing property.

    private var tf:TextField;
    private var button:Button101;

    It’s not required to put all properties together, but for the organization of your file, it’s helpful to keep things in consistent places. Personally, I always list properties at the very top of the class, before the constructor. This way, I always know where to go to find a property declaration. Where they go in the file isn’t as important as coming up with your own standard and sticking to it.

    Moving on, we can now instantiate the Button101 in the document class’s constructor:

    public function DocumentClass() {
    	tf = new TextField();
    	addChild(tf);
    	tf.text = "Hello World";
    
    	button = new Button101();
    	button.x = 10;
    	button.y = 200;
    	button.setLabel("Button 1");
    	addChild(button);
    	button.addEventListener(MouseEvent.CLICK, onButtonClick);
    
    	//stage.addEventListener(MouseEvent.CLICK, onButtonClick);		//we have removed this line
    }

    Note that we modified the line that set up a listener for clicks on the stage. We’re shifting that interactivity to the button.

    Now, you may be wondering how it is that we’re treating this Button101 object as if it were a Sprite or MovieClip (see the AS3 101 tutorial on the Display List if you weren’t wondering that). This has everything to do with that extends business I’ve asked to gloss over for now. I promise, we’ll get to it soon (in the next part of this series).

    At this point, we should be able to test it out. It should work similarly as before, except that you’ll see the button appear, and instead of clicking anywhere on the stage, you need to click on the button.

    For reference, here is the complete document class at this point, with additions and changes in bold:

    package {
    	import flash.display.MovieClip;
    	import flash.text.TextField;
    	import flash.events.MouseEvent;
    
    	public class DocumentClass extends MovieClip {
    
    		private var tf:TextField;
    		private var button:Button101;
    
    		public function DocumentClass() {
    			tf = new TextField();
    			addChild(tf);
    			tf.text = "Hello World";
    
    			button = new Button101();
    			button.x = 10;
    			button.y = 200;
    			button.setLabel("Button 1");
    			addChild(button);
    			button.addEventListener(MouseEvent.CLICK, onButtonClick);
    
    		}
    
    		private function onButtonClick(e:MouseEvent):void {
    			tf.text = "Hey, you clicked!";
    		}
    	}
    }

    So, what did that accomplish us? The big thing is that we got a pretty nifty button that we could use with very little effort (not counting the effort put into writing the Button101 class in the first place).

    To accomplish the same functionality without classes and OOP, we’d have to write considerably more code in our main script. To illustrate this further, let’s create a second button.


    Step 20: Create Another Button

    OK, now let’s let OOP really shine. We’ll create a second instance of the button, merely by adding a few more lines of code to the document class.

    The changes involved will be extremely similar to the previous step. First, add a property:

    private var tf:TextField;
    private var button:Button101;
    private var button2:Button101;

    Then set it up in the constructor:

    public function DocumentClass() {
    	tf = new TextField();
    	addChild(tf);
    	tf.text = "Hello World";
    
    	button = new Button101();
    	button.x = 10;
    	button.y = 200;
    	button.setLabel("Button 1");
    	addChild(button);
    	button.addEventListener(MouseEvent.CLICK, onButtonClick);
    
    	button2 = new Button101();
    	button2.x = 220;
    	button2.y = 200;
    	button2.setLabel("Button 2");
    	addChild(button2);
    	button2.addEventListener(MouseEvent.CLICK, onButtonClick);
    }

    You can, in fact, just copy and paste the first button’s lines of code and just change button to button2, and also the x position of the second button (otherwise button2 will sit right on top of button1).

    We’ve doubled the complexity of our application in just a few short lines of code, thanks to the reusability of the Button101 class. We have the class, which, if you remember, is the blueprint from which the actual instances are created. We now have two distinct buttons, yet they share that common “heritage.” Even though there are many characteristics that are the same between these two buttons, like the rollover effect and the size, there are still aspects of individuality, namely the position.

    Hopefully this starts to illustrate the usefulness and power of Object-Oriented Programming, in which we facilitate the reuse of code very easily.

    Go ahead and test it out; you should have two buttons that do the exact same thing.

    Naturally, you’ll probably want to tweak the Button101 class so that it looks fancier, or has a slicker roll over effect, or what-have-you. By all means, take the Button101 class and make it more useful for your own needs. Our goal here was to demonstrate how a button class can be made, not to make the ultimate button class.


    Step 21: Summary

    There were two main themes in today’s tutorial. To recapitulate, these are: the idea of blueprints (classes) and houses (instances); and the notion of scope.

    Classes are the code files that we write, as well as the concept of an entity that serves as the blueprint for the objects that will get created from them. One class can beget any number of instances. Objects are the instances of classes, and tend to be the things that, when put together, comprise our application. Instances of the same type share functionality in common, but retain unique identities and can possibly contain variances in the data contained within.

    Scope is an important concept through all of programming, and no less so in Object-Oriented Programming. Scope determines the “life span” of a variable or function, and also a “place to live.” A variable at the object scope has a different life span than a variable at the method scope.


    Until Next Time

    This is, however, just scratching the surface of the tip of the iceberg. It’s all we have time for right now, but in the soon-to-be-published Part 2 of the AS3101 OOP series, we’ll dive a little deeper and finally get an explanation on all of things I was asking to put aside, like extends and public. Things will begin to make more sense. But when it comes to a complicated topic like Object-Oriented Programming, it’s best to take things slow.


  3. Activetuts+ Editor says:
    October 26, 2011 at 6:36 pm

    Fans of the Activetuts+ Facebook page can now access a new bonus tutorial – in this month’s Facebook Fan Bonus, you’ll learn how to remove the background color from a sprite sheet using AS3, and blit the result to a bitmap canvas.

    Final Result Preview

    Here’s a look at the kind of effect you’ll be working towards in this tutorial:

    Blitting in Flash: removing background

    Download This Fan Bonus Now!

    All you have to do is Like us…


    Not On Facebook?

    Don’t worry, the tutorial will be posted on Activetuts+ in a month’s time!


  4. Anthony Lombardo says:
    October 26, 2011 at 7:31 pm

    I can’t tell you how many articles and tutorials I have come across on how to use symbols in Flash that immediately dismiss the graphic symbol as having no practical purpose, relegating it as just a step above grouping items. This article will attempt to dispel this myth by showing that the graphic symbol actually has some pretty cool and convenient features and knowing how and when to utilize them is a nice tool to have when you’re creating animations in Flash.

    I first began using Flash with version MX. And through all the enhancements and added features in every release, one thing that has remained constant is the graphic symbol. But what has also remained constant, surprisingly enough, is how many Flash users don’t know what the graphic symbol actually does. Somewhere along the line, this symbol has received a bad rap as being totally useless. If you’ve ever wondered what exactly the purpose of the graphic symbol is and why the heck Adobe continues to keep it in Flash, this article is for you.


    The Basics

    We’ll start off with the most known and basic of things you can do with the graphic symbol that are inherent to all Flash symbols. Just like movie clips and buttons, a graphic symbol can have color effects applied to it like alpha and tint, get broken apart into its comprising elements via CMD/CTRL-B, and of course have its properties motion-tweened.

    I know that’s far from a revelation, but I mention these attributes because I think it’s important to keep in mind that a graphic symbol at its core is just like any other Flash symbol but with its own unique set of features.


    Animation Misconceptions

    One of the biggest misconceptions about the graphic symbol is that it cannot contain animation – or that, if it does, Flash will just ignore it at runtime. Not only is that completely untrue, but in actuality graphic symbols are very powerful and flexible when it comes to creating timeline animation.

    Just like a movie clip, a graphic symbol can contain nested animations on top of nested animations of other graphic symbols and movie clips. It is the symbol of choice used by most professional Flash animators, especially when it comes to creating complex timeline animation with lots of vector assets. Let’s see why.


    Animation and the Properties Panel

    The true power of the graphic symbol lies within the Properties panel. This is where you can control the animation inside a graphic symbol, which is one of the hidden, unknown jewels in Flash. The approach that I am about to detail is really an animation technique referred to by many as the Chris Georgenes method.

    If you’re not familiar with Chris Georgenes, he is a well-respected Flash animator who innovated this approach to animating with graphic symbols and I was lucky enough to take a character animation course he was the instructor of. I highly recommend you read up on many of his Flash animation techniques and tricks.

    graphic symbol properties panel

    That’s enough background information so let’s get cracking with the good stuff. When you create a graphic symbol (Modify > Convert to Symbol), you have three options for handling how the symbol will play back its animation; to see them, with the symbol selected, go over to the Properties panel and look under the Looping category.

    When you click on the Options drop-down, you will be presented with three options to choose from: Loop, Play Once and Single Frame. Also below the drop-down, you’ll see a small input field labeled ‘First’. Before we get to that, let’s understand the three looping options – but keep that little input field in mind as we go through each option as it will all tie together.

    Note: If you don’t see the Options field, just click on the arrow to the left of Looping to reveal the drop-down.

    looping options of a graphic symbol

    Loop: Loop is the default setting for every new graphic symbol that is created. Basically this option will constantly loop any and all animation that is nested inside it. So in other words, the symbol’s timeline will play through its duration and then start over again, just like a movie clip.

    Play Once: This setting is pretty self-explanatory as well. It will play the symbol’s timeline once through and then stop. Think of it as the graphic symbol’s way of adding a stop() action on the final frame of its timeline.

    Single Frame: Single frame allows you to display only a certain frame within the symbol’s timeline. Whereas the symbol’s timeline is actually playing when it’s set to Loop or Play Once, the Single Frame option just jumps the timeline to a specific frame within the symbol and stays there. I like to think of it as the graphic symbol’s version of using gotoAndStop(frame). So how is this done? If you’re recalling that tiny input field labeled ‘First’ that I told you to keep in mind a few paragraphs back, you’re heading in the right direction.


    First Frame Input Field

    Though very ambiguous and easily unnoticed, this input field is where all the fun happens for controlling the timeline of a given symbol. This is one of my favorite features of the graphic symbol because you can target a specific frame on the symbol’s timeline by typing a frame number in the input field.

    When a graphic symbol is first created, the first frame input field is set to 1 by default – as denoted by the 1 inside the field. This means frame 1 on the symbol’s timeline will be the first frame the animation will begin on. That’s where the label First comes in; think of it as the first frame you want to display or the first frame you want to play from. So if you have a symbol set to Single Frame and type 6 in the first frame field, it will display whatever is on frame 6. If the supplied frame number is blank or if the symbol doesn’t even have that many frames in its timeline, then nothing will display.

    You can also use the first frame field with the Loop and Play Once options. If you set a symbol to Play Once and type in a certain frame number in the input field it will start from that frame. The same applies if you set it to loop. The symbol would begin to loop starting with the frame number you supplied in the input field. Keep in mind though that if you typed in 6, it will start to loop from frame 6 but once it reaches the end of the timeline it will continue to frame 1 in its usual manner.


    But It Still Isn’t Animating

    Now, if you took it upon yourself to try any of this out within Flash, you’re probably wondering why your animation isn’t playing in the manner I’ve been describing. Open up the file named looping_basics.fla in the source package. Double-click the graphic symbol that is on the stage to check out the animation that’s inside of it. You’ll see two layers spanning 239 frames on the timeline, with a new keyframe on both layers every 30 frames (i.e. every second). So if you scrub the play head, you’ll see we basically have an 8-second animation in which on every second the number in the center increments by one and the circular background changes color. By all means nothing fancy.

    After you have the gist of the animation, return to the main timeline, click on the graphic symbol and check the properties panel to make sure the symbol is set to Loop and 1 in the first frame field. Now test out the movie.

    What’s going on here? Our symbol isn’t animating even though we have it set to Loop. Right about now you might want to say you told me so about Flash just ignoring a graphic symbol’s animation. Before you do so, let’s get to the bottom of this.


    It’s All About the Timeline

    This is the common pitfall most people experience when they create an animation inside a graphic symbol. And it’s probably the reason why the symbol is thought of as useless. You create an animation on the graphic’s timeline then position the symbol on the main timeline just like you would with a movie clip. But when you go to export your movie, the symbol just sits there static on the stage. This is where the misconception lies: we are expecting the graphic symbol to behave just like a movie clip.

    The trick to the graphic symbol is that it is timeline driven – meaning its own timeline coincides with the timeline the symbol is placed on. So if it’s placed on the stage, it needs just as many frames on the main timeline as it has on its own timeline in order to play the animation in its entirety. In other words, whereas a movie clip will play independently of the timeline, a graphic symbol will be played only as far as its parent’s timeline will allow it.

    In a nutshell, a graphic symbol needs frames.

    Give It Some Frames

    If you go back to our example in Flash, the reason our graphic symbol isn’t playing is because there is only one frame on the main timeline. So let’s add some frames. Just for demonstration purposes, go to frame 30 and add frames. Now go to frame 60 and do the same. Do you see what’s happening here? Then go to frame 90. Very cool, huh? Keep adding as many frames as you want and test the movie. You should see the animation begin to play, depending on how many frames you have on your main timeline. Remember our symbol has 239 frames on its timeline, so in order to see the entire animation, there needs to be the same amount on the main timeline.

    Note: Keep in mind this principal we’ve been discussing doesn’t just apply for the main timeline. The timeline that the graphic symbol is actually placed on will dictate its playback. So for example, if your graphic is inside a movie clip, you need frames on the movie clip’s timeline to render the graphic’s animation. Try it out yourself.

    Automatic Playback

    As you probably noticed from the example file, you can actually see the graphic symbol animate as you scrub the timeline from the stage. Yes, very cool. This brings us to another unique feature that differentiates a graphic symbol from a movie clip and you’ll probably find it to be its most useful. Since the graphic symbol is timeline driven, a benefit of that is having your animation automatically update within Flash. As long as you have ample amount of frames on the timeline where your symbol is located, you can always see your graphic symbol animate live.


    Case Study: Facial Expressions

    Let’s explore these techniques a little more to give you another look on how you can incorporate a graphic symbol into a project. Open up the file named facial_expressions.fla that’s in the source package. You will be greeted with a nice smiling face on the stage that was part of an illustration for an animated character I created a few years back.

    character creation graphic symbols

    If you click on the symbol, you’ll see it’s a graphic with a library name of expressions, and that it is set to Single Frame 1. Go inside the symbol and you’ll see three layers: eyes, mouth and head, each of which contain graphic symbols. The head layer contains all the other elements that comprise this little guy’s smiling face, and if you unlock the layer and double-click the symbol you’ll see are all graphic symbols as well. For our purposes, though, we are going to be focusing on the graphic symbols for the mouth and eyes. Go inside the mouth symbol and you’ll see it contains various different mouth shapes at various points on the timeline, and the same goes for the eyes. Let me point out that the left and right eyes are instances of the same exact symbol.

    Go inside both the mouth and eye symbols and take a look around. You’ll notice that I have a frame labels layer corresponding to each facial expression and that I chose to put each of them on a keyframe that are 10 frames apart. There’s no reason for having the timeline set up like this other than it’s my own way of trying to keep it clean and organized. I probably wouldn’t use the frame labels in ActionScript (though I could if I converted my graphic to a movie clip) but having a label for every new expression lets me know at a glance where a certain expression is on the timeline. And besides giving me some space so the labels can actually be read, the 10 frame gap between each keyframe simply makes it easy for me to remember where a new mouth or eye expression occurs on the timeline.

    Now jump back one level to the expressions graphic where we just have our three layers of the mouth, eyes and head, and start using these symbols to create some animation. There’s a lot of different ways you can set things up here, depending on what you want to do, but let’s just keep it simple and make our guy blink.

    Insert a new frame on all three layers. Check that both the mouth and eye symbols are set to Single Frame 1 and then insert a new keyframe on the eyes layer and set both eyes to Single Frame 10.

    Go back to the stage, give yourself about 45 or so frames, make a new keyframe on frame 30 and change the 1 in the first frame field to a 2. Remember your keyframes should be set to Single Frame. Now test it out and your guy should be blinking. I know that’s nothing fancy but the point here isn’t so much about what can be created with the graphic symbol, but rather about the convenience and flexibility it provides you. We’ll get to more on this in a bit but hopefully this example has your gears turning.


    When Would You Use a Graphic Over a Movie Clip?

    Personally, any time I am working on a project that calls for creating numerous timeline animations, I consider using the graphic symbol. Any Flash user who has ever spent countless hours tinkering with numerous movie clips that all contain their own animations has probably run into a situation where they wish they could pinpoint where something was occurring on a certain movie clip’s timeline from another spot in the movie. From my own experience, there have been many times in which I have an animation inside one movie clip and want to use it within another clip but needed to know when a certain point in my animation was reached so I can have something else happen. I would have to resort to a tedious process of jumping back and forth between movie clips and counting frames so I could figure out where to place it on that second clip’s timeline. Using my animation as a graphic would allow me to see everything without having to export my entire movie.

    properties panel movie clip graphic

    Tip: Even when I am using a movie clip for a timeline animation, I sometimes temporarily set it as a graphic in the properties panel just so I can view the animation playback while other objects are animating around it. I can then get a better sense of the overall timing and do some tweaks; when I’m done, I set it back to act as a movie clip.

    To do this, just click on your symbol, go to the top of the Properties panel and click on the drop down. This is where you can change your symbol’s behavior on the fly, toggling it between a movie clip and a graphic. This is very useful when you want to use the same symbol as both a movie clip and a graphic throughout your project. Note: This technique will not work if you try to change between a movie clip and a button or between a graphic and a button.


    Practical Uses

    Here are some other practical uses of when you might want to consider using a graphic symbol:

    Animated Presentations: Presentations are the projects where I find myself using graphic symbols the most. Most flash presentations tend to be heavy on animation and syncing visuals to a script. The graphic symbol lends itself well to projects like these that are in linear in nature and have limited user interaction.

    Syncing audio with an animation: This is an extension of the previous point. Anytime you want pinpoint synchronization between a sound and an animation, running your audio alongside your animated graphic symbol will give you that type of control. Many voiceover presentations that I have been involved in have employed animated graphic symbols.

    flash presentation design

    Character animation: Anytime you are going to create intricate animations with vector artwork that has lots of layers, the graphic symbol is the way to go. Many cartoon animations have been made with flash and I would bet anything that if you were to examine the FLA they were made in, the library would be packed to the brim with graphic symbols. Just like facial expressions, creating sequences for walk cycles and lip syncing sequences are ideal jobs for using the graphic symbol.

    Creating multiple variations of a symbol: We already touched on this notion throughout the article but I think it’s worth further explanation. If you recall in our facial expressions example from earlier, the mouth and eye graphic were used to house all our different mouth and eye shapes for easy animating. Well, sometimes I use the graphic symbol to just hold a bunch of similar movie clips that are just slightly different, or what I like to refer to as poses.

    In some cases, I’m not looking to sequence these poses for an animation like in the facial expressions example but to act as a holder of my elements, which will simplify the process of accessing them later on. I find it much easier to refer to each pose if they are all on their own frame inside a graphic instead of having to sift through one long movie clip timeline with numerous layers. All I have to do is target the frame number of the one I want inside the first frame field like we did in the facial expressions example. And if I need to control any of my poses with actionscript, I just turn my graphic into a movie clip.


    Limitations

    The graphic symbol is not without its limitations and drawbacks. While the graphic symbol can be very useful in certain situations, by no means am I advocating it as a replacement to the movie clip. In most situations, a movie clip will be your symbol of choice and will do just fine even for creating most timeline animations. Here are some things to keep in mind when using the graphic symbol:

    Can’t be controlled by ActionScript: This is an obvious point but it’s a biggie. Unlike a movie clip, you can’t assign a graphic symbol an instance name and any script you place on its timeline will be ignored. Keep in mind though you can still use a movie clip that has ActionScript on its timeline as a graphic and it will play back normally.

    Can’t apply filters: For some reason, Flash doesn’t allow you to apply any of the filters or blending modes to a graphic symbol. To get around this, you can simply put your graphic symbol inside a movie clip and then apply the filter to the clip.

    classic tweening graphic symbol

    Classic tweening graphic symbols with nested animation can be problematic: This is one I learned the hard way and it’s an issue that can happen quite easily without you even realizing. Let’s say you have a graphic symbol with a pretty involved animation inside it, and you want to tween the symbol on the main timeline from left to right across the stage as your nested animation plays. You create your first keyframe on the timeline and you set it to Play Once starting on frame 1 in the Properties panel. When you create your second keyframe, Flash will automatically set it to Play Once and update the first frame field accordingly with the correct frame number in sequence.

    So using the above example if your first keyframe is on frame 10 on the main timeline and your next keyframe is on frame 40, the graphic symbol on this frame would be set to Play Once with the first frame field already set to 30. Get it? It inserted the frame number you left off from? Now if you were to add or delete frames within the tween, the symbol on that second keyframe will still have 30 set as its first frame to play from thus completely throwing off the order of your nested animation. It’s just something to keep in mind; when you initially create keyframes, the first frame number will update correctly, but once you start moving keyframes up and down the timeline, things will get thrown off.

    Note: This only applies to classic tweens. If you are using the method for creating motion tweens that was introduced in Flash CS4, this won’t be an issue.


    Conclusion

    Hopefully after reading this article you have a different opinion of the graphic symbol. Though it may not be something you can see yourself using all that frequently, the thing to keep in mind with the graphic symbol is that it’s about knowing when to use it. As a developer, I don’t use it all that often but I know I have it as an option if the situation calls for it. Like with most things in Flash, it comes down to a matter of personal preference. If you pick and choose your spots wisely, using the graphic symbol can be convenient and a time-saver.

    I know a lot was covered in this article, but the best way to really understand what the graphic symbol can do is to spend some time playing around with it in Flash. Change its looping options, target different frame numbers to start your animation on and toggle back and forth between using it as a graphic and a movie clip to really see what works and what doesn’t. So maybe the next time you hit F8 and you are planning on creating a timeline animation, remember the graphic symbol might not be that useless after all.


  5. Joseph Clover says:
    October 26, 2011 at 8:23 pm

    In this Quick Tip, you’ll learn how to construct a reference to a class from a String, and then create an instance of that class, using a built-in AS3 function called getDefinitionByName(). You’ll also learn the best methods for using this in different situations.


    Why Is getDefinitionByName() Useful?

    getDefinitionByName() is very useful if you need to make new instances of classes by using a String. For example, if you had seven different tiles – each represented by a class called Tile1, Tile2, etc – and you needed to create an instance of each, you would have to write the following code:

    
    
    private function createTiles():void
    {
    	var tile1:Tile1 = new Tile1();
    	var tile2:Tile2 = new Tile2();
    	var tile3:Tile3 = new Tile3();
    	var tile4:Tile4 = new Tile4();
    	var tile5:Tile5 = new Tile5();
    	var tile6:Tile6 = new Tile6();
    	var tile7:Tile7 = new Tile7();
    	stage.addChild( tile1 );
    	stage.addChild( tile2 );
    	stage.addChild( tile3 );
    	// You get the idea, it is very lengthy!
    }
    

    getDefinitionByName() allows you to solve this problem!


    How to Use It

    Now, the above code was a little messy and we had to type many lines just to make a few different tiles. This is how we could achieve the same goal using getDefinitionByName():

    
    
    private function createTiles():void
    {
    	for( var i:int = 1; i < 8; i++ )
    	{
    
    		var tileRef:Class = getDefinitionByName( "Tile" + i ) as Class;
    		var tile:tileRef = new tileRef();
    		stage.addChild( tile );
    
    	}
    }
    

    In line 6, getDefinitionByName() returns a reference of the class called “Tile + the current value of i in the for-loop“. So, when i is equal to 1, getDefinitionByName("Tile" + i); returns a reference to the class Tile1. We then create the tile and add it to the stage.

    However, when you run this code, it will not work! You’ll get a variable is undefined error message, in most cases, because “Tile1″ might not be enough information for Flash to find the class. Let’s look at some workarounds.


    Make It Work

    There are a few commonly-used methods to solve the problem of the variable is undefined error you’ll get when you run the above code, and I am going to teach you what they are. I would also like to give credit to Gert-Jan van der Well of Floorplanner Tech Blog for this blog post.

    Here are some of the methods you can use:

    • Use a Dummy Variable
    • Use short notation of Class name
    • Include the full path in the String
    • Include the class’s SWC in your project

    Using a Dummy Variable

    In this method, you just create some dummy variables with references to the classes you want to refer to with getDefinitionByName() later:

    
    
    private var dummyTile1:Tile1;
    private var dummyTile2:Tile2;
    //etc
    
    private function createTiles():void
    {
    	//Create the tiles
    }
    

    This works, but it is very ugly. If you have the Tile classes in another package, you would also have to import them!

    Short Notation

    This is much like the Dummy Variable method, but you don’t bother setting up a dummy variable for each class; you just drop a few explicit references to the classes themselves:

    
    
    Tile1;Tile2;Tile3;Tile4;Tile5;Tile6;Tile7;
    //etc
    
    private function createTiles():void
    {
    	//Create the tiles
    }
    

    Now, this may look neater, but the fact that you will have to update this list everytime you make a new Tile remains.

    Including the Full Path Name

    Another method, which is the tidiest (if you have classes in another package) is to include the full path name in your String:

    
    
    //Let's say my Tiles are all in the package 'project.Tiles'
    
    private function createTiles():void
    {
    	for( var i:int = 1; i < 8; i++ )
    	{
    
    		var tileRef:Class = getDefinitionByName( "project.Tiles.Tile" + i ) as Class;
    		var tile:tileRef = new tileRef();
    		stage.addChild( tile );
    
    	}
    }
    

    Much tidier! However, this only works if the classes are in a separate package from this class.

    Using a SWC

    If the Tiles are held in an SWC, you can make this much easier, without needing to use any imports or dummy variables. I would like to give credit to v0id from Dreaming in Flash for this blog post that explained to me how to use this method:

    • In the project properties choose “ActionScript Compiler”
    • To the “Additional compiler arguments” field, add the following: include-libraries PATH_TO_SWC

    The PATH_TO_SWC must be the absolute path and not the relative path!

    Great, all these methods have now been explained. Unfortunately, there are no fantastic magical methods to use if you have all the tiles in the same package as all the other AS Files. I would recommend you make a new package called Tiles or something if you want to use the good methods!


    Conclusion

    Well, today you should have learnt how to use getDefinitionByName() and the best methods of using it. I hope this will help you in any future projects and if you have any questions, leave them in the comments section below!


  6. Jordan McNamara says:
    October 26, 2011 at 8:47 pm

    Hey folks! I’m Jordan McNamara, the Community Manager for Envato and I wanted to share some exciting news with you about the Envato Marketplaces.

    The 12th of September was an exciting day for me as a member of our thriving Marketplace community. I along with everyone here at Envato HQ watched eagerly as the global Marketplace member count steadily grew higher and higher and higher…

    We were close, very close to the 1,000,000 member milestone. With every page refresh the count grew higher and I began to reflect on just how staggering having 1,000,000 members really is and on just what a fantastic community everyone has helped to build here.

    I remember starting at Envato in 2009 and being blown away by the 250,000 or so accounts that were registered at the time. I bragged to all of my friends “Can you believe there’s a quarter of a million members!?”. Little did I know in just under two and a half years I would be writing this post!


    View the Infographic!

    To celebrate this exciting occasion we wanted to do something interesting and fun that celebrates the Marketplace community and the sites themselves. So with that in mind, we are proud to present the 1,000,000 Members Infographic! We’ve packed it full of fascinating facts and data about our members and our nine Marketplaces.

    Click to Jump to the Infographic!

    Every day we continue to be amazed at the astonishing speed our community of creative members grows. We’ve enjoyed every minute of the journey and are proud and thankful of the achievements our members have made. Here’s to the next million!

    View the Infographic!


  7. Ashish Bogawat says:
    October 26, 2011 at 8:51 pm

    Designers vs. developers – it is an argument as old as computers. The truth is, though, neither can live without the other. A brilliant UI design is as worthless without functionality as is the best piece of code with an ugly, unusable frontend. In this first post on UI Basics for developers, I am going to try and lay out some simple ground rules that devs can follow to make sure their apps, templates and prototypes are as beautiful as the code itself – and usable to boot.

    Think: the first impression is the last impression.


    Alignment

    Alignment refers to the position or orientation of an element in relation to another element or to itself. When we refer to two elements being aligned to each other, alignment usually refers to which side of both elements is in line. In the context of text, alignment refers to the side to which text is anchored in a straight line.

    Form Design

    Alignment of form fields

    In the image above, the second example of a simple form design shows labels that are right-aligned to each other with input fields that are left-aligned. This ensures that the association between each label and its input field is clear and the user does not get confused if some labels are too small while others are long.

    Think: Make sure input fields are not too far away from the longest label. If the variation in width is small, try right-aligning labels and left-aligning input fields.

    Text

    Text alignment

    For text, it is ideal to use left-alignment when desiging for the screen. Since most for-screen type rendering methods are incapable of distributing space appropriately when justifying text to both sides, left alignment keeps text readable and well organized. You can, of course, use center and right alignment where the design demands it, but those are usually reserved for special cases and smaller chunks of text.


    Flow

    The primary purpose of any user interface is to let the user interface with the application. This, believe it or not, is not going to be possible unless you tell the user what he needs to do and in what order. Since you won’t be there behind every user to help them out with this, the interface needs to provide all the cues. Here are some questions to ask when evaluating whether the intended workflow is appropriate:

    • How critical is it that the task be performed in a set order of steps?
    • Is it obvious to the user where to start and what to do next?
    • Is the intended outcome stated or implied – implicitly, if not explicitly?
    Search with category selection n iStockPhoto

    Let’s take the example of a search category selection on iStockPhoto. In this case, I can either search everything or select a specific category to limit my searches to that type of information. Since the primary act is to enter a search term and hit Search, those should be fairly obvious. A possible step in between is to select a category, which can be a drop-down list between (you guessed it right) the search field and the Search button.

    The income/expense entry dialog in cashbase

    Another example is the income/expense input dialog in the cashbase app. The fields are arranged according to the typical workflow one will use to log such information: enter the amount (which is the most important element), select a category, add a note if necessary, and click Add. Secondary information that will be used much less frequently – like the date which by default is today, and the option to repeat or cancel – are available, but much more subtle.

    Further reading:

    • Designing for Flow

    Proximity

    Related elements in an interface should be grouped together. This might sound like common sense when I mention it, but it is not always well understood. The reason all page navigation links on most websites are laid out in a single horizontal bar, is so that the user can identify the relationship at a glance and make the choice to interact with them without any confusion.

    The message toolbar in Gmail

    Let’s look at this example from Gmail – an app that many of use on a regular basis. This is the toolbar that appears at the top when you open a mail. Although all those buttons perform some action on the open message, they are further grouped together based on what they do – actions one would use to get rid of the message (archive, spam, delete), to change the importance of the message (when using priority inbox), label-related actions, and finally a drop-down with secondary options.

    Feature grouping in Zootool

    Another example of good use of proximity is the options bar in Zootool. The toolbar at the bottom is divided into three sets, each corresponding to the three panes in the app: the list packs on the left, the mail window in the center which contains all your bookmarks, and the details pane on the right.

    Further reading:

    • Proximity in Design: Why I can’t use my car’s A/C
    • Design Basics: Proximity (Or Why Skype’s "End Call" Button Is All Wrong)

    Hierarchy

    Not everything in a user interface, or any layout for that matter, carries the same importance as everything else. Hierarchy is the arrangement of elements in a way that denotes what is higher in order, what comes next, and so on.

    A layout with no sense of hierarchy within elements

    Let’s look at this example here and try to identify what the order of precedence is. Since everything – titles, labels and paragraph text – looks the same, one has to read through everything to make sense. If the same interface was tweaked just a little bit like below, the overall impact on the readability and in turn the usability of the interface is enormous.

    The same layout with a better sense of hierarchy

    As a general rule, the page heading should be biggest and most visible on the screen. This is followed by section titles, sub-titles and then smaller labels. Paragraph text can be more or less prominent depending on its purpose. It is also not limited to text. Primary action buttons can be differentiated from secondary actions by making them brighter, bigger or fancier. Input fields for mandatory inputs can be made more obvious than the others. I could go on, but I think you get the idea.


    Contrast

    Another very important consideration when designing interfaces is to ensure clear differentiation between elements. Of course, you want the text to be readable on the background, but contrast goes beyond simply using light text on a dark background or vice versa. Headings and paragraph text should be clearly distinguishable. Panels and navigation bars need to be segregated from each other so the user knows what is what. The list goes on.

    Contrast can be established using one or more of the following characteristics:

    Color

    This should be obvious, but its amazing how often people slip on this point. If your background is light, you obviously want the text to be dark to ensure readability. Although in theory complimentary colors should work well together, it is not always that easy. Try placing bright green text on a red background and you will know what I’m saying.

    Good & bad examples of contrast

    The possibilities here are limitless, so my first recommendation to anyone looking to select colors is to pick up a popular color palette from sites like Adobe Kuler or ColourLovers. They are contributed, evaluated and voted up by passionate users who usually know their way around color. All the basics of color matching and contrast are usually taken care of, so its just a matter of deciding which color scheme works in your app’s context.

    Browsing through color palettes on Kuler & ColourLovers

    One note of caution though – be very wary of going overboard with color. You don’t want them to overshadow the utility and usability of your app.

    Size

    Another good way to differentiate between elements – based on hierarchy, categorization, or visual flow – is to use different sizes. This applies to text as much as it does to images, backgrounds and static or interactive elements. You may want to put more emphasis on the primary action button, for example, and keep the secondary buttons comparatively less accessible. Or optional prompts can be smaller and lighter than the primary labels in a form.

    Yesterday, today and tomorrow in Teuxdeux

    The TeuxDeux app does a brilliant job of using color to differentiate between past, present and future days. Since the layout is geared towards a work week, different sizes of text are used to make sure that names of days are easy to identify, while the dates are comparatively more subtle.


    Interaction

    Since the primary purpose of any user interface is to enable users interact with the app, it is imperative that learners intuitively know what to do. As creators of the interface, it is very easy to forget that you won’t be there for every user to tell them what to do. Neither do users have the patience any more to read manuals and quick start guides before diving into using an app. The interface is required to make it amply clear what parts of it are clickable, touchable, draggable – in short, interactive.

    Everyone knows how to flick an electrical switch, right? The thing that makes it obvious to anyone that a switch needs to be pressed at a certain point to change state is called affordance. On the flat surface of a screen – desktop, mobile or otherwise – different techniques can be utilized to enable users intuitively click a button or type inside an input field. When creating text hyperlinks, adding an underline for the link is the most commonly used standard, although there are many other creative ways to do that.

    Here are some examples:

    Each interactive element has a different interaction objective, and therefore a different visual treatment

    Going with the switch example, how do you know if flicking the switch did what it was supposed to do? The light comes on or goes off, or in some cases a light inside the switch helps make it clear whether the switch is on or off.

    In an application, such feedback can be very obvious in cases where a button navigates to another page or opens a popup, but what about situations where all it does is process some data in the background – like when saving changes to the user settings? Some sort of a feedback mechanism is critical to let users know their action was successful. This could be as simple as a "your settings were saved" message, a brief notification at the top of the page, or a quick highlight around the area that was updated.

    Two-level feedback in Remember the Milk

    When you add a new task in Remember the Milk, it can either appear in the list on the same page, or simply get added to another list in the background (if, for example, the task has been assigned to a different category). The feedback for the action is therefore provided at two levels:

    1. a green highlight appears for a couple of seconds behind the task in the list to point to where it has been added, and
    2. a very prominent message appears on a yellow background at the top of the page letting the user know what exactly happened.

    Typography

    The text in your app – everything from the logo to the titles, labels and copy – is your primary mode of communication with the users. Since it is how your users access information about the app or through it, how you set the type can mean the difference between success and failure. Of course titles have to be bigger than body text and the fine print has to be, well, fine; but a lot of other decisions also influence how users consume information.

    Fonts

    Step one: define your fonts. It surprises me how many developers simply never bother to change whatever font their text gets generated in. Default fonts change from OS to OS and browser to browser, which means that unless you explicitly state what font you want to use, your text is going to look different in every OS and browser combination. Besides, Times New Roman – which a lot of browsers still use as the default font – is just not a good font for on-screen reading. My first recommendation is often to use a sans-serif font, although Georgia or the new Cambria font in Windows 7 also look good.

    Sans-serif fonts make a big difference to the readability of text over Times New Roman

    If you decide to use fonts other than the safe, universally available ones like Arial/Helvetica, Georgia, Tahoma etc., make sure there is a way to have them render similarly on all platforms. If Flash is your development environment of choice, embed them where necessary. For HTML/JS based apps, use @font-face in CSS or any of the web font services like Typekit or Google WebFonts. Remember though, that these techniques come with a caveat of extra file sizes for the embedded fonts. If speed and responsiveness are paramount for you, sticking to the base fonts is your best bet.

    Disclaimer: Yes, I do know that Arial and Helvetica are not exactly similar, but they are similar enough for most users to not notice the difference.

    Leading

    The amount of space between two lines of text is the leading. You want the leading of your paragraph text (line-height in CSS speak) to be at least 140% of the font size to make sure it is easily readable. Any less and your text is going to be much harder to read and – more imporantly – to scan through.

    Text leading makes a huge difference to the readability of your text

    Localization

    If you plan to translate your app into oither languages – and you really should – it is best to test the interface early on with different scripts. At the very least, the amount of space a certain message requires can vary drastically across different scripts. The East Asian scripts use fewer words on an average but need a bigger font size, Indian (Indic) scripts also need to be slightly bigger to be readable and middle-eastern scripts (like Arabic) go from right to left instead of the usual left-to-right.

    Wrapping Up

    That’s about it for now. I hope these tips covered enough basics for you to start applying them in your projects right away. As with most design-related disciplines, there are no hard and fast rules to follow, and everyone has their own take on how things should work. So if you disagree with any of my suggestions above – or even if you agree with them but have a different perspective – let’s hear about them in the comments.

    Next up, we will take all of this wisdom and try applying it to an actual interface. Stay tuned!


  8. Michael James Williams says:
    October 26, 2011 at 9:06 pm
    This entry is part 3 of 3 in the series Box2D for Flash and AS3

    In the first two parts of this series, we created two simple types of object, rendered using Flash’s display list. In this part, we’ll see how to extend this to let us create as many different types of object as we want, without our code getting all tangled up!

    I recommend reading this series from the start, but if you want to start here, then grab this zip file — it contains the source code from the end of the the second part. (The Download button above contains the source code from the end of this part.)


    Step 1: New Balls Please

    Let’s take a quick look at where we left off:

    Bunch of wheels and crates bouncing around. The wheels don’t all have the same properties; each wheel has a random size, restitution, friction, and density. Ditto for the crates.

    That’s been fine for testing, but now let’s make things a little less random. We’ll start by replacing the wheels with tennis balls, which all have the same properties.

    First, draw a tennis ball (or get a photo of one). Here’s mine:

    To make yours consistent with mine, make sure that it’s called TennisBall.png, that you save it in \lib\, that it’s 35x35px, and that it has a transparent background. (You can change any of these points, if you wish, but you’ll have to figure out how to modify your code accordingly.)

    Embed the PNG into your Main.as file, just like we’ve done before:

    
    
    [Embed(source='../lib/TennisBall.png')]
    public var TennisBall:Class;
    

    Now, create two arrays: one for your tennis ball Box2D objects, and one for the corresponding images:

    
    
    public var tennisBallArray:Array;
    public var tennisBallImages:Array;
    
    
    
    tennisBallArray = new Array();
    tennisBallImages = new Array();
    

    (This is all much the same as we did in the second part of this series, so take another look at that if you need a refresher.)

    Now we need a function to create a single tennis ball. Here’s what we use to create a single wheel:

    
    
    private function createWheel(mRadius:Number, pxStartX:Number, pxStartY:Number, mVelocityX:Number, mVelocityY:Number):void
    {
    	var wheelBodyDef:b2BodyDef = new b2BodyDef();
    	wheelBodyDef.type = b2Body.b2_dynamicBody;
    	wheelBodyDef.position.Set(pxStartX * pxToM, pxStartY * pxToM);
    	var wheelBody:b2Body = world.CreateBody(wheelBodyDef);
    	var circleShape:b2CircleShape = new b2CircleShape(mRadius);
    	var wheelFixtureDef:b2FixtureDef = new b2FixtureDef();
    	wheelFixtureDef.shape = circleShape;
    	wheelFixtureDef.restitution = (Math.random() * 0.5) + 0.5;
    	wheelFixtureDef.friction = (Math.random() * 1.0);
    	wheelFixtureDef.density = Math.random() * 20;
    	var wheelFixture:b2Fixture = wheelBody.CreateFixture(wheelFixtureDef);
    
    	var startingVelocity:b2Vec2 = new b2Vec2(mVelocityX, mVelocityY);
    	wheelBody.SetLinearVelocity(startingVelocity);
    
    	wheelArray.push(wheelBody);
    
    	var wheelImage:Bitmap = new SimpleWheel();
    	wheelImage.width = mRadius * 2 * mToPx;
    	wheelImage.height = mRadius * 2 * mToPx;
    	var wheelSprite:Sprite = new Sprite();
    	wheelSprite.addChild(wheelImage);
    	wheelSprite.x = pxStartX;
    	wheelSprite.y = pxStartY;
    	wheelImages.push(wheelSprite);
    	this.addChild(wheelSprite);
    	wheelSprite.addEventListener(MouseEvent.CLICK, onClickWheelImage);
    }
    

    We can copy this and modify it to our needs. Since all tennis balls will have the same properties (size, restitution, friction, and density), we don’t need the mRadius argument, and we don’t need to use random numbers anywhere. It’s hard to guess what values of restitution and so on will be correct, so just have a go – we can always correct them later.

    Here’s my createTennisBall() function:

    
    
    private function createTennisBall(pxStartX:Number, pxStartY:Number, mVelocityX:Number, mVelocityY:Number):void
    {
    	var tennisBallBodyDef:b2BodyDef = new b2BodyDef();
    	tennisBallBodyDef.type = b2Body.b2_dynamicBody;
    	tennisBallBodyDef.position.Set(pxStartX * pxToM, pxStartY * pxToM);
    	var tennisBallBody:b2Body = world.CreateBody(tennisBallBodyDef);
    	var circleShape:b2CircleShape = new b2CircleShape(35 * .5 * pxToM);
    	var tennisBallFixtureDef:b2FixtureDef = new b2FixtureDef();
    	tennisBallFixtureDef.shape = circleShape;
    	tennisBallFixtureDef.restitution = 0.8;
    	tennisBallFixtureDef.friction = 0.75;
    	tennisBallFixtureDef.density = 1.0;
    	var tennisBallFixture:b2Fixture = tennisBallBody.CreateFixture(tennisBallFixtureDef);
    
    	var startingVelocity:b2Vec2 = new b2Vec2(mVelocityX, mVelocityY);
    	tennisBallBody.SetLinearVelocity(startingVelocity);
    
    	tennisBallArray.push(tennisBallBody);
    
    	var tennisBallImage:Bitmap = new TennisBall();
    	var tennisBallSprite:Sprite = new Sprite();
    	tennisBallSprite.addChild(tennisBallImage);
    	tennisBallSprite.x = pxStartX;
    	tennisBallSprite.y = pxStartY;
    	tennisBallImages.push(tennisBallSprite);
    	this.addChild(tennisBallSprite);
    	//tennisBallSprite.addEventListener(MouseEvent.CLICK, onClickWheelImage);
    }
    

    A few things to note:

    • The b2CircleShape() constructor is expecting to receive the radius of the tennis ball, in meters, and I don’t want to squash or enlarge the image I’ve made. I guess I could look up the radius of an actual tennis ball, enter this value in here, and alter the pxToM scale factor to make everything else fit, but instead I’ve just told the constructor to convert the pixel radius of my tennis ball image to meters.
    • Restituion is the bounciness of the object, on a scale of 0 to 1; tennis balls are pretty bouncy so I’ve set this quite high.
    • Friction is also between 0 and 1; tennis balls are quite rough so I set this fairly high, too.
    • Density is not limited to any particular range; tennis balls are mostly air, so I set this to the same value as my crates (which I’m also assuming are empty).
    • Unlike in createWheel(), there’s no need to resize the image (as I mentioned above), so I’ve deleted those lines.
    • I’ve just commented the onClickWheelImage event listener out for now, as it’s not relevant.

    Try to compile the SWF. It should work – if it didn’t, you missed something out – but since we aren’t actually calling createTennisBall() from anywhere, nothing will be different.


    Step 2: Creating Tennis Balls

    Let’s just remove the wheels straight away, and replace them with tennis balls. Change this code, in getStarted():

    
    
    for (var i:int = 0; i < 20; i++)
    {
    	createWheel(
    		Math.random() * 0.5,
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createCrate(
    		Math.random() * 1.5,
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	)
    }
    

    …to this:

    
    
    for (var i:int = 0; i < 20; i++)
    {
    	createTennisBall(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createCrate(
    		Math.random() * 1.5,
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	)
    }
    

    Note that the first argument has been deleted, since we don’t manually set the size any more, but all other arguments remain the same. Try it out:

    Hmm… not quite right. Ah, of course – we didn’t add any code to render the tennis balls. We’ll do that next. Change onTick() from this:

    
    
    private function onTick(a_event:TimerEvent):void
    {
    	world.Step(0.025, 10, 10);
    	world.DrawDebugData();
    
    	var wheelImage:Sprite;
    	for each (var wheelBody:b2Body in wheelArray)
    	{
    		wheelImage = wheelImages[wheelArray.indexOf(wheelBody)];
    		wheelImage.x = (wheelBody.GetPosition().x * mToPx) - (wheelImage.width * 0.5);
    		wheelImage.y = (wheelBody.GetPosition().y * mToPx) - (wheelImage.height * 0.5);
    	}
    
    	var crateImage:Sprite;
    	for each (var crateBody:b2Body in crateArray)
    	{
    		crateImage = crateImages[crateArray.indexOf(crateBody)];
    		crateImage.x = (crateBody.GetPosition().x * mToPx);// - (crateImage.width * 0.5);
    		crateImage.y = (crateBody.GetPosition().y * mToPx);// - (crateImage.height * 0.5);
    		crateImage.rotation = crateBody.GetAngle() * radToDeg;
    	}
    }
    

    …to this:

    
    
    private function onTick(a_event:TimerEvent):void
    {
    	world.Step(0.025, 10, 10);
    	world.DrawDebugData();
    
    	var tennisBallImage:Sprite;
    	for each (var tennisBallBody:b2Body in tennisBallArray)
    	{
    		tennisBallImage = tennisBallImages[tennisBallArray.indexOf(tennisBallBody)];
    		tennisBallImage.x = (tennisBallBody.GetPosition().x * mToPx) - (tennisBallImage.width * 0.5);
    		tennisBallImage.y = (tennisBallBody.GetPosition().y * mToPx) - (tennisBallImage.height * 0.5);
    	}
    
    	var crateImage:Sprite;
    	for each (var crateBody:b2Body in crateArray)
    	{
    		crateImage = crateImages[crateArray.indexOf(crateBody)];
    		crateImage.x = (crateBody.GetPosition().x * mToPx);// - (crateImage.width * 0.5);
    		crateImage.y = (crateBody.GetPosition().y * mToPx);// - (crateImage.height * 0.5);
    		crateImage.rotation = crateBody.GetAngle() * radToDeg;
    	}
    }
    

    (It’s really just a case of doing a find-and-replace, switching “wheel” to “tennisBall”.) Try the SWF now:

    Better, but we don’t have any rotation (we didn’t need it before, because the wheels were all rotationally symmetric). Add that now:

    
    
    var tennisBallImage:Sprite;
    for each (var tennisBallBody:b2Body in tennisBallArray)
    {
    	tennisBallImage = tennisBallImages[tennisBallArray.indexOf(tennisBallBody)];
    	tennisBallImage.x = (tennisBallBody.GetPosition().x * mToPx) - (tennisBallImage.width * 0.5);
    	tennisBallImage.y = (tennisBallBody.GetPosition().y * mToPx) - (tennisBallImage.height * 0.5);
    	tennisBallImage.rotation = tennisBallBody.GetAngle() * radToDeg;
    }
    

    Ah. Remember we had this problem with the crates? Remember how we solved it? Have a go at doing the same here, on your own. My solution is below if you want to check:

    
    
    private function createTennisBall(pxStartX:Number, pxStartY:Number, mVelocityX:Number, mVelocityY:Number):void
    {
    	var tennisBallBodyDef:b2BodyDef = new b2BodyDef();
    	tennisBallBodyDef.type = b2Body.b2_dynamicBody;
    	tennisBallBodyDef.position.Set(pxStartX * pxToM, pxStartY * pxToM);
    	var tennisBallBody:b2Body = world.CreateBody(tennisBallBodyDef);
    	var circleShape:b2CircleShape = new b2CircleShape(35 * .5 * pxToM);
    	var tennisBallFixtureDef:b2FixtureDef = new b2FixtureDef();
    	tennisBallFixtureDef.shape = circleShape;
    	tennisBallFixtureDef.restitution = 0.8;
    	tennisBallFixtureDef.friction = 0.75;
    	tennisBallFixtureDef.density = 1.0;
    	var tennisBallFixture:b2Fixture = tennisBallBody.CreateFixture(tennisBallFixtureDef);
    
    	var startingVelocity:b2Vec2 = new b2Vec2(mVelocityX, mVelocityY);
    	tennisBallBody.SetLinearVelocity(startingVelocity);
    
    	tennisBallArray.push(tennisBallBody);
    
    	var tennisBallImage:Bitmap = new TennisBall();
    	var tennisBallSprite:Sprite = new Sprite();
    	tennisBallSprite.addChild(tennisBallImage);
    	tennisBallImage.x -= tennisBallImage.width / 2;
    	tennisBallImage.y -= tennisBallImage.height / 2;
    	tennisBallSprite.x = pxStartX;
    	tennisBallSprite.y = pxStartY;
    	tennisBallImages.push(tennisBallSprite);
    	this.addChild(tennisBallSprite);
    	//tennisBallSprite.addEventListener(MouseEvent.CLICK, onClickWheelImage);
    }
    
    //...
    
    private function onTick(a_event:TimerEvent):void
    {
    	world.Step(0.025, 10, 10);
    	world.DrawDebugData();
    
    	var tennisBallImage:Sprite;
    	for each (var tennisBallBody:b2Body in tennisBallArray)
    	{
    		tennisBallImage = tennisBallImages[tennisBallArray.indexOf(tennisBallBody)];
    		tennisBallImage.x = (tennisBallBody.GetPosition().x * mToPx);// - (tennisBallImage.width * 0.5);
    		tennisBallImage.y = (tennisBallBody.GetPosition().y * mToPx);// - (tennisBallImage.height * 0.5);
    		tennisBallImage.rotation = tennisBallBody.GetAngle() * radToDeg;
    	}
    
    	var crateImage:Sprite;
    	for each (var crateBody:b2Body in crateArray)
    	{
    		crateImage = crateImages[crateArray.indexOf(crateBody)];
    		crateImage.x = (crateBody.GetPosition().x * mToPx);// - (crateImage.width * 0.5);
    		crateImage.y = (crateBody.GetPosition().y * mToPx);// - (crateImage.height * 0.5);
    		crateImage.rotation = crateBody.GetAngle() * radToDeg;
    	}
    }
    

    Test it out:

    Ace.


    Step 3: Creating Bowling Balls

    I’d like to add three more types of ball: a bowling ball, a basketball, and a rubber ball. As you can see from the above, it’s a pain to do the same thing over and over again. We’ll add the bowling ball next, and try to simplify the process so we don’t have to keep making this irritating little changes.

    Here’s my bowling ball image. Again, feel free to use your own, but try to make it 60x60px with the name BowlingBall.png:

    Embed the image and add the necessary arrays:

    
    
    [Embed(source='../lib/BowlingBall.png')]
    public var BowlingBall:Class;
    
    //...
    
    public var bowlingBallArray:Array;
    public var bowlingBallImages:Array;
    
    //...
    
    bowlingBallArray = new Array();
    bowlingBallImages = new Array();
    

    Write a createBowlingBall() function:

    
    
    private function createBowlingBall(pxStartX:Number, pxStartY:Number, mVelocityX:Number, mVelocityY:Number):void
    {
    	var bowlingBallBodyDef:b2BodyDef = new b2BodyDef();
    	bowlingBallBodyDef.type = b2Body.b2_dynamicBody;
    	bowlingBallBodyDef.position.Set(pxStartX * pxToM, pxStartY * pxToM);
    	var bowlingBallBody:b2Body = world.CreateBody(bowlingBallBodyDef);
    	var circleShape:b2CircleShape = new b2CircleShape(60 * .5 * pxToM);
    	var bowlingBallFixtureDef:b2FixtureDef = new b2FixtureDef();
    	bowlingBallFixtureDef.shape = circleShape;
    	bowlingBallFixtureDef.restitution = 0.0;	//not bouncy
    	bowlingBallFixtureDef.friction = 0.0;	//very smooth
    	bowlingBallFixtureDef.density = 20.0;	//very heavy
    	var bowlingBallFixture:b2Fixture = bowlingBallBody.CreateFixture(bowlingBallFixtureDef);
    
    	var startingVelocity:b2Vec2 = new b2Vec2(mVelocityX, mVelocityY);
    	bowlingBallBody.SetLinearVelocity(startingVelocity);
    
    	bowlingBallArray.push(bowlingBallBody);
    
    	var bowlingBallImage:Bitmap = new BowlingBall();
    	var bowlingBallSprite:Sprite = new Sprite();
    	bowlingBallSprite.addChild(bowlingBallImage);
    	bowlingBallImage.x -= bowlingBallImage.width / 2;
    	bowlingBallImage.y -= bowlingBallImage.height / 2;
    	bowlingBallSprite.x = pxStartX;
    	bowlingBallSprite.y = pxStartY;
    	bowlingBallImages.push(bowlingBallSprite);
    	this.addChild(bowlingBallSprite);
    	//bowlingBallSprite.addEventListener(MouseEvent.CLICK, onClickWheelImage);
    }
    

    …and create the actual objects:

    
    
    for (var i:int = 0; i < 20; i++)
    {
    	createTennisBall(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createBowlingBall(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createCrate(
    		Math.random() * 1.5,
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	)
    }
    

    Phew. Okay, now for the rendering. Let’s take another look at our rendering code so far:

    
    
    private function onTick(a_event:TimerEvent):void
    {
    	world.Step(0.025, 10, 10);
    	world.DrawDebugData();
    
    	var tennisBallImage:Sprite;
    	for each (var tennisBallBody:b2Body in tennisBallArray)
    	{
    		tennisBallImage = tennisBallImages[tennisBallArray.indexOf(tennisBallBody)];
    		tennisBallImage.x = (tennisBallBody.GetPosition().x * mToPx);// - (tennisBallImage.width * 0.5);
    		tennisBallImage.y = (tennisBallBody.GetPosition().y * mToPx);// - (tennisBallImage.height * 0.5);
    		tennisBallImage.rotation = tennisBallBody.GetAngle() * radToDeg;
    	}
    
    	var crateImage:Sprite;
    	for each (var crateBody:b2Body in crateArray)
    	{
    		crateImage = crateImages[crateArray.indexOf(crateBody)];
    		crateImage.x = (crateBody.GetPosition().x * mToPx);// - (crateImage.width * 0.5);
    		crateImage.y = (crateBody.GetPosition().y * mToPx);// - (crateImage.height * 0.5);
    		crateImage.rotation = crateBody.GetAngle() * radToDeg;
    	}
    }
    

    Notice anything? Thanks to the change we made in the last step – to fix the rotation problem – the two highlighted sections are almost identical; just swap out the word “tennisBall” for “crate” in each case and they’re a perfect match.

    This suggests that we could combine them into a single loop, which could be used to render all objects. That way, we wouldn’t need to create a new loop to render the bowling balls. Let’s look at this next.


    Step 4: Rendering in a Single Loop

    To do this, we just need to combine the tennisBallArray and crateArray into a single array. It’s easier if I show you:

    
    
    private function onTick(a_event:TimerEvent):void
    {
    	world.Step(0.025, 10, 10);
    	world.DrawDebugData();
    
    	var generalB2BodyArray:Array = new Array();
    	generalB2BodyArray = generalB2BodyArray.concat(tennisBallArray, crateArray);
    	var generalImages:Array = new Array();
    	generalImages = generalImages.concat(tennisBallImages, crateImages);
    
    	var generalImage:Sprite;
    	for each (var generalBody:b2Body in generalB2BodyArray)
    	{
    		generalImage = generalImages[generalB2BodyArray.indexOf(generalBody)];
    		generalImage.x = (generalBody.GetPosition().x * mToPx);
    		generalImage.y = (generalBody.GetPosition().y * mToPx);
    		generalImage.rotation = generalBody.GetAngle() * radToDeg;
    	}
    }
    

    See how that works? In lines 6-10, we create a couple of new arrays: one contains all the tennis ball and crate b2Body objects, and the other contains all the tennis ball and crate Sprites. Most importantly, they contain them in the same order – if the 17th element of generalImages[] is a tennis ball, then the 17th eleemnt of generalB2BodyArray[] is the same tennis ball’s b2Body.

    The for loop then does exactly the same as the two before it did; it’s just way more general. Try it out:

    The bowling ball images don’t move, but look how easy it is to add them to the renderer:

    
    
    private function onTick(a_event:TimerEvent):void
    {
    	world.Step(0.025, 10, 10);
    	world.DrawDebugData();
    
    	var generalB2BodyArray:Array = new Array();
    	generalB2BodyArray = generalB2BodyArray.concat(tennisBallArray, crateArray, bowlingBallArray);
    	var generalImages:Array = new Array();
    	generalImages = generalImages.concat(tennisBallImages, crateImages, bowlingBallImages);
    
    	var generalImage:Sprite;
    	for each (var generalBody:b2Body in generalB2BodyArray)
    	{
    		generalImage = generalImages[generalB2BodyArray.indexOf(generalBody)];
    		generalImage.x = (generalBody.GetPosition().x * mToPx);
    		generalImage.y = (generalBody.GetPosition().y * mToPx);
    		generalImage.rotation = generalBody.GetAngle() * radToDeg;
    	}
    }
    

    That’s all it takes! Check it out:

    It’s beginning to run a little slowly on my machine, so I’m going to reduce the number of objects from 60 to 30:

    
    
    for (var i:int = 0; i < 10; i++)
    {
    	createTennisBall(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createBowlingBall(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createCrate(
    		Math.random() * 1.5,
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	)
    }
    

    There’s more room for them now, too:


    Step 5: Creating Basketballs

    Basketballs, next. My image is 75x75px and called Basketball.png:

    As usual, start by embedding the image as a class:

    
    
    [Embed(source='../lib/Basketball.png')]
    public var Basketball:Class;
    

    Now we’ll add the two arrays for the basketball b2Body objects and Sprites. Except… wait. Why do we need a separate array for these?

    We don’t, actually! Not any more. Let’s combine all our b2Body objects into one array, and all our Sprites into another. Change this:

    
    
    public var crateArray:Array;
    public var crateImages:Array;
    public var tennisBallArray:Array;
    public var tennisBallImages:Array;
    public var bowlingBallArray:Array;
    public var bowlingBallImages:Array;
    

    …to this:

    
    
    public var generalB2BodyArray:Array;
    public var generalImages:Array;
    

    Change this:

    
    
    wheelArray = new Array();
    wheelImages = new Array();
    crateArray = new Array();
    crateImages = new Array();
    tennisBallArray = new Array();
    tennisBallImages = new Array();
    bowlingBallArray = new Array();
    bowlingBallImages = new Array();
    

    …to this:

    
    
    generalB2BodyArray = new Array();
    generalImages = new Array();
    

    In every create«Whatever» function, change the equivalent of this:

    
    
    tennisBallArray.push(tennisBallBody);
    

    …to this:

    
    
    generalB2BodyArray.push(tennisBallBody);	//or .push(crateBody), or whatever
    

    …and this:

    
    
    tennisBallImages.push(tennisBallSprite);
    

    …to this:

    
    
    generalImages.push(tennisBallSprite);	//or .push(crateSprite), or whatever
    

    We can make onClickWheelImage() applicable to all types of objects very easily now; just change this one line:

    
    
    private function onClickWheelImage(event:MouseEvent):void
    {
    	var spriteThatWasClicked:Sprite = event.target as Sprite;
    	var relatedBody:b2Body = wheelArray[wheelImages.indexOf(spriteThatWasClicked)];
    	var centerX:Number = spriteThatWasClicked.x + (spriteThatWasClicked.width / 2);
    	var centerY:Number = spriteThatWasClicked.y + (spriteThatWasClicked.height / 2);
    	var xDistance:Number = centerX - event.stageX;
    	var yDistance:Number = centerY - event.stageY;
    	var xImpulse:Number = 60 * xDistance * pxToM;	//I picked 60 simply because
    	var yImpulse:Number = 60 * yDistance * pxToM;	//it "felt right" to me
    	relatedBody.ApplyImpulse(
    		new b2Vec2(xImpulse, yImpulse),
    		relatedBody.GetPosition()
    	);
    }
    

    …like so:

    
    
    private function onClickWheelImage(event:MouseEvent):void
    {
    	var spriteThatWasClicked:Sprite = event.target as Sprite;
    	var relatedBody:b2Body = generalB2BodyArray[generalImages.indexOf(spriteThatWasClicked)];
    	var centerX:Number = spriteThatWasClicked.x + (spriteThatWasClicked.width / 2);
    	var centerY:Number = spriteThatWasClicked.y + (spriteThatWasClicked.height / 2);
    	var xDistance:Number = centerX - event.stageX;
    	var yDistance:Number = centerY - event.stageY;
    	var xImpulse:Number = 60 * xDistance * pxToM;	//I picked 60 simply because
    	var yImpulse:Number = 60 * yDistance * pxToM;	//it "felt right" to me
    	relatedBody.ApplyImpulse(
    		new b2Vec2(xImpulse, yImpulse),
    		relatedBody.GetPosition()
    	);
    }
    

    Finally, in onTick(), we can delete the lines highlighted below:

    
    
    private function onTick(a_event:TimerEvent):void
    {
    	world.Step(0.025, 10, 10);
    	world.DrawDebugData();
    
    	var generalB2BodyArray:Array = new Array();
    	generalB2BodyArray = generalB2BodyArray.concat(tennisBallArray, crateArray, bowlingBallArray);
    	var generalImages:Array = new Array();
    	generalImages = generalImages.concat(tennisBallImages, crateImages, bowlingBallImages);
    
    	var generalImage:Sprite;
    	for each (var generalBody:b2Body in generalB2BodyArray)
    	{
    		generalImage = generalImages[generalB2BodyArray.indexOf(generalBody)];
    		generalImage.x = (generalBody.GetPosition().x * mToPx);
    		generalImage.y = (generalBody.GetPosition().y * mToPx);
    		generalImage.rotation = generalBody.GetAngle() * radToDeg;
    	}
    }
    

    Compile your SWF to make sure it works:

    If it doesn’t, it’s probably due to a missed array somewhere; just check your error messages and try again.

    That took a while, but it makes it much simpler to add new objects. We’re gradually streamlining the whole process.

    There’s another simplification we can make to these arrays, though…


    Step 6: Linking Images to b2Body Objects

    Why do we have the generalImages[] array? It’s simply so that we can link a b2Body to its associated image, and vice-versa. But there’s a better way to do this.

    Every b2Body has an internal “user data” object – this can be set to any object you like, and can be retrieved from anywhere. We can set this to point to the b2Body object’s Sprite.

    It’s simple to do; in each create«Whatever»() function, alter the equivalent of this line:

    
    
    generalImages.push(tennisBallSprite);
    

    …to the equivalent of this:

    
    
    tennisBallBody.SetUserData(tennisBallSprite);
    

    Then, in onTick(), instead of finding the image from an array, we can find it using the user data:

    
    
    private function onTick(a_event:TimerEvent):void
    {
    	world.Step(0.025, 10, 10);
    	world.DrawDebugData();
    
    	var generalImage:Sprite;
    	for each (var generalBody:b2Body in generalB2BodyArray)
    	{
    		generalImage = generalBody.GetUserData() as Sprite;
    		generalImage.x = (generalBody.GetPosition().x * mToPx);
    		generalImage.y = (generalBody.GetPosition().y * mToPx);
    		generalImage.rotation = generalBody.GetAngle() * radToDeg;
    	}
    }
    

    (If you wanted to, you could replace the user data with a sprite sheet and use blitting to render the objects here. It’s quite simple to do so, with this structure.)

    You could actually remove the generalImages[] array altogether now… apart from one thing: it’s still used in onClickWheelImage() to get a reference from the image to the b2Body.

    We could just comment onClickWheelImage() out, because we’re not using it right now, but that would be lazy. And this raises a good point, anyway: we need to be able to find any image’s associated b2Body. Unfortunately, we’re using the Sprite class, and it doesn’t have a built-in “user data” – but we could give it one.

    Create a new class, called B2Sprite, extending Sprite, in your \src\ folder:

    
    
    package
    {
    	import flash.display.Sprite;
    
    	public class B2Sprite extends Sprite
    	{
    
    		public function B2Sprite()
    		{
    
    		}
    
    	}
    
    }
    

    (I’ve used a capital B to distinguish it from the official Box2D classes.)

    Create a b2Body property:

    
    
    package
    {
    	import Box2D.Dynamics.b2Body;
    	import flash.display.Sprite;
    
    	public class B2Sprite extends Sprite
    	{
    		public var body:b2Body;
    
    		public function B2Sprite()
    		{
    
    		}
    
    	}
    
    }
    

    Because this extends Sprite, it’ll act exactly the same as a Sprite, except with that extra property that we need.

    Now, in every create«Whatever»() function, change the equivalent of this code:

    
    
    var tennisBallSprite:Sprite = new Sprite();
    

    …to this:

    
    
    var tennisBallSprite:B2Sprite = new B2Sprite();
    

    Also, wherever you have the equivalent of this line:

    
    
    tennisBallBody.SetUserData(tennisBallSprite);
    

    …add another line underneath it, to create a connection from the B2Sprite to the b2Body:

    
    
    tennisBallBody.SetUserData(tennisBallSprite);
    tennisBallSprite.body = tennisBallBody;
    

    Then, you can alter onClickWheelImage(), like so:

    
    
    private function onClickWheelImage(event:MouseEvent):void
    {
    	if (event.target is B2Sprite)
    	{
    		var spriteThatWasClicked:B2Sprite = event.target as B2Sprite;
    		var relatedBody:b2Body =  spriteThatWasClicked.body;
    		var centerX:Number = spriteThatWasClicked.x + (spriteThatWasClicked.width / 2);
    		var centerY:Number = spriteThatWasClicked.y + (spriteThatWasClicked.height / 2);
    		var xDistance:Number = centerX - event.stageX;
    		var yDistance:Number = centerY - event.stageY;
    		var xImpulse:Number = 60 * xDistance * pxToM;	//I picked 60 simply because
    		var yImpulse:Number = 60 * yDistance * pxToM;	//it "felt right" to me
    		relatedBody.ApplyImpulse(
    			new b2Vec2(xImpulse, yImpulse),
    			relatedBody.GetPosition()
    		);
    	}
    }
    

    Now that you’ve done all of that, you can uncomment out the lines that add event listeners for onClickWheelImage() (in the tennis ball and bowling ball creation functions), and try out your SWF:

    Click a tennis ball or bowling ball to see the effect.

    Rename the onClickWheelImage() function to onClickClickableImage(). If you like, you could try making the crates clickable, too!


    Step 7: Creating Basketballs (Still)

    Hey, weren’t we adding basketballs? Let’s get back to that.

    So, we’ve removed the image array, which means we were about to write the createBasketball() function. But, wait… I can’t help but wonder whether we need the generalB2BodyArray[].

    It turns out that we don’t. The b2world contains a list of all b2Body objects inside it, so the array is unnecessary. We’ll just make a quick change – I promise – and then we can add the basketball.

    This list is not an array. It works like this:

    1. You request world.GetBodyList(), and this gives you the first b2Body object in the list.
    2. With this body, you call .GetNext() to retrieve the next b2Body object in the list.
    3. If .GetNext() returns null, you’ve reached the end of the list.

    Have a go at re-writing the onTick() rendering code to use this list instead of the generalB2BodyArray[]. Here’s my solution if you want to check:

    
    
    private function onTick(a_event:TimerEvent):void
    {
    	world.Step(0.025, 10, 10);
    	world.DrawDebugData();
    
    	var currentBody:b2Body = world.GetBodyList();
    	var currentImage:B2Sprite;
    	while (currentBody != null)
    	{
    		if (currentBody.GetUserData() is B2Sprite)	//important, since the boundaries don't have associated images
    		{
    			currentImage = currentBody.GetUserData() as B2Sprite;
    			currentImage.x = (currentBody.GetPosition().x * mToPx);
    			currentImage.y = (currentBody.GetPosition().y * mToPx);
    			currentImage.rotation = currentBody.GetAngle() * radToDeg;
    		}
    		currentBody = currentBody.GetNext();
    	}
    }
    

    (I’ve taken the opportunity to add some additional checks and change the name of some variables; you don’t have to do this, but it’s probably easier if you do, to keep our code consistent.)

    You can now remove all references to generalB2BodyArray[]. Make sure you test your SWF to check it still runs fine:

    Creating that basketball is now pretty simple. First, write createBasketball():

    
    
    private function createBasketball(pxStartX:Number, pxStartY:Number, mVelocityX:Number, mVelocityY:Number):void
    {
    	var basketballBodyDef:b2BodyDef = new b2BodyDef();
    	basketballBodyDef.type = b2Body.b2_dynamicBody;
    	basketballBodyDef.position.Set(pxStartX * pxToM, pxStartY * pxToM);
    	var basketballBody:b2Body = world.CreateBody(basketballBodyDef);
    	var circleShape:b2CircleShape = new b2CircleShape(75 * .5 * pxToM);
    	var basketballFixtureDef:b2FixtureDef = new b2FixtureDef();
    	basketballFixtureDef.shape = circleShape;
    	basketballFixtureDef.restitution = 0.6;	//fairly bouncy
    	basketballFixtureDef.friction = 0.4;	//a little rough
    	basketballFixtureDef.density = 2.5;	//pretty light
    	var basketballFixture:b2Fixture = basketballBody.CreateFixture(basketballFixtureDef);
    
    	var startingVelocity:b2Vec2 = new b2Vec2(mVelocityX, mVelocityY);
    	basketballBody.SetLinearVelocity(startingVelocity);
    
    	var basketballImage:Bitmap = new Basketball();
    	var basketballSprite:B2Sprite = new B2Sprite();
    	basketballSprite.addChild(basketballImage);
    	basketballImage.x -= basketballImage.width / 2;
    	basketballImage.y -= basketballImage.height / 2;
    	basketballSprite.x = pxStartX;
    	basketballSprite.y = pxStartY;
    	basketballBody.SetUserData(basketballSprite);
    	this.addChild(basketballSprite);
    	basketballSprite.body = basketballBody;
    	basketballSprite.addEventListener(MouseEvent.CLICK, onClickClickableImage);
    }
    

    …then, create a whole bunch of them:

    
    
    for (var i:int = 0; i < 10; i++)
    {
    	createTennisBall(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createBowlingBall(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createBasketball(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createCrate(
    		Math.random() * 1.5,
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	)
    }
    

    Done! Try it:

    He shoots, he scores.


    Step 8: Making Object Construction Easier

    Every time we write a new create«Whatever»() function, we copy and paste an old one. They’re almost identical. And, as you’ve seen, that usually means we can improve our code structure to prevent us from having to copy and paste the same lines over and over again; it means there’s a better way to do things, which will make it easier for us to create new objects in the future.

    Look at this:

    
    
    private function createTennisBall(pxStartX:Number, pxStartY:Number, mVelocityX:Number, mVelocityY:Number):void
    {
    	var tennisBallBodyDef:b2BodyDef = new b2BodyDef();
    	tennisBallBodyDef.type = b2Body.b2_dynamicBody;
    	tennisBallBodyDef.position.Set(pxStartX * pxToM, pxStartY * pxToM);
    	var tennisBallBody:b2Body = world.CreateBody(tennisBallBodyDef);
    	var circleShape:b2CircleShape = new b2CircleShape(35 * .5 * pxToM);
    	var tennisBallFixtureDef:b2FixtureDef = new b2FixtureDef();
    	tennisBallFixtureDef.shape = circleShape;
    	tennisBallFixtureDef.restitution = 0.8;
    	tennisBallFixtureDef.friction = 0.75;
    	tennisBallFixtureDef.density = 1.0;
    	var tennisBallFixture:b2Fixture = tennisBallBody.CreateFixture(tennisBallFixtureDef);
    
    	var startingVelocity:b2Vec2 = new b2Vec2(mVelocityX, mVelocityY);
    	tennisBallBody.SetLinearVelocity(startingVelocity);
    
    	var tennisBallImage:Bitmap = new TennisBall();
    	var tennisBallSprite:B2Sprite = new B2Sprite();
    	tennisBallSprite.addChild(tennisBallImage);
    	tennisBallImage.x -= tennisBallImage.width / 2;
    	tennisBallImage.y -= tennisBallImage.height / 2;
    	tennisBallSprite.x = pxStartX;
    	tennisBallSprite.y = pxStartY;
    	tennisBallBody.SetUserData(tennisBallSprite);
    	tennisBallSprite.body = tennisBallBody;
    	this.addChild(tennisBallSprite);
    	tennisBallSprite.addEventListener(MouseEvent.CLICK, onClickClickableImage);
    }
    

    I’ve been using it as the template for all my b2Body creation functions. Here’s how they all boil down:

    
    
    private function create«Whatever»(pxStartX:Number, pxStartY:Number, mVelocityX:Number, mVelocityY:Number):void
    {
    	//create body def and set its starting position
    	//create body
    	//create shape and set its type and size
    	//create fixture def and set its properties
    	//create fixture
    	//set object's starting velocity
    	//create instance of image and add it to stage at correct position
    	//link image to body (and vice-versa)
    	//add required event listener to image
    }
    

    For our round objects, some of these steps are identical, and most of them only differ by a couple of parameters or instance names. So, what if we could inherit all that identical code from some general createRoundObject() function?

    We can’t do exactly that, but we can do something similar. Create a new folder in \src\ called \builders\, and create a new class inside that called RoundObjectBuilder.as:

    
    
    package builders
    {
    
    	public class RoundObjectBuilder
    	{
    
    		public function RoundObjectBuilder()
    		{
    
    		}
    
    	}
    
    }
    

    This is going to take a b2world and create a b2Body, so add appropriate code for that:

    
    
    package builders
    {
    	import Box2D.Dynamics.b2Body;
    	import Box2D.Dynamics.b2World;
    
    	public class RoundObjectBuilder
    	{
    		public var body:b2Body;
    		protected var world:b2World, pxToM:Number;
    
    		public function RoundObjectBuilder(world:b2World, pxToM:Number)
    		{
    			this.world = world; 		//sets this.world to parameter called world
    			this.pxToM = pxToM;
    		}
    
    	}
    
    }
    

    It’s going to create a round object, so we’ll give it a function to create such a shape:

    
    
    package builders
    {
    	import Box2D.Collision.Shapes.b2Shape;
    	import Box2D.Collision.Shapes.b2CircleShape;
    	import Box2D.Dynamics.b2Body;
    	import Box2D.Dynamics.b2World;
    
    	public class RoundObjectBuilder
    	{
    		public var body:b2Body;
    		protected var world:b2World, pxToM:Number;
    		protected var shape:b2Shape;
    
    		public function RoundObjectBuilder(world:b2World, pxToM:Number)
    		{
    			this.world = world;
    			this.pxToM = pxToM;
    		}
    
    		public function createShape():void
    		{
    			shape = new b2CircleShape(mRadius);
    		}
    	}
    
    }
    

    (Where’s the radius? You’ll see…)

    It’s going to create a fixture def, so create a function for that, too:

    
    
    package builders
    {
    	import Box2D.Collision.Shapes.b2Shape;
    	import Box2D.Collision.Shapes.b2CircleShape;
    	import Box2D.Dynamics.b2Body;
    	import Box2D.Dynamics.b2FixtureDef;
    	import Box2D.Dynamics.b2World;
    
    	public class RoundObjectBuilder
    	{
    		public var body:b2Body;
    		protected var world:b2World, pxToM:Number;
    		protected var shape:b2CircleShape;
    		protected var fixtureDef:b2FixtureDef;
    
    		public function RoundObjectBuilder(world:b2World, pxToM:Number)
    		{
    			this.world = world;
    			this.pxToM = pxToM;
    		}
    
    		public function createShape():void
    		{
    			shape = new b2CircleShape(mRadius);
    		}
    
    		public function createFixtureDef():void
    		{
    			fixtureDef = new b2FixtureDef();
    			fixtureDef.shape = shape;
    			fixtureDef.restitution = restitution;
    			fixtureDef.friction = friction;
    			fixtureDef.density = density;
    		}
    	}
    
    }
    

    (Where do we define the properties? Again, you’ll see…)

    It’s going to create a body def, too:

    
    
    package builders
    {
    	import Box2D.Collision.Shapes.b2Shape;
    	import Box2D.Collision.Shapes.b2CircleShape;
    	import Box2D.Dynamics.b2Body;
    	import Box2D.Dynamics.b2BodyDef;
    	import Box2D.Dynamics.b2FixtureDef;
    	import Box2D.Dynamics.b2World;
    
    	public class RoundObjectBuilder
    	{
    		public var body:b2Body;
    		protected var world:b2World, pxToM:Number;
    		protected var shape:b2CircleShape;
    		protected var fixtureDef:b2FixtureDef;
    		protected var bodyDef:b2BodyDef;
    
    		public function RoundObjectBuilder(world:b2World, pxToM:Number)
    		{
    			this.world = world;
    			this.pxToM = pxToM;
    		}
    
    		public function createShape():void
    		{
    			shape = new b2CircleShape(mRadius);
    		}
    
    		public function createFixtureDef():void
    		{
    			fixtureDef = new b2FixtureDef();
    			fixtureDef.shape = shape;
    			fixtureDef.restitution = restitution;
    			fixtureDef.friction = friction;
    			fixtureDef.density = density;
    		}
    
    		public function createBodyDef(mStartX:Number, mStartY:Number):void
    		{
    			bodyDef = new b2BodyDef();
    			bodyDef.type = b2Body.b2_dynamicBody;
    			bodyDef.position.Set(mStartX, mStartY);
    		}
    	}
    
    }
    

    It’s going to create an actual body and fixture, and set the body’s initial velocity:

    
    
    package builders
    {
    	import Box2D.Collision.Shapes.b2Shape;
    	import Box2D.Collision.Shapes.b2CircleShape;
    	import Box2D.Common.Math.b2Vec2;
    	import Box2D.Dynamics.b2Body;
    	import Box2D.Dynamics.b2BodyDef;
    	import Box2D.Dynamics.b2Fixture;
    	import Box2D.Dynamics.b2FixtureDef;
    	import Box2D.Dynamics.b2World;
    
    	public class RoundObjectBuilder
    	{
    		public var body:b2Body;
    		protected var world:b2World, pxToM:Number;
    		protected var shape:b2CircleShape;
    		protected var fixtureDef:b2FixtureDef;
    		protected var bodyDef:b2BodyDef;
    		protected var fixture:b2Fixture;
    		protected var startingVelocity:b2Vec2;
    
    		public function RoundObjectBuilder(world:b2World, pxToM:Number)
    		{
    			this.world = world;
    			this.pxToM = pxToM;
    		}
    
    		public function createShape():void
    		{
    			shape = new b2CircleShape(mRadius);
    		}
    
    		public function createFixtureDef():void
    		{
    			fixtureDef = new b2FixtureDef();
    			fixtureDef.shape = shape;
    			fixtureDef.restitution = restitution;
    			fixtureDef.friction = friction;
    			fixtureDef.density = density;
    		}
    
    		public function createBodyDef(mStartX:Number, mStartY:Number):void
    		{
    			bodyDef = new b2BodyDef();
    			bodyDef.type = b2Body.b2_dynamicBody;
    			bodyDef.position.Set(mStartX, mStartY);
    		}
    
    		public function createBody():void
    		{
    			body = world.CreateBody(bodyDef);
    		}
    
    		public function createFixture():void
    		{
    			fixture = body.CreateFixture(fixtureDef);
    		}
    
    		public function setStartingVelocity(mVelocityX:Number, mVelocityY:Number):void
    		{
    			startingVelocity = new b2Vec2(mVelocityX, mVelocityY);
    			body.SetLinearVelocity(startingVelocity);
    		}
    	}
    
    }
    

    Next, we add the image:

    
    
    package builders
    {
    	import Box2D.Collision.Shapes.b2Shape;
    	import Box2D.Collision.Shapes.b2CircleShape;
    	import Box2D.Common.Math.b2Vec2;
    	import Box2D.Dynamics.b2Body;
    	import Box2D.Dynamics.b2BodyDef;
    	import Box2D.Dynamics.b2Fixture;
    	import Box2D.Dynamics.b2FixtureDef;
    	import Box2D.Dynamics.b2World;
    	import flash.display.Bitmap;
    
    	public class RoundObjectBuilder
    	{
    		public var body:b2Body;
    		protected var world:b2World, pxToM:Number;
    		protected var shape:b2CircleShape;
    		protected var fixtureDef:b2FixtureDef;
    		protected var bodyDef:b2BodyDef;
    		protected var fixture:b2Fixture;
    		protected var startingVelocity:b2Vec2;
    		protected var sprite:B2Sprite;
    
    		public function RoundObjectBuilder(world:b2World, pxToM:Number)
    		{
    			this.world = world;
    			this.pxToM = pxToM;
    		}
    
    		public function createShape():void
    		{
    			shape = new b2CircleShape(mRadius);
    		}
    
    		public function createFixtureDef():void
    		{
    			fixtureDef = new b2FixtureDef();
    			fixtureDef.shape = shape;
    			fixtureDef.restitution = restitution;
    			fixtureDef.friction = friction;
    			fixtureDef.density = density;
    		}
    
    		public function createBodyDef(mStartX:Number, mStartY:Number):void
    		{
    			bodyDef = new b2BodyDef();
    			bodyDef.type = b2Body.b2_dynamicBody;
    			bodyDef.position.Set(mStartX, mStartY);
    		}
    
    		public function createBody():void
    		{
    			body = world.CreateBody(bodyDef);
    		}
    
    		public function createFixture():void
    		{
    			fixture = body.CreateFixture(fixtureDef);
    		}
    
    		public function setStartingVelocity(mVelocityX:Number, mVelocityY:Number):void
    		{
    			startingVelocity = new b2Vec2(mVelocityX, mVelocityY);
    			body.SetLinearVelocity(startingVelocity);
    		}
    
    		public function setImage():void
    		{
    			sprite = new B2Sprite();
    			var bitmap:Bitmap = new Image();
    			sprite.addChild();
    			bitmap.x -= bitmap.width / 2;
    			bitmap.y -= bitmap.height / 2;
    			body.SetUserData(sprite);
    			sprite.body = body;
    		}
    
    		public function linkImageAndBody():void
    		{
    			body.SetUserData(sprite);
    			sprite.body = body;
    		}
    	}
    
    }
    

    Do you see where we’re going with this? You might have guessed that we’ll eventually create an instance of RoundObjectBuilder and then call createShape(), createFixtureDef(), and so on, all in the right order, with the right parameters, then retrieve the b2Body object after everything’s set up. That’s correct, but there is a little more to it than that.


    Step 9: Creating a Specific Builder

    First, create protected variables to hold all the properties that are missing:

    
    
    public var body:b2Body;
    protected var world:b2World, pxToM:Number;
    protected var shape:b2CircleShape;
    protected var fixtureDef:b2FixtureDef;
    protected var bodyDef:b2BodyDef;
    protected var fixture:b2Fixture;
    protected var startingVelocity:b2Vec2;
    protected var sprite:B2Sprite;
    protected var mRadius:Number;
    protected var restitution:Number, friction:Number, density:Number;
    protected var Image:Class;
    

    Now, create a new class, in your \builders\ folder, called TennisBallBuilder.as, and make sure it extends RoundObjectBuilder:

    
    
    package builders
    {
    	import Box2D.Dynamics.b2World;
    
    	public class TennisBallBuilder extends RoundObjectBuilder
    	{
    
    		public function TennisBallBuilder(world:b2World, pxToM:Number)
    		{
    			super(world, pxToM);
    		}
    
    	}
    
    }
    

    (Remember, super() will run the code in the constructor function of RoundObjectBuilder, because we extended it.)

    Now, underneath that call to super(), set the restitution, friction, and density of the tennis ball:

    
    
    package builders
    {
    	import Box2D.Dynamics.b2World;
    
    	public class TennisBallBuilder extends RoundObjectBuilder
    	{
    
    		public function TennisBallBuilder(world:b2World, pxToM:Number)
    		{
    			super(world, pxToM);
    			restitution = 0.8;
    			friction = 0.75;
    			density = 1.0;
    		}
    
    	}
    
    }
    

    Next, embed the tennis ball image, and use it to set the Image class which will be used to create the bitmap; also, set the radius:

    
    
    package builders
    {
    	import Box2D.Dynamics.b2World;
    
    	public class TennisBallBuilder extends RoundObjectBuilder
    	{
    		[Embed(source='../../lib/TennisBall.png')]
    		public var TennisBall:Class;
    
    		public function TennisBallBuilder(world:b2World, pxToM:Number)
    		{
    			super(world, pxToM);
    			restitution = 0.8;
    			friction = 0.75;
    			density = 1.0;
    
    			Image = TennisBall;
    			mRadius = 35 * 0.5 * pxToM;
    		}
    
    	}
    
    }
    

    So now we have a class that encapsulates all of the information and all the functions needed to create a tennis ball. We’ve just got to put it all together. Modify Main.createTennisBall() like so:

    
    
    private function createTennisBall(pxStartX:Number, pxStartY:Number, mVelocityX:Number, mVelocityY:Number):void
    {
    	var tennisBallBuilder:TennisBallBuilder = new TennisBallBuilder(world, pxToM);
    	tennisBallBuilder.createShape();
    	tennisBallBuilder.createFixtureDef();
    	tennisBallBuilder.createBodyDef(pxStartX * pxToM, pxStartY * pxToM);
    	tennisBallBuilder.createBody();
    	tennisBallBuilder.createFixture();
    	tennisBallBuilder.setStartingVelocity(mVelocityX, mVelocityY);
    	tennisBallBuilder.setImage();
    	tennisBallBuilder.linkImageAndBody();
    
    	var tennisBallSprite:B2Sprite = tennisBallBuilder.body.GetUserData() as B2Sprite;
    	tennisBallSprite.x = pxStartX;
    	tennisBallSprite.y = pxStartY;
    	this.addChild(tennisBallSprite);
    	tennisBallSprite.addEventListener(MouseEvent.CLICK, onClickClickableImage);
    }
    

    If you test your SWF, you’ll see that this still works:

    But so what? We haven’t gained much here. In fact, we’ve ended up with more code than we started with, and it still requires copying and pasting.

    Time for one more improvement. Create a new class, in \builders\, called RoundObjectDirector.as:

    
    
    package builders
    {
    
    	public class RoundObjectDirector
    	{
    
    		public function RoundObjectDirector()
    		{
    
    		}
    
    	}
    
    }
    

    Here’s how this will work:

    1. We’ll tell the RoundObjectDirector to use a specific RoundObjectBuilder.
    2. We’ll tell the RoundObjectDirector to create a new round object.
    3. The RoundObjectDirector will do so, using the RoundObjectBuilder that we specified, and will return said object.

    Here’s the code:

    
    
    package builders
    {
    	import Box2D.Dynamics.b2Body;
    
    	public class RoundObjectDirector
    	{
    		protected var roundObjectBuilder:RoundObjectBuilder;
    
    		public function RoundObjectDirector()
    		{
    
    		}
    
    		public function setRoundObjectBuilder(builder:RoundObjectBuilder):void
    		{
    			this.roundObjectBuilder	= builder;
    		}
    
    		public function createRoundObject(mStartX:Number, mStartY:Number, mVelocityX:Number, mVelocityY:Number):b2Body
    		{
    			roundObjectBuilder.createShape();
    			roundObjectBuilder.createFixtureDef();
    			roundObjectBuilder.createBodyDef(mStartX, mStartY);
    			roundObjectBuilder.createBody();
    			roundObjectBuilder.createFixture();
    			roundObjectBuilder.setStartingVelocity(mVelocityX, mVelocityY);
    			roundObjectBuilder.setImage();
    			roundObjectBuilder.linkImageAndBody();
    			return roundObjectBuilder.body;
    		}
    
    	}
    
    }
    

    See how most of the code in createRoundObject() is taken from our Main.createNewTennisBall() function? All you have to do is replace “tennisBall” with “roundObject” in each case. (Well, okay, I’ve also changed all measurements to be in meters rather than pixels, since we’re not dealing with any images here.)

    Now we can modify Main.createNewTennisBall() like so:

    
    
    private function createTennisBall(pxStartX:Number, pxStartY:Number, mVelocityX:Number, mVelocityY:Number):void
    {
    	var tennisBallBuilder:TennisBallBuilder = new TennisBallBuilder(world, pxToM);
    	var roundObjectDirector:RoundObjectDirector = new RoundObjectDirector();
    	roundObjectDirector.setRoundObjectBuilder(tennisBallBuilder);
    	var tennisBallBody:b2Body = roundObjectDirector.createRoundObject(pxStartX * pxToM, pxStartY * pxToM, mVelocityX, mVelocityY);
    
    	var tennisBallSprite:B2Sprite = tennisBallBody.GetUserData() as B2Sprite;
    	tennisBallSprite.x = pxStartX;
    	tennisBallSprite.y = pxStartY;
    	this.addChild(tennisBallSprite);
    	tennisBallSprite.addEventListener(MouseEvent.CLICK, onClickClickableImage);
    }
    

    (Note that I’ve converted the starting positions to pixels here, before passing them to the Director.)


    Step 10: Creating Rubber Balls

    Let’s create a brand new type of object, and see how much faster it is. We’ll use a super-bouncy rubber ball:

    Mine is 15x15px and called RubberBall.png.

    First step: create a new class, extending RoundObjectBuilder, to create the rubber ball:

    
    
    package builders
    {
    	import Box2D.Dynamics.b2World;
    
    	public class RubberBallBuilder extends RoundObjectBuilder
    	{
    		[Embed(source='../../lib/RubberBall.png')]
    		public var RubberBall:Class;
    
    		public function RubberBallBuilder(world:b2World, pxToM:Number)
    		{
    			super(world, pxToM);
    			restitution = 1.0;
    			friction = 0.0;
    			density = 5.0;
    
    			Image = RubberBall;
    			mRadius = 15 * 0.5 * pxToM;
    		}
    
    	}
    
    }
    

    Second step: create Main.createRubberBall():

    
    
    private function createRubberBall(pxStartX:Number, pxStartY:Number, mVelocityX:Number, mVelocityY:Number):void
    {
    	var rubberBallBuilder:RubberBallBuilder = new RubberBallBuilder(world, pxToM);
    	var roundObjectDirector:RoundObjectDirector = new RoundObjectDirector();
    	roundObjectDirector.setRoundObjectBuilder(rubberBallBuilder);
    	var rubberBallBody:b2Body = roundObjectDirector.createRoundObject(pxStartX * pxToM, pxStartY * pxToM, mVelocityX, mVelocityY);
    
    	var rubberBallSprite:B2Sprite = rubberBallBody.GetUserData() as B2Sprite;
    	rubberBallSprite.x = pxStartX;
    	rubberBallSprite.y = pxStartY;
    	this.addChild(rubberBallSprite);
    	rubberBallSprite.addEventListener(MouseEvent.CLICK, onClickClickableImage);
    }
    

    Third step: create the actual objects:

    
    
    for (var i:int = 0; i < 10; i++)
    {
    	createTennisBall(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createBowlingBall(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createBasketball(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createRubberBall(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createCrate(
    		Math.random() * 1.5,
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	)
    }
    

    That’s it. Easy.


    Step 11: Getting Even More General

    I can’t help myself. I have to make one more simplification.

    Did you notice that Main.createRubberBall() and Main.createTennisBall() are almost identical? The only things that differ are the type of RoundObjectBuilder and the variable names.

    Let’s combine them into a single function: Main.createRoundObject():

    
    
    private function createRoundObject(roundObjectBuilder:RoundObjectBuilder, pxStartX:Number, pxStartY:Number, mVelocityX:Number, mVelocityY:Number):void
    {
    	roundObjectDirector.setRoundObjectBuilder(roundObjectBuilder);
    	var body:b2Body = roundObjectDirector.createRoundObject(pxStartX * pxToM, pxStartY * pxToM, mVelocityX, mVelocityY);
    
    	var sprite:B2Sprite = body.GetUserData() as B2Sprite;
    	sprite.x = pxStartX;
    	sprite.y = pxStartY;
    	this.addChild(sprite);
    	sprite.addEventListener(MouseEvent.CLICK, onClickClickableImage);
    }
    

    I’ve also made roundObjectDirector a protected variable, belonging to Main, so that we don’t have to keep creating a new one:

    
    
    protected var roundObjectDirector:RoundObjectDirector = new RoundObjectDirector();
    

    Delete the createTennisBall() and createRubberBall() functions.

    Now we can alter the code that creates objects, from this:

    
    
    for (var i:int = 0; i < 10; i++)
    {
    	createTennisBall(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createBowlingBall(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createBasketball(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createRubberBall(
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	);
    	createCrate(
    		Math.random() * 1.5,
    		Math.random() * (stage.stageWidth - 20) + 10,
    		Math.random() * (stage.stageHeight - 20) + 10,
    		(Math.random() * 100) - 50,
    		0
    	)
    }
    

    …to this:

    
    
    var tennisBallBuilder:TennisBallBuilder = new TennisBallBuilder(world, pxToM);
    var rubberBallBuilder:RubberBallBuilder = new RubberBallBuilder(world, pxToM);
    for (var i:int = 0
  9. Kah Shiu Chong says:
    October 26, 2011 at 10:03 pm
    This entry is part 3 of 3 in the series Kinematics

    Premium members, rejoice! It’s time for another Activetuts+ Premium tutorial. This time, you’ll learn how to use forward kinematics to create a robotic arm – in this case, the example is for an excavator, but you can use the techniques you’ll learn in all sorts of situations. It follows on nicely from our previous tutorials on linear kinematics and inverse kinematics. Read on to see what you’ll learn…

    Forward Kinematics (FK) is a positioning algorithm. It’s not as complicated as it sounds if you associate it to sequence of actions from an excavator operator’s point of view. Beginning with the node closest to it, the operator configures the orientation of each node in the hope that the scoop will reach the location intended. Often, several attempts are made before achieving success. FK is an algorithm to perform such task.

    In this tutorial, we shall attempt the implementation of FK and apply it onto an excavator from a 2D side view. Having understood this algorithm, one can easily adapt it to a 3D environment. Enjoy!


    Preview

    Let’s take a look at the final result we will be working towards:

    Press the space key to scroll through nodes (the current one is marked by a red bracket). While you are at it, press the arrow keys to change the angle.

    This tutorial covers the following:

    • Explanation for FK’s Mathematical background.
    • Hard-coded implementation of the FK.
    • Object-oriented class to implement FK algorithm.
    • Demonstration of FK class used in a project.
    • Graphics (as seen above) applied to the demonstration.

    Active Premium Membership

    Activetuts+ Premium Membership

    We run a Premium membership system which periodically gives members access to extra tutorials, like this one! You’ll also get access to Psd Premium, Vector Premium, Audio Premium, Net Premium, Ae Premium, Cg Premium, Photo Premium, and the new Mobile Premium too. If you’re a Premium member, you can log in and download the tutorial. If you’re not a member, you can of course join today!

    Also, don’t forget to follow @envatoactive on twitter and grab the Activetuts+ RSS Feed to stay up to date with the latest tutorials and articles.


  10. Ian Yates says:
    October 26, 2011 at 10:38 pm

    Twice a month, we revisit some of our best posts from throughout the history of Activetuts+. This week’s retro-Active post as originally posted on the 8th of November, 2010; since then we’ve seen Microsoft announce that Windows 8 will support HTML5 for native apps, Adobe move further and further into the mobile area, and the release of HTML5 multimedia tools such as Edge. Things are certainly different – how have the experts’ predictions held up?

    The subject of Flash, HTML5, Silverlight, RIAs and all that surrounds them continues to be debated across the net. It’s a sensitive issue as we’ve discovered; our recent roundup post certainly opened a can of worms and touched a raw nerve with a few folk!

    Today, we’re going to put that behind us and approach the discussion in a more sensible fashion. Read on to see what some of the most respected members of our community have to say on the matter.


    The Contributors

    A huge thanks to everyone who gave up their time in contributing to this article. We’ve collected commentary from Authors, Designers, Developers, UI & UX Architects, Evangelists and Community Experts from all sides of the fence. Here they are, in no particular order.

    Jump to any Section of this page quickly by following a link below:

    • Alan Klement Powerflasher Developer
    • Keith Peters Flash/ActionScript Developer, Author & Speaker
    • Bruce Lawson Web Evangelist for Opera
    • Jonathan Campos Director of Software Development at Dedo Inc. & Adobe Community Professional
    • Stray Flash & AIR Programmer
    • Tom Green Flash Educationalist & Author
    • Romin Irani Software Developer
    • Joseph Labrecque Senior Multimedia Application Developer & Adobe Education Leader
    • Rich Clark User Interaction Designer & Creator of html5doctor.com
    • Jack Doyle Founder of GreenSock Tweening Platform
    • Rich Tretola Adobe Community Expert, Author & Speaker
    • Paul Neave Interaction Designer
    • Rob Larsen Interface Architect, Isobar
    • Kevin Suttle Flash Platform User Experience Developer
    • Mike Taulty Microsoft UK
    • Steve Fulton 8bitrocket.com
    • Remy Sharp All Round Supporter of Make Believe Animals
    • James Whittaker UI/UX Architect TweetDeck Inc. & Adobe Community Professional

    Megaphone Icon by silenceplease available on GraphicRiver.


    Alan Klement
    Powerflasher Developer

    We are expected to be innovators and that means pushing ourselves outside of our comfort zones from time to time.

    Lately, it seems cooler heads are slowly prevailing when it comes to the “HTML5 vs Flash” debate. The consensus is shifting toward choosing “the right tool for the right job” and that is how it should be for everyone. We’re all craftsmen and professionals – not tool-smiths and laborers. Perhaps the most fun, and most intimidating, part of our job as creators is to be willing to explore new and better ways of engaging those who enjoy what we create. Does a painter use only one brush or a dentist use only a drill?

    We are expected to be innovators and that means pushing ourselves outside of our comfort zones from time to time. The question to ask yourself is, ‘Am I choosing the best tool that fits the project’s needs?

    Alan Klement
    web: http://blog.alanklement.com
    twitter: @alanklement


    Keith Peters
    Flash/ActionScript Developer, Author & Speaker

    You fear what you don’t understand. The more you learn, the less you fear.

    I think the whole argument of technology X vs. technology Y is stupid and childish and anyone who gets all defensive about their technology – or offensive about some other technology – is mainly showing off their own lack of confidence or certainty in their own future. I know Flash very well. I can do Flex. I can code up just about anything on the iPhone. I’ve dabbled in Android. I’m currently learning Silverlight and XNA for Windows Phone 7 development. You fear what you don’t understand. The more you learn, the less you fear.

    HTML and JavaScript can currently do many things that you really needed Flash for years ago. That will only grow. I think the ideal of being able to do more things without relying on third party plugins is a good thing. But we are a long way from getting rid of them altogether. That said, I’d hate to have to do all my coding in JavaScript as it currently stands. While AS3 has a lot of room for improvement, it has grown a lot in the last decade. Coding in JS is like going back to AS1. If JavaScript looked more like AS3, I’d be a lot more interested in diving into HTML5.

    Keith Peters
    web: http://www.bit-101.com
    twitter: @bit101


    Bruce Lawson
    Web Evangelist for Opera

    A professional developer evaluates the client, the task and the audience and chooses the tool accordingly.

    The big misconception is that it’s either HTML5 or Flash/Silverlight. Flash in particular is part of the Web’s ecosystem, and we’ll need to be able to render Flash content for ever. It would be a tragedy if future generations were not able to enjoy the Kenya song.

    HTML5 even legalises the <embed> tag so adding plugin content to HTML5 pages can be done without making the page invalid.

    Some HTML5 technologies can replace some uses of Flash: scripted graphics can be achieved using <canvas> for example, and interacting with videos through script is (arguably) easier to achieve using HTML5. It’s important, though, that we now have a choice; previously, for video or animations you were pretty much limited to plugins; now there is an open standards choice as well.

    Some things can’t be as easily achieved in HTML5 as they can using plugins. AS I alluded to in my Five things that carrots can do that HTML5 can’t video, the choice of technology should be based on what you’re trying to achieve. A professional developer evaluates the client, the task and the audience and chooses the tool accordingly.

    Bruce Lawson
    blog: http://www.brucelawson.co.uk
    buy my book: http://introducinghtml5.com
    twitter: @brucel


    Jonathan Campos
    Director of Software Development at Dedo Inc. & Adobe Community Professional

    Neither HTML5 nor Flash is without flaw.

    As a previous Javascript application developer and current Flash application developer I have followed the arguments about HTML5 with a passing interest and little more. HTML5 will carve out room on the RIA landscape, but as with every piece of technology, HTML5 has it’s strengths and it’s weaknesses. A switch to HTML5 doesn’t ensure you will be free of bugs, performance issues, or testing. It just means you will be checking for bugs, optimizing performance, and testing on a different base language and with different tool sets. Neither HTML5 nor Flash is without flaw.

    As a Javascript developer turned Flash developer, I can say from my own experience that you can do almost everything you could do in Flash in Javascript. However, it takes longer, is more difficult, and requires more testing on multiple browsers and environments.

    Working with the Flash Player on large scale multitouch devices and multiscreen development, I can tell you that there are things we do now that HTML5 just can’t do yet. As such, we will continue to watch HTML5 grow but for us we are happy with the capabilities provided to us through the Flash Player and Adobe AIR.

    Jonathan Campos
    work: http://www.dedoinc.com
    blog: http://www.unitedmindset.com/jonbcampos
    twitter: @jonbcampos


    Stray
    Flash & AIR Programmer

    Deciding the technology your users might want to use your site/app in is only the first step.

    In the short term, I see HTML5 taking on Flash in creating over-designed ego-driven micro-sites. The clients we’ve been turning down on these projects for a couple of years don’t even bother us Flash devs anymore. They’re ruining the lives of HTML5 devs instead! Thanks Steve – we owe you for that one.

    My little company mostly builds big Air apps – tuition and instruction for the engineering industry. These types of applications leverage the full power of flash development: a grown-up set of technologies and tools, and the incredible flexibility of the Flash timeline. This is Flash’s strength over HTML5 – audio, video, text, multilayer animation, interaction and the application they’re sitting in all playing together.

    The other strength flash has is a mature tool set and some great frameworks and libraries. Increasingly generous open-source development is lifting the game of whole chunks of the community. A lot of us are really good at what we do and getting better every day.

    Deciding the technology your users might want to use your site/app in is only the first step. Building real software is hard. And it’s different from building websites. The number of pathways through a really rich application or game is mind-blowing. Not blowing-our-own-minds building this stuff is what flash devs have become good at. We’ve learned through making a lot of mistakes – HTML5 devs haven’t had that opportunity yet.

    I predict a lot of high-profile HTML5 project fails – anyone remember boo.com?

    Stray
    web: http://flair-flash-flex-air.blogspot.com
    twitter: @stray_and_ruby


    Tom Green
    Flash Educationalist & Author

    I truly see the browser as a doomed technology.

    The jury is still out on whether HTML is a Flash-killer. Over the years, I have seen too many of these “emergent technologies” touted as the “App_Name_Goes_Here- killer” to get myself worked up about it.

    I found it rather fascinating, though, to see a demo of an app during the “Sneaks” at Max this year that essentially recompiled a swf into an HTML5 file. Again, there is a lot of “perception” between demo and release (Macromedia/Adobe’s Fixation on on Flash Lite for Mobile a few years back, for example) to get myself too worked up. The implications of this sort of thing, though, are rather interesting.

    The ability to cross-compile a swf to an HTML5 file gets Flash onto Apple’s devices without a lot of extra work and essentially gets Flash/Air/Flex projects driven by the Flash Player on to practically every device on the planet. Even then I truly see the “browser” as a doomed technology. We are undergoing a fundamental shift away from browser-based presentations to apps that don’t necessarily need to be delivered through an ethernet cable or viewed on a PC or laptop to be experienced.

    The challenge around this multiscreen “environment” that just popped up is aimed more at designers than the codies. The codies quite rightfully claim they can “Write-Once/Deploy Everywhere” which is true because it is code and data. The danger in that is though it is true, it is also wrong. As I pointed out during a RIM Focus Group at Max when I asked this question: “Do you really think the app on your Blackberry Torch is going to look equally stunning on the 60″ inch Samsung monitor over there, my MacBook Pro, your Dell PC laptop and that guy’s Motorola?” What I was getting at is the real issue is a design issue because designers will have to play close attention to the Presentation layer than simply whipping something up in Flex. Think about it for a minute. Apps look great when they are on a screen roughly the size of a business card but you simply can’t expect that content to scale up in orders of magnitude without sacrificing quality or something else. I find it rather interesting that no one has started talking about this issue and I can pretty well guarantee it will come up later rather than sooner.

    Tom Green
    web: http://www.tomontheweb.ca
    twitter: @TomGreen


    Romin Irani
    Software Developer

    HTML5 lowers my barrier to start creating powerful browser applications today

    I think the biggest misconception is to think in terms of “Flash is going to die” or “HTML5 is not going to succeed” and so on. Given the way the world works, neither of them are going to be clear winners or losers. Every developer knows that to create a compelling application to reach out to as wide an audience as possible, you need to cater to both sides. For e.g. you cannot assume that HTML5 will be present on all browsers, similarly you cannot assume that Flash will be present everywhere. You have to design for a fallback mechanism and that I believe is ingrained.

    Flash is powerful. The graphics capabilities, the Charting support and its current reach is excellent. Where I think it stands out and will stay its ground today is not in features but two things:

    1. Plenty of excellent developer tools, IDEs that are available
    2. The huge developer ecosystem.

    Both of these are well entrenched. HTML5 is still evolving, once it is finalized can one expect more tools.

    In summary, HTML5 lowers my barrier to start creating powerful browser applications today. HTML, CSS and JS are all I need to get started. I am particularly excited by the set of Javascript APIs that come along with HTML5 i.e. Geolocation, Offline support, Storage, etc that allow me to address key architectural aspects in my application to make my browser apps more powerful. The other area I am waiting for wider acceptance is Web Sockets, that could be a game changer for a lot of gaming applications.

    Romin Irani
    blog: http://iromin.wordpress.com
    check out: http://www.oreillynet.com
    twitter: @iRomin


    Joseph Labrecque
    Senior Multimedia Application Developer & Adobe Education Leader

    Why would anyone expect HTML, as a specification, to stand still?

    Ever since the inception of this debate, I’ve held the position that the majority of dialogue around “HTML vs. Flash” is an intentional misrepresentation of facts and usage. There is no better example of this than Steve Jobs’ counterfactual letter, “Thoughts on Flash”; a message clearly designed to provide ignorant media outlets and technology zealots with cleverly crafted soundbytes used to encourage a position against Flash as a viable platform on the web and on devices.

    HTML5 is the natural progression of the HTML specification. As such, it poses no threat to the Flash Platform because HTML and Flash have always existed as complimentary technologies. Why would anyone expect HTML, as a specification, to stand still? In my opinion, it has done so for far too long and is overdue an abundance of rich, new features. Does this in any way harm Flash as a platform? Of course not; Flash advances at a much faster rate than HTML, unrestrained by standards bodies and bickering between opposing corporations. The addition of capabilities with HTML only augments embedded Flash in the browser, as these new capabilities (geolocation data, for example) can be fed into a Flash interface through local connection or via initialization variables.

    I actually find it humorous that the fate of Flash is called into question at this time of great advances. Flash Player 10.1 took a long time to emerge since a massive rewrite was required to allow a good experience across desktops, mobile devices, and eventually the digital living room. Now that this foundation has been set, we are seeing some startling growth across numerous areas of platform implementation. The beginnings of which can be seen in the upcoming 3D “Molehill” APIs, the super-performant StageVideo classes, the first glimpses of multi-threading, and upcoming 64-bit runtimes across Windows, Linux, and Mac OS. This doesn’t even consider advances in the AIR runtime and associated frameworks.

    It’s a great time to be a Flash developer – and a great time for HTML too!

    Joseph Labrecque
    blog: http://inflagrantedelicto.memoryspiral.com
    twitter: @JosephLabrecque


    Rich Clark
    User Interaction Designer & Creator of html5doctor.com

    ..it’s likely proprietary solutions will always be somewhat ahead of the curve when compared to open standards..

    Both Adobe & Microsoft seem to be working towards embracing HTML5. Just look at IE9, it’s come on leaps and bounds from previous versions of the browser. If Adobe can get on board and develop a decent IDE for working with <canvas> and SVG then they’ll be onto a winner as well.

    There’s maybe not been a shift [in disciplines where Flash is used] but there likely will be a shift in the not too distant future. I don’t think that there’s much doubt that Flash will continue to push the boundaries of what’s possible online. Companies like Adobe can afford innovate, improve and release new products more rapidly in comparison to an organisation like the W3C who have to work with implementers, authors and users while still maintaining backwards compatibility. That’s why it’s likely proprietary solutions will always be somewhat ahead of the curve when compared to open standards – it’s the nature of the beast.

    Video & Audio are the main areas that HTML5 will start to outgrow Flash I imagine. In fact, some would have you believe that a large percentage of HTML5 _compatible_ video already exists.

    Probably the biggest misconception is defining HTML5. It seems to be whatever you want it to be – that annoys me. Especially when people lump together CSS3, Web Fonts, SVG, etc all into HTML5. It would be preferable for people to use the phrase ‘Open Standards’ or similar but we’re probably too far down the line for that now. When you see daily newspapers using the term ‘HTML5′ you know it ain’t gonna happen ;)

    [I'm looking forward to] the fact that the web will move away from the need for proprietary plugins (and associated software) that are replaced by Open Standards that anyone with a text editor can work with.

    Rich Clark
    web: http://richclarkdesign.com
    twitter: @rich_clark


    Jack Doyle
    Founder of GreenSock Tweening Platform

    ..despite the hype around HTML5, Flash is doing great.

    The HTML5 vs. Flash topic has become far too divisive. HTML5 is an evolving standard that promises some exciting capabilities, but it is most definitely not a Flash killer. HTML and Flash have always coexisted but I believe that 3 things are primarily responsible for the recent crusade against Flash: Apple’s refusal to support it in iOS, HTML5’s proposed <Video> tag, and CSS3’s animation capabilities. I’ve addressed each one in the full article on my site (cut here for brevity).

    True craftsmen use different tools for different tasks. Developers are no different. Consider the objectives of each project and choose the appropriate technology. Don’t avoid Flash just because Steve Jobs insulted it or because it’s the trendy thing to do. And don’t use Flash just because it is what you’re comfortable with. I have seen plenty of sites which have been built 100% in Flash for no apparent reason. That’s absurd. Likewise, some developers burn through insane amounts of hours trying to accomplish something with HTML/CSS/JavaScript, making lots of compromises just to avoid Flash. Use Flash if it does the job better (and the reality is that Flash is far superior to HTML/CSS/JavaScript for certain tasks). Otherwise, stick with HTML/CSS/JavaScript which are more search engine friendly and accessible. HTML5 is another great tool for our toolbox, but it certainly doesn’t supplant Flash altogether.

    For the Flash developers out there, the sky isn’t falling. In fact, despite the hype around HTML5, Flash is doing great. Better than ever. I firmly believe that it will continue to be a major player in web and mobile development. Adobe has got some great stuff up their sleeve too, so stay tuned.

    For more thoughts check out Flash vs. HTML5: Faux Drama on my site.

    Jack Doyle
    web: http://blog.greensock.com
    twitter: @tweenlite


    Rich Tretola
    Adobe Community Expert, Author & Speaker

    The biggest misconception is that you can use HTML5 to do anything that can be done with Adobe Flash. At this point, this is not even close to true.

    The rise of HTML5 is an exciting one as it will continue the transformation of the web to a much more rich and interactive experience. Although there is a perception that Adobe and Microsoft both have technologies that compete with HTML5, in my opinion Flash and Silverlight should be used to compliment and not compete with HTML5.

    There’s certainly been a shift in disciplines where Flash is used; Apple’s decision not to include the Flash player on iOS (iPhone, iPad) has led to many companies reconsidering the use of Flash for creating content that can also be created with HTML. This decision is a simple one based on cost of development; by going with HTML5 over Flash, a single application can be created to target all major platforms.

    Before Adobe MAX 2010, I would have argued that HTML5 is ideal for building rich web applications where Adobe Flex currently resides as a tool of choice for many developers. However, after seeing the Adobe sneak peeks and what Adobe has been able to accomplish in the conversion of Flash animation to traditional assets, CSS, and JavaScript it appears the sky is the limit for what can be transitioned to HTML5.

    Since the Flash player will continue to evolve at a much faster pace than HTML5 (which has taken years and is still in progress), it will always offer more options for developers. I also believe that Apple will eventually agree to allow the Flash player on its iOS which will reverse the trend I mentioned earlier.

    Eventually though, Flash and HTML5 will redefine their space in web development with each being used for what it does best. I look forward to the merging of these technologies into a collaborative development space which will ultimately continue to make the user experience a more interactive one.

    Rich Tretola
    web: http://blog.everythingflex.com
    check out: http://twittapolls.com
    twitter: @richtretola


    Paul Neave
    Interaction Designer

    It’s not about the tools or the platform, it’s about the idea.

    There’s no such battle as Flash vs HTML. It’s Flash and HTML. Flash is just one of the many tools in the toolbox, and like any tool it needs to be used in the right way for the right job. And it’s the role of the developer to decide which tool is appropriate.

    The thing I love about Flash most is its cross-platform nature. But its major problem is that it’s a plug-in. It’s a closed off black box and not a native part of the web, despite what Adobe says when it refers to the “full web”. Flash is an augmentation; an extension to add features originally missing from HTML. There was a technological land grab and Flash got there first. But HTML/CSS/JavaScript is encroaching on Flash’s territory fast and within a year we’ll have a web that can do pretty much everything Flash can, if not more. Even 3D is coming to the web soon with WebGL. The only major thing lacking will be device support for webcams and microphones, but that’s on the roadmap.

    So why on earth would anyone write code for a plug-in when the browser can handle it all natively? You could argue that Adobe’s tooling is better. But more often than not, this is when Flash developers get emotional and call JavaScript a “toy language”, and HTML/CSS a cesspool of hacks and incompatibility. But that isn’t true, and it certainly isn’t going to help.

    The Flash work I do these days is mostly device specific rather than generic. Perhaps Flash is becoming less cross-platform and more niche. We now have more devices, browsers and operating systems to deal with than ever before. The good news is that Flash is not going to go away. Flash may become more niche, but it’s relevance will simply shift, not shrink.

    To Flash developers I say: remember why you’re doing this. It’s not about the tools or the platform, it’s about the idea. Never stop creating, and never stop learning!

    Paul Neave
    web: http://www.neave.com
    twitter: @neave


    Rob Larsen
    Interface Architect, Isobar

    [I'm] excited by how far HTML5 has come over the past couple of years

    Personally, I come at this from two angles. There’s the part of me that wants to expand the use of web standards wherever possible and wants to put those technologies to use early and often. That guy is excited by how far HTML5 has come over the past couple of years, with hundreds of developers working long hours to fill in the implementation gaps, allowing us to use some of the most exciting technologies, like Canvas, today. I’m working on a project right now that utilizes a Canvas charting component. That would have been Flash just a couple of years ago. That’s exciting.

    There’s another part of me, the pragmatist, that realizes there’s a limit to what we SHOULD be doing with HTML5 right now, at least in a production environment and a limit to what we will be able to do in the future. I’m responsible to clients, co-workers and users to get the best site or application out the door as efficiently as possible. From that perspective, Flash is a powerful, mature option that I’d be silly to ignore.

    Rob Larsen
    web: http://htmlcssjavascript.com
    twitter: @robreact


    Kevin Suttle
    Flash Platform User Experience Developer

    We’re all working together towards the same goal: the best possible content experiences for our users.

    When I first started in this industry, the tech tabloids hadn’t yet skewed it with terms like “technology wars” and other poorly-researched sensationalism. We just saw the web as a single, wide-open medium, and you know what? It still is.

    HTML5/CSS3 is beginning to extend the web experience for many desktop and mobile browsers. The Flash Platform continues daily to push the limits of desktop applications, mobile devices, tablets, television, and hardware that doesn’t really fit in any one category. As both developers and users, we need to ignore the hype, use the right tool for the job, and remember that we’re all working together towards the same goal: the best possible content experiences for our users.

    Kevin Suttle
    web: http://kevinsuttle.com
    twitter: @kevinSuttle


    Mike Taulty
    Microsoft UK

    The reality is that Silverlight occupies a strong position even in a future world where every user has an HTML5 capable browser.

    It’s common to see “HTML5″ browsers and RIA frameworks like Silverlight presented as an “either/or” choice with the success of one necessitating the hasty demise of the other. The reality is that Silverlight occupies a strong position even in a future world where every user has an “HTML5″ capable browser.

    Silverlight applications can run both in and outside of the browser and offer elevated trust options. The runtime remains cross-browser (IE6,IE7,IE8,IE9, Safari, Chrome, FireFox) and cross-platform (Windows7,Vista,XP,OS X) where it provides a consistent experience. Silverlight also provides a framework for building apps for the new Windows Phone 7 devices to get re-use of code and skills.

    Today, HTML based clients offer the greatest possibility of a client reaching across devices and platforms as HTML browsers are ubiquitous albeit with challenges around using a single set of markup in all browsers. Microsoft’s committed to web standards and is doing a tonne of work in IE9 around “HTML5″ to build a performant implementation in a clean, safe browser that does more to enable this idea of “one markup”.

    As that works gets released and IE9 and other “HTML5″ browsers become the default over time, then developers will be able to take this reach approach across those new HTML5 features like video, audio, canvas, offline storage and so on.

    However, there are still a rich set of capabilities that an “HTML5″ browser doesn’t have which show up in a framework like Silverlight and those sit in 3 main areas of premium media experiences, casual gaming and business applications. Applications need those kinds of capabilities even in an “HTML5″ world and Silverlight will take that forward, innovating at pace.

    For more detailed information on the future of Silverlight – see this longer post from the Silverlight team.

    Mike Taulty
    blog: http://mtaulty.com
    twitter: @mtaulty


    Steve Fulton
    8bitrocket

    I’m looking forward to more great opportunities to make a good living from making cool stuff.

    Adobe needs to make tools to create HTML5 content, that’s just obvious. I’d like to see the Flash IDE export both .swfs and HTML5/JavaScipt/Canvas. Obviously you would have to make concessions for what the HTML5 Canvas can support, but for things like ad units and animations with click-through it should be a no-brainer. Adobe’s reaction though has been a bit defensive, which I think is a mistake. Microsoft is embracing HTML5 in IE 9, but I’m still not sure how much they really believe in it. They have many enterprise customers, and the concept of using Visual Studio to build both your front and backend of the web site is very compelling for them.

    From what I’ve seen, Adobe is taking Flash into the games market in a big way. There are things they showed at Max this year that would be extremely difficult to do in HTML5, and even if you could do them, they would only be supported by a very small subset of browsers. I would also look to Adobe focusing on Air as the delivery mechanism for content to multiple platforms.

    Saying that, I do think HTML5 will take some ground from Flash. For example, content that is consumable by mobile devices where developers currently use Flash to develop only because there is no better alternative. Ad units, simple (and I do mean simple) audio and video players, drop-down navigation, animated overlays, etc. Flash will retain its position in the Games market and Air applications, Flex based apps, e-learning, and applications where the content and code needs to be secure for monetization.

    Biggest misconceptions? Flash is dead. HTML5 sucks. Silverlight is lame. Hyperbole is the realm of the Steve Jobs in the world, developer’s don’t need it. We should think about how we can make use of any decent technology to solve problems.

    Steve Fulton
    web: http://www.8bitrocket.com
    twitter: @8bitrocket


    Remy Sharp
    All Round Supporter of Make Believe Animals

    Both Flash and HTML5 haters are going to be left behind, and frankly good riddance.

    Both Flash and HTML5 haters are going to be left behind, and frankly good riddance. Flash for a long time has been plugging the holes in browsers for us via custom fonts, drawing APIs, SVG support, sockets, video and much more. HTML5 and related specs, for the most part formalises those technologies so that we don’t have to rely on plugins to play a video – and seriously how many flash developers think “Flash” amounts to being able to play a video?

    The biggest misconception I run into is that HTML5 is this single silver bullet that will return the unicorns to the fields and the phoenix to the skies. It’s not. In fact the HTML5 specification is a collection of APIs (the HTML component aside), so it’s not the silver bullet, nor do we need browsers to support every single API before we start making use of just one of them, such as the canvas API, video or perhaps the history API. We should use the right technology for the job, and that’s still true if Flash is the right technology for the job.

    Remy Sharp
    web: http://remysharp.com
    buy my book: http://introducinghtml5.com
    twitter: @rem


    James Whittaker
    UI/UX Architect TweetDeck Inc. & Adobe Community Professional

    I’m hoping that as developers and designers we have learnt from all the bad things that were done in the early days of Flash.

    HTML5 and Flash. Both have really passionate communities surrounding them who actively promote and enjoy sharing code, techniques and solutions. The Flash Platform community is amazing and from personal experience many Flash and Flex dev’s are keen to get a more detailed understanding of HTML5 and JavaScript, they are always looking to learn new stuff, be challenged and see how it could fit into their workflow. Also, don’t forget that many people, including myself, love working with both technologies.

    At TweetDeck our flagship desktop application is built using Adobe Flex and deployed cross platform using Adobe AIR. Adobe AIR was the best and fastest way to build consistent cross platform apps that integrated with the OS using either Flash or HTML. Our application is one of the largest distributed AIR apps in existence and we have really pushed what the platform can do and been amazed with the results.

    We are also busy building an HTML5 version of TweetDeck for deployment as a web app using the Google Chrome Web Store. This will pack the same (if not more!) detailed feature set as the AIR client so it’s giving us a real sense of how these two technologies stack up against each other. For me, the new CSS3 animations and transitions have been really fun to try out.

    Flash has been around for a long time. From animations to tacky skip intro screens it is now a credible platform for building enterprise level apps for desktop and mobile. HTML5 is still very new, I’m hoping that as developers and designers we have learnt from all the bad things that were done in the early days of Flash and don’t repeat them in HTML5.

    Let’s stop arguing and get down to creating amazing experiences.

    James Whittaker
    blog: http://JamesWhittaker.com
    work: http://www.TweetDeck.com
    check out: http://RefreshingApps.com
    twitter: @jmwhittaker


    Your Turn

    You’ve heard it from the horses’ mouths, now let’s see how you feel about what they’ve had to say. We want to hear your comments! Let’s try and keep this discussion civil though..

    Remember, this roundup was originally posted in November, 2010. A lot can change in that time!


Leave a Reply

Click here to cancel reply.

search search search search search
Find an Article
Categories
  • Flash Video Training
  • Hints and Tips
  • Recommended
Please Support Our Sponsors
Recent Posts
  • Workshop Coding Challenge: Fix This Breakout Game
  • Enable the Latest AIR SDK in Flash Professional CS5.5+
  • Quick Tip: Versioning Your Files With Dropbox (via Webdesigntuts+)
  • Workshop: Nuclear Outrun – Critique
  • Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy
Tag Cloud
2011 ActionScript Active Activetuts+ Adobe animation Basic Basix Best Build Button Character Create Creating Critique Custom design Effect Effects Files Flash from Game Guide HTML5 Introduction Macromedia Motion Muzzle part Player Premium Professional Quick Silverlight Simple Text Tool Tutorial Tuts+ Tween Using Video website Workshop
About Our Site:

Hey there and welcome to "Flash Video Training Source", a resource for anybody interested in learning more about Adobe's great tool. We feature educational videos, which will help you master Adobe Flash and help you get to know all of its features. We at "Flash Video Training Source" believe that video training and video... more

Why don't you follow us on Twitter and get the latest video tutorials twitted to your account. Just click on the floating twitter bar to your right!

Go Back In Time
May 2012
M T W T F S S
« Apr    
 123456
78910111213
14151617181920
21222324252627
28293031  
Pretty Blank Box
top

Blogroll

  • Development Blog
  • Documentation
  • Plugins
  • Suggest Ideas
  • Support Forum
  • Themes
  • WordPress Planet

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org

Archives

  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • May 2010
  • April 2010
Powered by WordPress  |  Designed by Elegant Themes  |  Lightning Fast Hosting by Site 5 Hosting