Web DevCenter
oreilly.comSafari Books Online.Conferences.
MySQL Conference and Expo April 14-17, 2008, Santa Clara, CA

Sponsored Developer Resources

Web Columns
Adobe GoLive
Essential JavaScript
Megnut

Web Topics
All Articles
Browsers
ColdFusion
CSS
Database
Flash
Graphics
HTML/XHTML/DHTML
Scripting Languages
Tools
Weblogs

Atom 1.0 Feed RSS 1.0 Feed RSS 2.0 Feed

Learning Lab






ActionScript Cookbook

An Introduction to OOP in Flash and ActionScript, Part 2

by Joey Lott, author of ActionScript Cookbook
08/19/2003

In Part 1 of this article we looked at the basics of how to work with the built-in ActionScript class. These classes include MovieClip, Array, Date, and many more. Learning how to first work with the built-in classes is a very important step in object-oriented programming. And for many developers, that much may suffice.

However, learning to create your own custom classes in ActionScript can really propel your efficiency to another level. In the second part of this series we'll take a look at how custom classes can be a benefit, and then we'll look at how to actually create your own custom ActionScript classes.

Why Make Custom Classes?

There are a lot of things you can do in this world. So before you launch off into learning something new it is often wise to ask why. In this case, it is important to ask why building a custom ActionScript class is such a great idea. If you're going to invest your time in learning how to accomplish this task, you want to first make sure it's worthwhile.

So what are the benefits of building custom classes? The potential benefits are too numerous to list. But to give a few examples:

Related Reading

Actionscript Cookbook
Solutions and Examples for Flash MX Developers
By Joey Lott

  • Custom classes enable you to efficiently reuse code. Rather than reinvent the wheel each time, you can simply utilize the class you created once. For example, if you find that many of your applications utilize a certain functionality to arrange objects on the stage, you might create a class that facilitates that. You can then reuse the class in multiple projects.

  • Custom classes enable you to encapsulate your code. This is at the heart of object-oriented programming. Rather than having one long code routine in your program, you can encapsulate related portions into a class. This helps make your code more readable. It also helps you organize and focus your code.

  • Custom classes can help you accomplish things that would otherwise be difficult or tedious to accomplish. Imagine if every time you wanted to accomplish a single task you had to write 30 lines of code. If you want to have this one thing occur multiple times within the same application then you could end up with an unwieldy amount of code. And to further complicate matters you'll probably have to also keep track of a lot of variables associated with those operations. But by creating a custom class you can make this whole process much simpler.

Basically, if you like to do things the hard way, then read no further. But if you want to work smarter, not harder, then welcome to custom classes.

Of Classes and Prototypes

Let's begin our discussion of how to create custom classes by looking at how Flash MX determines inheritance. Inheritance refers to instances of a class automatically getting the methods and properties of the class. Unlike languages with a formal class structure, Flash MX ActionScript uses what is known as prototype-based inheritance. The class is defined by what we call a top-level object. This top-level object has a property-named prototype. All instances of the class automatically inherit all methods and properties assigned to the prototype. Because of the way the built-in classes are defined, they don't all allow you to see the methods and properties of their prototype. Some do, however. The XML class is one such class. You can see this for yourself:

  1. Open a new Flash document.
  2. On the first frame of the default layer of the main timeline add the following code:
    for(var item in XML.prototype) {
      trace(item);
    }
  3. Test the movie.

When you try this you should see a list of the properties and methods of the XML class listed in the Output window. Even without having to know what these properties and methods actually do, you can verify that they correspond to the properties and methods listed in the Actions toolbox for the XML class.

Adding to Existing Prototypes

Next, before we create a new prototype for a totally new class, let's look at how we can add a new property or method to an existing prototype. We'll employ the same techniques to add properties and methods to the new custom prototypes as well, so this is a good starting point.

Let's add one property and one method to the MovieClip prototype. Once we've defined the new property and method we can access them from any movie clip instance. We can add new properties and methods to a prototype just the same way as we added custom properties and methods to objects in Part 1 of this article. Only now, instead of applying the custom property or method to the instance, we apply them to the prototype. The new property we'll add to the MovieClip class is called currentDepth. We'll initialize it to 1.

MovieClip.prototype.currentDepth = 1;

Now, we'll add a method, getNewDepth(). This method will return the value of currentDepth, and then increment currentDepth.

MovieClip.prototype.getNewDepth = function() {
  return this.currentDepth++;
};

Now, from any movie clip instance you can utilize the property and method. The getNewDepth() method can be particularly useful if you programmatically add a lot of movie clips and/or text fields to your movies using duplicateMovieClip(), attachMovie(), createEmptyMovie(), and createTextField(). Here is an example. Notice that getNewDepth() can be invoked from any movie clip.

var newDepth = this.getNewDepth();
this.createEmptyMovieClip("holder_mc", newDepth);
var nestedNewDepth = holder_mc.getNewDepth();
holder_mc.createEmptyMovieClip("nested_mc", nestedNewDepth);

Creating New Prototypes

Adding new properties and methods to existing classes can be moderately useful. But we're more interested in creating new prototypes. So how does one go about such a thing? It's actually quite simple: Define a function. Believe it or not, that's all there is to it. For example:

function NewClass() {
}

Each new function automatically has a prototype property to which you can assign properties and methods. When a function is used as a simple function, of course, we don't work with the prototype at all. But in cases where we want to define a new class we first create the function (we call this the constructor function), and then we assign the properties and methods to the prototype. For example, if the function/class name is NewClass, as in the preceding example, then we can add new properties and methods to the prototype as follows:

NewClass.prototype.someProperty = "someValue";
NewClass.prototype.someMethod = function() {
  trace("someMethod called");
};

You can then create a new instance of the NewClass class using a new statement just as with many of the built-in classes.

var nc = new NewClass();

And you can then utilize the properties and methods of that instance:

trace(nc.someProperty);
nc.someMethod();

Now, of course, the NewClass example is not particularly useful. So instead, let's look at an example of a class that you might actually want to use. Here we create a Drawer class. This class allows you to specify a movie clip, and then you can tell it to draw a circle in the movie clip.

function Drawer(mc) {
  this.mc = mc;
}

Drawer.prototype.mc;

Drawer.prototype.drawCircle = function(radius, x, y, outlineColor, fillColor) {
  this.mc.lineStyle(1, outlineColor, 100);
  if(fillColor != undefined) {
    this.mc.beginFill(fillColor, 100);
  }
  var angleDelta = Math.PI / 4;
  var ctrlDist = radius/Math.cos(angleDelta/2);
  var angle = 0;
  var rx, ry, ax, ay;
  this.mc.moveTo(x + radius, y);
  for (var i = 0; i < 8; i++) {
    angle += angleDelta;
    rx = x + Math.cos(angle-(angleDelta/2))*(ctrlDist);
    ry = y + Math.sin(angle-(angleDelta/2))*(ctrlDist);
    ax = x + Math.cos(angle)*radius;
    ay = y + Math.sin(angle)*radius;
    this.mc.curveTo(rx, ry, ax, ay);
  }
};

Notice that the constructor function for the Drawer class accepts a parameter. This parameter is a reference to the movie clip in which it can draw. The drawCircle() method then draws a circle in that movie clip. Here's an example:

drwr = new Drawer(this);
drwr.drawCircle(100, 0, 0, 0, 0xFDACFD);

The Drawer class is a pretty simple class as it stands, but obviously you could add many more methods to it for drawing different types of shapes.

Pages: 1, 2, 3

Next Pagearrow