I would have to say that Flash Action Script has not been an easy language or environment to learn. At my job I’ve had the benefit of observing other software engineers learn Flash. Based on my own experience, my observation and questions I get asked I have compiled a list of the most common problems associated with programming in Flash. This is a list of what they are and what to do about them. If I was starting out learning Action Script 2 in Flash I would take the time to read this.
1. 90% of problems in flash are Scope issues. Remember that. Every time something doesn’t work I start to trace out the references and variables I have in my code. Am I referring to the object or variable I am trying to use? Does this variable contain the information I think it does? 90% of the time it is a scope issue. That means that the movieclip, object or variable I am trying to access in my code is not available in the location I am typing it in. Your code runs in its own scope in the movie. That means it has it’s own set of variables and references it can access locally. Everything else you have to go up the provided scope chain. To find other movieclips or objects from that scope you need to know the absolute or relative path to that other object. That means using _parent.someMovieClip rather than someMovieClip. For more info click here
Use trace(“myMovieClip_mc=”+myMovieClip_mc) to see if the movieclip is there
Use trace(“myVariable=”+myVariable) to check if your variable has the value you expect
Use trace(“this=”+this) to see what the keyword “this” is
In your classes always use event delegation:
myBtn.onRelease = Delegate.create(this, myFunction);
// where myFunction is a method of the class
Do not use:
myBtn.onRelease = function () { }
in a class.
Nested functions are evil. Actually, nested functions inside class methods are evil. They are not actually evil but they break the lexical scope chain. So what normally works now stops working because the function is nested in another function. The nested function code block goes out of scope. Only the local variables and the parent functions local variables are accessible to your nested function. The keyword “this” ends up revering to the activation object that was created at the time the function was created rather than the class you are in. The solution is to use scope delegation to keep the function in scope and if possible make the function a class method.
Quick Rules of scope
1. Always use Delegate.create method inside of classes
2. Never use nested functions. If you do anyway use the delegation class. See above.
3. ALWAYS!!! trace out variables, references and “this” to verify you are getting what you expect
2. 90% of what you are trying to do has already been done. If you do not know your resources you know nothing. Learn all the properties of the movieclip class. Go through the help docs and read. Learn all the classes that are available to you. Learn all about the V2 UI Components. I am telling you, 90% of what you want to do has already been done. Look in the docs. Get familiar with every class, every property, every method and every event that exists. Before you start, search google for what you are doing. Consult other flash developers. Know what resources you have before you start. I cannot emphasize this enough. This is most applicable before you start a project. Know all you have available.
Here is how I find what I need (99% of the time I get it):
1. Open the Flash help panel and search on the keyword if it is a method, property or object.
2. If it is on a component then I look in the Components Dictionary. I look at the component for the property or method. If its not there I look in the inherited classes.
4. If I have another developer next to me I ask them.
3. If I cannot find any information in the Help panel I look on live docs.
4. If I cannot find anything on Live docs then I search google.
5. If I do not find it on google I search FlashNewbies, FlashCoders or http://flashmx2004.com/forums.
6. By now I have come to the point to compose a nice message and post it to FlashCoders or FlashNewbies.
7. If I cannot get a response from either of those two newsgroups I email one of the few component developers/friends of mine.
8. If they don’t know I contact an offshore Flash coder friend and offer some money for him to find the answer for me. :)
3. Case sensitivity. Small issue but gets many new developers. In other words, “myMovieClip” is NOT the same as “mymovieclip”. Keep case sensitivity in mind.
4. Know when to ask for help. If you spend more than an hour or two on a single item then it’s time to ask for help. Do a search on google or post a question to a group like flash newbies or flash coders. It takes someone 5 minutes to tell you “that’s a bug” as opposed to you spending “2 days” spinning your wheels wondering why it’s not working.
5. Do stand alone examples working by themselves before integrating them in a more complex project. Do them on the timeline if possible before putting them in class. The Flash compiler is not as strict with code on the timeline but at the same time it does not have the same scope issues. I figure the trade off is better since I keep all my code in the actions of frame 1. Addendum: Classes are harder to debug and setup than code on the timeline. For newbies, when something doesn’t work it is much harder to debug in a class than in the timeline (the timelines do not have half as many scope issues). If you are not a newbie, I suggest you do stand alone examples with a class and using FlashDevelop with mtasc syntax checking. It is more strict than the MM compiler and will help you catch some not so obvious bugs.
6. Use Flash Remoting for anything server side. Use flash remoting. It is easy, fast, reusable, free (in php and a few others) and it WILL SAVE YOU TIME!!! Trust me. It will save you tons of time when you get it. There are some tutorials on www.amfphp.org. It is not to hard to setup and all you need is PHP support.
7. The Flash components are your friends. They are good, skinnable feature packed components. Anyone who says otherwise does not know what they are talking about. I have been using them and extending them for 3 years now. They are also relatively light weight. What?? You say. Yes, they have an initial 50kb weight because each component inherits a set of base classes but each additional V2 components only add a few kb more because the base classes have already been included in the first component. Read the classes in the $flash/Classes folders. You will learn an incredible amount of useful information from them.
That’s it for now. Please post any of your tips.
> Nested functions are evil. Actually, nested functions inside class methods are evil.
I submit that there are some things that there just isn’t really a good way to do without them. Particularly if you are tying to keep things general, such as a method that you intend to be used to do the same basic thing in numerous situations and/or subclasses, and thus expect to be called by a variety of different “client code.” Keeping things general and flexible always pays off from a design standpoint in these kinds of cases, and there are a lot of things that ask for functions as arguments, and you aren’t able to specify any arguments for those functions in addition than the ones they normally get — but you need them to have access to data that you’re receiving as parameters.
Take my DataGrid numeric-sorting function. “client code” calls it with arguments including the DataGrid it is intended to work on, and an array of integers specifying which columns are intended to be sorted numerically. It then sets up an EventListener for the headerRelease event — a function that checks to see if this is one of those numeric columns and chooses a sorting method accordingly. This listener is a function that needs to know what DataGrid it’s working with, but it can get that from the event object that it gets as its only parameter — which is the problem. You can’t very well ask ActionScript to please please let a listener accept more arguments just this once, and the function *also* needs to know which columns were specified as needing numeric sorting. You can only get that information from the enclosing scope — the function that adds the numeric-sorting listener. You sure can’t write a separate class-level function for every possible combination of DataGrid columns that numeric sorting might be wanted on.
Of course, you could hard-code the column numbers for the right columns every individual time you want a certain DataGrid column to sort numerically, but then you’re making the kind of busy work for yourself that Object Orientation was supposed to be about freeing us from. The way I wrote the numeric-sorting-setup-function, you can simply paste it into your code, call it with the right arguments, and there’s no need to dive into it and go hacking around.
I should mention, yes, I did have to use Delegate to get it to work… and really, there are some situations where you *should* have to use Delegate, and other situations where it’s just a hack to work around a certain really lame bug.
> Do them on the timeline if possible before putting them in class.
I don’t know about this one. It seems from my experience that the main timeline is a lot looser with types and scope than class-based code. More than once already (in the whole couple months I’ve been working with ActionScript), I’ve been given something that works on the timeline but I have to a lot of messing with before it will work in a class.
> I should mention, yes, I did have to use Delegate to get it to work…
Holy crap, apparently I was wrong… the DataGrid sorter thingie actually works *without* using Delegate even *once*… my mistake. So you don’t need to *always* use Delegate.
I think anytime you Delegate to “this,” however, you’re working around a bug that needs to go.
I’m enjoying working with ActionScript so far, but version 3.0 can’t come soon enough for me.
I see your point. I stress not using nested functions (with or without delegatation) because as long as you don’t need a reference to any variable outside the limited scope of a nested function, it very easily happens that I’ll accidently refer to a variable outside that scope. It then comes back to bite me when that variable is out of scope. Using delegation in the first place helps me avoid those type of problems. Once AS3 is here we won’t have to worry about it.
I ran into this code recently in the Text Input component class:
// addEnterEvents is a method of the class
function addEnterEvents():Void
{
if (enterListener == undefined)
{
enterListener = new Object();
enterListener.owner = this;
enterListener.onKeyDown = enterOnKeyDown;
}
}
// enterOnKeyDown is a method of the class
function enterOnKeyDown():Void {
if (Key.getAscii() == Key.ENTER) {
owner.dispatchEvent({type:”enter”});
}
}
The following coding is working for me in another project. But now i am doing one new project. Delegate function is not working. Pls Help me.
function FFlippingBookClass()
{
//this is the main movieclip
this.zooming.onMotionChanged = mx.utils.Delegate.create(this, function ()
{
var _loc4 = 2;
trace(“zooming motion” +this.zooming.zoomProg);
this.zooming.zoomFactor = 1 + (_loc4 – 1) * this.zooming.zoomProg;
this._xscale = this._yscale = this.zooming.zoomFactor * 100;
var _loc2 = this.zooming.centeredX – this.zooming.anchorX * (this.zooming.zoomFactor – 1);
var _loc3 = this.zooming.centeredY – this.zooming.anchorY * (this.zooming.zoomFactor – 1);
if (this._model._currentPage – 2 this._model._realPages.length – 1)
{
_loc2 = this._bookWidth * this.zooming.zoomFactor / 2;
} // end else if
trace(“widht heiht “+ this._x +” “+ this._y);
this._x = _loc2;
this._y = _loc3;
});
this.zoomIn = function ()
{
this.onZoomIn();
this.zooming.mag_mc._visible = false;
this.zooming.hand_mc = this._parent.attachMovie(“handIcon”, “hand_mc”, this._parent.getNextHighestDepth());
this.zooming.hand_mc._visible = false;
this.zooming.hand_mc.onEnterFrame = function ()
{
this._x = Math.round(this._parent._xmouse) – 8;
this._y = Math.round(this._parent._ymouse) – 8;
};
if (this.zooming.anchorX == null)
{
this.zooming.anchorX = 0;
} // end if
if (this.zooming.anchorY == null)
{
this.zooming.anchorY = 0;
} // end if
this.zooming.isZoomed = true;
this.zooming.tween.stop();
this.zooming.tween = new mx.transitions.Tween(this.zooming, “zoomProg”, mx.transitions.easing.Regular.easeInOut, this.zooming.zoomProg, 1, 10);
this.zooming.tween.onMotionChanged = this.zooming.onMotionChanged;
this.setMask(this.zooming.mask_mc);
};
}
I want one more help. How to access the function of one class in ( i have one swf, in that onclick i have to access the this class function) swf object function. This swf attached in this project and class also in same project.
Hi Geetha – Please ask this same question on stackoverflow.com using tags Flash, ActionScript2.