On this page we discuss the code for the simpler example, Example 1. If you prefer to look at the code directly, in the corresponding fla file, download the file names_part1.fla from page 1 of this tutorial. In our comments below, we try to explain all the main points of the script.
We begin by defining variables whose names are self-explanatory:
var dotSize:Number=10;
var boardSize:Number=280;
The variable numDots stores the current number of dots on the board.
var numDots:Number=0;
'curDispNum' stores the total number of dots created from the start of the movie or after clicking RESET button. The number includes all dots, even those deleted later by the user after they were created.
var curDispNum:Number=0;
We are creating a Sprite, spBoard, that will serve as a board for the user to work on. We add spBoard as a child of 'this', that is, the MainTimeline, and position spBoard within the main movie.
var spBoard:Sprite=new Sprite();
this.addChild(spBoard);
spBoard.x=(620-boardSize)-20;
spBoard.y=20;
We create a Shape, shPolygon, which we add as a child of spBoard. shPolygon will hold the fill created by joining the dots on the board.
var shPolygon:Shape=new Shape();
spBoard.addChild(shPolygon);
shPolygon.filters = [ new DropShadowFilter() ];
The Sprite, spDotHolder, will contain the dots created when the user clicks on spBoard. Having a separate container for dots serves two purposes. First, it is easier to keep track of the depth of each dot as spDotHolder has no other children but dots. Second, since we make spDotHolder a child of the MainTimeline ('this'), when the dot appears, the area of spBoard under the dot will no longer respond to mouse clicks. Thus, the user cannot create dots that completely overlap. (See the tutorial Areas Behind Display Objects and Mouse Events...)
var spDotHolder:Sprite=new Sprite();
this.addChild(spDotHolder);
spDotHolder.x=(620-boardSize)-20;
spDotHolder.y=20;
We are calling a function that draws a white rectangle in spBoard.
drawBoard();
function drawBoard():void {
spBoard.graphics.lineStyle(1,0x000000);
spBoard.graphics.beginFill(0xFFFFFF);
spBoard.graphics.drawRect(0,0,boardSize,boardSize);
spBoard.graphics.endFill();
spBoard.filters = [ new DropShadowFilter() ];
}
We add an event listener to spBoard that responds to mouse clicks. When the user clicks on spBoard, a new dot is created, plotted, and added as a child of spDotHolder on the highest consecutive depths, i.e. spDotHolder.numChildren. We add an event listener to each new dot so the user can remove it by clicking on it. We limit the number of dots to 999 only because the labels on dots would look unsightly with more than three digits. After a new dot is added, we update the fill by calling 'updatePolygon' function.
spBoard.addEventListener(MouseEvent.CLICK,boardClicked);
function boardClicked(e:MouseEvent):void {
var curX:Number=spBoard.mouseX;
var curY:Number=spBoard.mouseY;
if(checkCoords(curX,curY) && numDots < 999){
var currentDot:Sprite=new Sprite();
numDots+=1;
curDispNum+=1;
plotDot(currentDot);
spDotHolder.addChildAt(currentDot,spDotHolder.numChildren);
currentDot.x=curX;
currentDot.y=curY;
currentDot.addEventListener(MouseEvent.CLICK, dotClicked);
updatePolygon();
}
}
When a dot is clicked, we remove it from the Display List, update the value of numDots, and update the fill. We also remove the event listener attached to the dot. Stray event listeners can cause problems. Note that even though e.currentTarget is a dot and, thus, it is a Sprite, we need to cast it to a Sprite -- Sprite(e.currenTarget)-- in order to avoid a compiler error in Strict Mode. Casting for complex datatypes tells the compiler to treat the object being cast as the datatype to which we cast, in this case a Sprite.
function dotClicked(e:MouseEvent):void {
var curSprite:Sprite;
curSprite=Sprite(e.currentTarget);
spDotHolder.removeChild(curSprite);
curSprite.removeEventListener(MouseEvent.CLICK,dotClicked);
numDots+=-1;
updatePolygon();
}
The next function creates a format for dots' labels.
function setLabelFormat(tf:TextField):void {
var labelFormat:TextFormat=new TextFormat();
labelFormat.color=0xFFFFFF;
labelFormat.size=10;
labelFormat.font="Arial";
tf.defaultTextFormat=labelFormat;
}
The next function plots a circle and adds a label to it which displays the consecutive number of the dot being plotted (curDispNum). Note: we set curTextField.mouseEnabled to false, to avoid the mouse cursor changing to the text cursor when the user mouses over the text field.
function plotDot(s:Sprite):void {
var curTextField:TextField= new TextField();
curTextField.autoSize=TextFieldAutoSize.LEFT;
setLabelFormat(curTextField);
curTextField.text=String(curDispNum);
s.graphics.lineStyle(1,0x000000);
s.graphics.beginFill(0x0000CC);
s.graphics.drawCircle(0,0,dotSize);
s.graphics.endFill();
s.addChildAt(curTextField,s.numChildren);
curTextField.x=-curTextField.width/2;
curTextField.y=-curTextField.height/2;
curTextField.mouseEnabled=false;
s.filters = [ new DropShadowFilter() ];
}
The updatePolygon function is called each time when a dot is created or deleted. It draws a fill by moving from one child of spDotHolder to the next, in order of their depths. Because adding and deleting children moves other children so they fill the depths in between, the dots are automatically kept in order that they were created. The method that we need to access each next dot is spDotHolder.getChildAt(..). We cast it to Sprite, Sprite(.....), to avoid compiler errors in Strict Mode.
function updatePolygon():void {
var curX:Number;
var curY:Number;
var i:Number;
var curDot:Sprite;
shPolygon.graphics.clear();
if(numDots==2){
curDot=Sprite(spDotHolder.getChildAt(0));
shPolygon.graphics.lineStyle(1,0x000000);
shPolygon.graphics.moveTo(curDot.x,curDot.y);
curDot=Sprite(spDotHolder.getChildAt(1));
shPolygon.graphics.lineTo(curDot.x,curDot.y);
}
if(numDots > 2){
curDot=Sprite(spDotHolder.getChildAt(0));
shPolygon.graphics.lineStyle(1,0x000000);
shPolygon.graphics.beginFill(0xFFCC00);
shPolygon.graphics.moveTo(curDot.x,curDot.y);
for(i=1;i<numDots;i++){
curDot=Sprite(spDotHolder.getChildAt(i));
shPolygon.graphics.lineTo(curDot.x,curDot.y);
}
curDot=Sprite(spDotHolder.getChildAt(0));
shPolygon.graphics.lineTo(curDot.x,curDot.y);
shPolygon.graphics.endFill();
}
}
'checkCoords' is a helper function that is called from boardClicked to check if the user clicked sufficiently far away from the spBoard's boundary for the new dot to fit within the white square.
function checkCoords(a:Number,b:Number):Boolean {
if(a>dotSize && a<(boardSize-dotSize) && b>dotSize && b<(boardSize-dotSize)){
return true;
} else {
return false;
}
}
The RESET button clears drawings in dots and removes all the listeners attached to dots. Then, the function removes all the dots from the Display List. (Simple removal from the Display List does not clear circles and labels. They remain in AVM and eat memory.) Again, the only method we need is getChildAt and, again, we have to cast to Sprite, Sprite(...), even though dots are Sprites. Note: Sprite(spDotHolder.getChildAt(i)).removeChildAt(0); removes the text label from each dot.
btnReset.addEventListener(MouseEvent.CLICK,resetClicked);
function resetClicked(e:MouseEvent):void {
var i:Number;
for(i=0;i<numDots;i++){
Sprite(spDotHolder.getChildAt(i)).graphics.clear();
Sprite(spDotHolder.getChildAt(i)).removeChildAt(0);
Sprite(spDotHolder.getChildAt(i)).removeEventListener(MouseEvent.CLICK, dotClicked);
}
while(spDotHolder.numChildren>0){
spDotHolder.removeChildAt(0);
}
numDots=0;
curDispNum=0;
shPolygon.graphics.clear();
}
On the next page, we highlight the changes in the code that need to be made to meet challenges of Example 2.










