The Same Applet: Code Placed in a Custom AS3 Class

The applet below has exactly the same functionality as the applet on the previous page. Yet the code behind it is organized in a very different way. Most of the code has been moved into a custom AS3 class TriangleBoard. The class is contained in the file TriangleBoard.as which you will find in the zipped package below as well as the fla file as3_class_intro_2.fla corresponding to this applet. On this page, we discuss the class structure and compare it to the MainTimeline code from the previous page.

Download

Note: The fla files as3_class_intro_2.fla, as3_class_intro_3.fla, as3_class_intro_4.fla all use the class TriangleBoard. Thus, the file TriangleBoard.as must be in the same directory as the corresponding fla file for the fla file to compile.

The Anatomy of A Class

Let us look at the code in TriangleBoard.as class file and identify those elements that are common to all classes and those specific to our class. First we see:

package {

 

import flash.display.Sprite;

import flash.display.Shape;

import flash.events.MouseEvent;

import flash.filters.DropShadowFilter;

 

public class TriangleBoard extends Sprite {

 

.......................

.......................

.......................

 

}

}

Every AS3 class has to be included in a package. A package is the pathway through a series of nested subfolders at the end of which the class resides. If the class is meant to reside in the same folder as the fla file that uses it, you can simply use the keyword 'package' as we did above.

Then there come import statements. When you place your code on the Timeline, attached to a frame in your fla file, all the main AS3 packages, like flash.display.*, flash.filters.* are automatically imported. Occasionally, you may have to import some event classes for components and, of course, any custom classes you are using if they are not in the same folder. It is not so if you are putting your code in a class. You have to specifically import the packages of AS3 built-in classes or individual classes that you need. In our class, we need the Shape, the Sprite, the MouseEvent, and the DropShadowFilter classes so we import them. For each class we specify the folder in which the class is contained, e.g. flash.display, flash.events, etc.

Our class extends the Sprite class which means that any instance of TriangleBoard will be a Sprite and will inherit all the methods and properties of the Sprite class. It will also have additional properties and methods that we define within the class. Let's look past the 'package' and import statements. We have our class declaration containing its name (the name of the class must match the name of the .as file in which the class is saved). Then come the variables declarations. Variables within a class are called 'properties', functions are called 'methods'. Each property or a method has access modifiers: private, public, internal, or protected. In our class, we use only the 'private' and the 'public' modifiers. Private properties and methods can be accessed only from within the class, public properties and methods are accessible through any instance of the class. As you see, we declare all the same variables as we had in our Timeline code except for spBoard. (spBoard will be replaced in our fla file by an instance of the TriangleBoard class.)

public class TriangleBoard extends Sprite {

 

private var shTriangle:Shape;

private var spPoint1:Sprite;

private var spPoint2:Sprite;

private var spPoint3:Sprite;

private var boardWidth:Number;

private var boardHeight:Number;

private var colorBack:Number;

private var colorBorder:Number;

private var colorDot:Number;

private var colorTriangleBorder:Number;

private var colorTriangleFill:Number;

private var radiusDot:Number;

private var numPoints:int;

private var isDragging1:Boolean;

private var isDragging2:Boolean;

private var isDragging3:Boolean;

.......................

.......................

}

Note that we declare our variables and their datatypes but we do not initialize them. Initiallization will take place within the class constructor that comes next. The class constructor is a public method with the same name as the class itself. A class constructor may or may not take parameters. Ours does take two parameters. The return datatype for a class constructor must not be specified.

public function TriangleBoard(w:Number,h:Number){

 

this.boardWidth=w;

this.boardHeight=h;

this.shTriangle=new Shape();

this.addChild(shTriangle);

this.spPoint1=new Sprite();

this.addChild(spPoint1);

this.spPoint2=new Sprite();

this.addChild(spPoint2);

this.spPoint3=new Sprite();

this.addChild(spPoint3);

this.colorBack=0xFFFFFF;

this.colorBorder=0x000000;

this.colorDot=0xCC0000;

this.colorTriangleBorder=0x000000;

this.colorTriangleFill=0x6699FF;

this.radiusDot=5;

this.numPoints=0;

this.isDragging1 = false;

this.isDragging2 = false;

this.isDragging3 = false;

drawBack();

setUpListeners();

}

The constructor is evoked with the key word 'new' when, in your script that uses the class, you create an instance of the class. For example:

var board:TriangleBoard=new TriangleBoard(400,300);

