| |
 |
 |
 |
 |
|
Flash Tips for Programmers

Your very first stop on your way to learning and mastering Flash and ActionScript should be Colin Moock's website, and then to pick up a copy of his book ActionScript - The Definitive Guide (hereafter referred to as ASDG), as well as to study the wealth of code examples on his companion site. Veteran programmer or newbie, those are your single best resources and contain pretty much everything you'll need to know.
Still, given those resources, there are a few things that might leave you scratching your head, particularly if you're an impatient sort like myself. I've compiled a list of stumbling blocks below, as well as outline a few techniques for game programmers.
- Can I use my favourite text editor?
Thankfully, yes! If you're accustomed to working with your own editor, you'll probably be quickly frustrated by Flash's built-in one for anything more than a few lines of code. Fortunately, there's an incredibly intuitive and easy way around this. Rather than typing in all your code into a frame or clip script window, you can put it in an external text file and include it much like you would a server-side include or a header file in a c program. Just use #include "myscript.as" to include your script file. Many editors also have ActionScript syntax files that highlight keywords for you, including my own favourite, TextPad.
Some good reasons to use external source files:
- It allows you to make frequent backups of your source code separate from your .fla. This is safer, because if the FLA binary ever gets corrupted, all your code will be lost along with it. And small text files are easier to manage than large FLAs.
- It makes it easer to find a specific line in your code. You can also use any syntax and/or text processing tools at your disposal. You can use CVS more effectively. The list goes on.
- And for applications where you might want to write a skeletal framework and pass that off to a designer to dress up, you may be able to decouple the code from the FLA and keep a 'reference' version of the app that can be debugged independently.
- How do I 'draw' something?
Think about it like this: your movie clips (or 'sprites') are either visible or they're not. You set the position, rotation, scale and the sprite instantly responds to this new setting. You don't have to draw or erase anything manually. The downside to this is that Flash uses a very simple 'dirty rect' scheme; i.e., it will entirely redraw the smallest single rectangle needed to update whatever changed. Unfortunately this method is inefficient when you have only a couple of very small, moving objects at opposite corners of a large (or complex to draw) area.
- How do I use library items in my code?
Once you move beyond simple navigational coding, you will want to be able to take over the task of adding and removing movie clip instances from the scene with code rather than by adding them to frames in the movie. Flash allows ActionScript code to do this but it was one of those dumb things that stumped me for a while. It's explained quite clearly in ASDG, however I'll give you a quick walkthrough...
- Use Insert->New Symbol and create a new movie clip.
- Give it a name. Note: this is not the name you refer to in your ActionScript. We still need to export an identifier.
- This new clip will appear in the Library window. Right-click it and choose Linkage... from the context menu.
- The name you enter here is the name you will use in your script to create instances of this symbol. (Look up MovieClip.attachMovie() in ASDG.)
- The pitfalls of a weakly-typed language.
In a lot of ways, free-wheeling, loosely-typed languages like Perl and ActionScript can be incredibly flexible as well as quick and easy to learn, and you can often do a lot with very little, succinct code. On the other hand, it can make it really difficult to debug typos and other brain farts, since the interpreter/compiler will often swallow horribly wrong code. Some things to remember:
- Undeclared variables can be used without a problem. They will simply contain default 'null' values. Get out of the habit of changing the declaration of a variable name, hoping the parser will pick out the other occurances of it that you forgot to change. If you decide to change the name of a variable, be meticulous with your search and replace before moving on to other coding. And there's no harm in testing often since it's only a ctrl-enter away.
- Undefined functions can be called without a peep from the interpreter. They will simply be ignored. Nasty!
- Re-defining previously defined functions or variables will simply replace the original, including Flash's own internal functions. Eg., declaring your own Date function or 'class' will obscure Flash's very useful Date class. The more you familiarize yourself with Flash's functions, global variables and classes, the better off you will be. If in doubt, before using a very common or obvious-sounding name, look it up in ASDG's reference section to see if it already exists. Using an editor that highlights ActionScript's keywords can be invaluable (as noted above). You might consider doing a search within your own code as well to avoid obscuring your own functions/variables.
- Parser Bugs
Bug or feature? You decide. Here's a doozy that keeps getting me:
if( x == y ) // compare x to y
{
a = b;
}
So what's wrong with that? Other than mimicking classic c-style formatting, it doesn't do at all what you might think. What happens is this: the parser will compare x and y for equality. But rather than skipping over the code between the braces when x != y, it will consider the comment to be the statement to execute when x does equal y!! So the variable a will always be set to the value of b, regardless of the result of the comparison. Writing code in this format:
if( x == y ) { // compare x to y
a = b;
}
can help you to avoid this problem. Personally I am highly annoyed by this problem, as I absolutely detest the latter formatting style. I must wonder... is this is some sort of conspiracy to get holdouts like myself to abandon our preference for easily readable bracing that lines up along the left margin?? sigh. Also be wary of doing:
if( x == y ) // compare x to y
a = b;
for the same reason. The same goes for while() and for() loops, as well as function declarations.
One handy way to find such errors would be to get your text editor to find them. If your editor supports regular expressions, you can try a search using the expression:
)[ \t]*//
Which will look for a closing parenthesis, followed by any number of tabs or spaces, followed by the comment start (//) indicator.
- 'Sprites' and 'filmstrip' animation
Typically, most Flash users will create animated sequences using Flash's authoring tools. i.e., either by creating multi-frame vector art or with the use of tweening, or some combination of those. It is also possible to create sprite animations in a typical 2D bitmap game sense. Many games for example will use a sequence of bitmaps, with color-keyed transparency. There may or may not be an advantage to doing this in your own project. The pros are: a) bitmaps tend to render faster than complicated/anti-aliased vectors, especially detailed ones, b) bitmaps can sometimes look better than vector art. The cons include: a) bitmaps will not scale as well as vector art, b) if your bitmap is antialiased against a background color and contains transparent pixels, the edges of the sprite may not interact well with whatever background they appear over in the movie.
The easiest way to do this with Flash is to create a sequence of gifs, or an animated gif, (containing a transparent color for irregular shapes). A quick way to import a series of sprites is to name them in numbered sequence (eg: 'sprite00', 'sprite01', 'sprite02', etc.). To create a Symbol using this sequence, choose New Symbol from the Insert menu. Select the first image in the sequence, and Flash will ask you if you wish to import the entire sequence. This will automatically generate an animated sequence of bitmaps. Remeber to export an Identifier that you can use in your script, by right-clicking on the symbol in the Library window, choosing Linkage, and entering a name for the Identifier.
It is worth noting that Flash sometimes seems to have problems importing a sequence of gifs -- some frames may change the transparent color for some reason. The only way I have found around this is to delete the library symbol for just that frame and to re-import it. Be warned that I have experienced crashes while doing this, so you should save your movie every time you successfully import and correct any bad frames, making frequent backups so you don't risk losing too much work.
- Scaling animation by time
(I also have a similar Java example.)
One of the problems with games and multimedia, especially since computers with different hardware and different performance could run the same code, is that the more stuff you're drawing, or the larger the display size, or the slower the PC, the slower the frame rate will be. The more this difference becomes apparent, the more extreme the difference in user-experience will be. In order to compensate for this fact, game programmers since the early 90's have adopted the technique of moving objects by time rather than by frame. The typical solution in a language like C or Java might look like this:
while( true )
{
curT = GetTime();
deltaT = curT - prevT;
updateLogic(deltaT);
paintObjects();
prevT = curT;
}
Flash attempts to regulate framerate by allowing you to set a global setting, which it will attempt to maintain to the best of its ability. And in fact, I recommend first attempting to use Flash's built-in frame rate controls since it is quite often 'good enough'. Furthermore, attempting to regulate the framerate yourself opens up a whole other can of worms, not the least of which being problems with 'normal' animations. If however you're a stickler for squeezing the best performance possible out of the system your app is running on, these demos will show you how:
ball.zip [2001-11-14] - This example demonstrates simple motion scaled by time. You can set the movie framerate to any value, and the ball will cover the same distance in the same amount of time. [View ball.swf]
asteroid.zip [2001-11-14] - This example demonstrates both motion and animation scaled by time. Not only does the asteroid move at a consistent speed regardless of framerate/display size, but the asteroid's frames will advance at a constant rate. If you set the movie's framerate below the desired framerate set in the source code, you'll notice that it skips frames. [View asteroid.swf]
Note: both of the above examples have a bottom threshold for a framerate set to 10 frames per second (or 100ms/frame) in the AverageTimer class. So if you set the movie framerate below 10 FPS, it will actually begin to slow the whole thing down at that point. Usually you will want to set some maximum elapsed time per frame so you don't get weird behaviour in your app.
Starfield demo [2003-05-05] - This is a fun demo I put together to test large numbers of objects on screen, iteration through them, etc. This may be useful for beginner ActionScript coders as it contains:
- some simple object-oriented style coding (sort of)
- an object pool that re-uses objects and movieclips for performance
- basic concept of 3D illusion, dividing x and y by z (depth)
- motion scaled by time (again)
Note that all demos will require any associated ActionScript source (.as) files at 'publish' time (it must reside in the same directory as the .fla that includes it), but the swf itself is standalone and does not require them once generated.
Feedback, corrections, etc. appreciated and as usual. Contact me here.
posted: 2001-11-14
edited: 2001-11-17
edited: 2003-05-05
edited: 2003-07-12
|
|
 |
 |
 |
 |
|
|