The constructor performs all the initialization tasks. The word 'this' within the constructor (and throughout the class) refers to an instance of the class created when the constructor is evoked. The instance created above is stored in the variable 'board'. We passed to the constructor the width and the height we want for our instance of TriangleBoard.

Please note that the initial values for the variables set in the constructor are the same as in our Timeline script on the previous page. Similarly, we call the drawBack function and set up all listeners via setUpListeners() function call. (Both functions are defined within the body of the class.)

The body of our class closely parallels the Timeline script from the previous page. Looking past the constructor, we see:

private function drawBack():void {

this.graphics.clear();

this.graphics.lineStyle(1,colorBorder);

this.graphics.beginFill(colorBack);

this.graphics.drawRect(0, 0, boardWidth, boardHeight);

this.graphics.endFill();

this.filters = [ new DropShadowFilter() ];

}

It is the same function as before with 'spBoard' replaced by 'this'. So are most of other methods defined within the class:

private function drawPoint(n:int):void {

 

...............................

 

}

 

private function drawTriangle():void {

 

...............................

 

}

All listeners are the same as before. They are all assigned within one method 'setUpListeners':

private function setUpListeners():void {

this.addEventListener(MouseEvent.CLICK, placePoint);

this.addEventListener(MouseEvent.MOUSE_MOVE, updateTriangle);

this.addEventListener(MouseEvent.ROLL_OUT, stopDragging);

this.addEventListener(MouseEvent.MOUSE_UP, stopDragging);

spPoint1.addEventListener(MouseEvent.MOUSE_DOWN, startDragging1);

spPoint2.addEventListener(MouseEvent.MOUSE_DOWN, startDragging2);

spPoint3.addEventListener(MouseEvent.MOUSE_DOWN, startDragging3);

}

The listeners themselves are the same as before:

private function placePoint(e:MouseEvent):void {

 

...............................

 

}

Other listeners: updateTriangle, stopDragging, startDragging1, startDragging2, and startDragging3 are exactly the same as before with the 'private' modifier in front of them. So are the helper functions 'limitX' and 'limitY'.

As you see, all variables and methods so far have been declared as 'private'. Thus a programmer using the class will not be able to access them directly (without editing the class). Let's look at the public methods of our class. Those will be used to customize and manipulate an instance.

public function changeColorBack(c:Number):void {

colorBack=c;

drawBack();

}

 

The latter method will be used to customize the background color of an instance of TriangleBoard. Note that making the property 'colorBack' public wouldn't exactly give us what we want. A programmer could change the value of the variable 'colorBack' after creating an instance of TriangleBoard, but without redrawing the background, that is, without calling the 'drawBack' function, the color would not change. Thus, instead of making 'colorBack' and 'drawBack' public, we create a public method that does exactly what the programmer may want to do. The situation is similar with changing the colors of the dots and the triangle. It is advisable to create specific methods for doing that:

public function changeColorDot(c:Number):void {

colorDot=c;

if(numPoints==3){

drawPoint(1);

drawPoint(2);

drawPoint(3);

} else if(numPoints==2){

drawPoint(1);

drawPoint(2);

} else if(numPoints==1){

drawPoint(1);

} else {

}

}

 

public function changeColorTriangle(c:Number):void {

colorTriangleFill=c;

if(numPoints==3){

drawTriangle();

}

}

The next public method clears the board:

public function resetBoard():void {

var i:int;

for(i=1;i<=3;i++){

this["spPoint"+String(i)].graphics.clear();

this["isDragging"+String(i)]=false;

}

shTriangle.graphics.clear();

numPoints = 0;

}

Let us see now how we can use the class to create our applet. On Frame 1 of the MainTimeline we place the following code:

var board:TriangleBoard = new TriangleBoard(400,300);

this.addChild(board);

board.x = 50;

board.y = 10;

btnReset.addEventListener(MouseEvent.CLICK, resetAll);

function resetAll(e:MouseEvent):void {

board.resetBoard();

}

After a class is defined, the Timeline code becomes very simple.

Note: We should make a couple of points as they may not be obvious from our example. First, all code besides variables declarations within any class, must be placed inside methods or the class constructor. Second, a custom class creates a new datatype. Above, we declared our variable 'board' to be of datatype TriangleBoard. Without our custom class such a declaration would not be accepted by the compiler.

On the next two pages, we show two other applets that use our custom class.

Back to Bridging the Gap Tutorials              Back to Flash and Math Home

We welcome your comments, suggestions, and contributions. Click the Contact Us link below and email one of us.

Adobe®, Flash®, ActionScript®, Flex® are registered trademarks of Adobe Systems Incorporated.