Learn Some
ActionScript Tricks
by ilyas usal for now, but more people soon, I hope
One of the most important things for me in Actionscript is to have
a clear code. The shorter the better, for you and for the people who are going to read your
code.
This article gathers all the things I consider essential to write better code, but there is more.
That's why I hope everybody will share his little tricks with us, so that we can put everything
here.
I will talk about:
comment on your code
incrementation/decrementation
simple if...else tests
the tertiary operator
the var declaration
for...in loops
#include of a code
easy random color
_root, _parent and this
using prototypes instead of functions
comment on your code
Most of the best programmers on the world will tell you that: always comment on your code.
For yourself and for the others. This is absolutely vital. Personally, before writing any line of code,
I write in commentary everything I want to do. All the functions, and what they are doing.
It is a very good habit because it gives you a clear idea of what you have to do, if you
want to modify something a year later, you'll be happy to know what all your functions do, and if
you give your fla to someone, it will be a great help for him to understand it.
There are two ways to comment:
And the other:
Of course, any code put in there will NOT be executed. That's why it is also useful for debugging
your code (you can try to take out parts that might not work in order to test the fla).
incrementation/decrementation
-
increment by 1
First: what does increment mean? When I say that I
increment a value by 1, it only means that I add 1 to this
value. There are several ways I can do that, the obvious
one being:
myValue = myValue +
1;
But there is a faster way: with the
++ operator. It will go
like this:
myValue++;
It has the exact same effect, but it's faster and
cleaner. You can do the exact same with -, which is called
decrementation:
myValue--;
-
Increment by another value
This time, I want to add a number to a value. The usual
way would be:
myValue = myValue +
3;
Well, there's a much shorter way to do that:
myValue += 3;
It also works with the other operators:
myValue -= 3;
myValue *= 3;
myValue /= 3;
simple if...else tests
There's a very useful shortcut in if...else tests when
you test whether a variable equals 0 or not. But you have to
know how to use the ! operator. This operator is used to
invert a boolean.
What does that mean? It means that if you have:
myBool =
true;
trace (!myBool);
It is also used to test the inequality between two
numbers, objects... Remember that in Flash, 0 is equivalent
to false, and any other number is considered as true.
myValue = 5;
if (myValue != 0)
{
trace ("myValue is not 0");
}
Now to test whether a number is or isn't equal to 0,
instead of doing:
if (myValue == 0)
//...
if (myValue != 0) //...
You can do respectively:
if (!myValue) //...
if (myValue) //...
Imagine that myValue = 0.
!myValue will be evaluated
as true. The same way if myValue =
5, !myValue will be
evaluated as false.
the tertiary operator
This operator is also used to shorten if tests. It
is used in the case that: if something is true, then 1 (or
0) thing happens, otherwise 1 (or 0) thing happens. Usually,
we would write it like this:
if
(i<5)
{
i++;
}
else
{
i--;
}
The first thing we can improve concerns the brackets:
when there's only 1 instruction after a if or a
else, you can forget about them:
if
(i<5) i++;
else i--;
The next step is to use the tertiary operator: A?B:C,
which means "if A is true, then B, else C". In our previous
example, it would give:
(i<5)?i++:i-- ;
If you don't want anything to happen, replace B or C by
null. If you want something
more complex to happen, replace B or C by a function.
the var declaration
This is not a very important issue for small movies, but
it is a good thing to think about it.
Declaring a variable as var makes it local to the
function in which it is declared. Therefore it cannot be
accessed from outside the function, and it is destroyed at
the end of each loop. So it is just a memory issue, but it
can become important on important projects.
function test ()
{
var i = 5;
trace (i);
}
test();
trace (i);
for...in loops
for...in loops are tricky
to use. What they do is simple though: they reference
everything they find in an object and put it in an array.
For instance, if we create two movie clips in the _root, and
then check what is in the _root, we will do it like that:
_root.createEmptyMovieClip("firstClip",1);
_root.createEmptyMovieClip("secondClip",2);
var j;
for (j in _root)
{
trace (j+" : "+this[j]);
}
Not so hard, but you can see that it returns all sorts of
things. Imagine that we want to get the movie clips only.
_root.createEmptyMovieClip("firstClip",1);
firstClip.createEmptyMovieClip("secondClip",1);
var j;
for (j in _root)
{
if (this[j]
instanceof MovieClip)
trace (j);
}
We only get the first clip because this time we created
the second clip INSIDE the first clip, so it is not in
_root. To find all the clips on the scene, we'd have to make
a recursive function that checks inside all the clips to
find movie clip.
_root.createEmptyMovieClip("firstClip",1);
firstClip.createEmptyMovieClip("secondClip",1);
MovieClip.prototype.searchClip =
function()
{
var j;
for (j in
this)
{
if (this[j]
instanceof MovieClip)
{
trace (j);
this[j].searchClip();
}
}
}
_root.searchClip();
In the first 2 lines of our script, we create a first
clip, and inside it a second clip. Then we define our
function (in fact a prototype, look for a text about them
here). The prototype checks the object that called it first,
checks whether what it finds is a movie clip, and if so
applies itself to that object. That's called recursion.
It is also practical to browse through arrays:
myArray =
new Array ("Kirupa","Supra","Upuaut","Phil","Eyez","Phil","Jubby");
count=0;
var j;
for (j in
myArray)
{
count++;
}
trace ("There are "+count+" elements
in myArray");
It works. But you have to be careful, because if you
define an array prototype, it will appear in the list.
It works. But you have to be careful, because if you define an array
prototype, it will appear in the list.
Array.prototype.myPrototype
= function () {}
myArray = new Array
("Kirupa","Supra","Upuaut","Phil","Eyez","Phil","Jubby");
count=0;
var j;
for (j in myArray)
{
count++;
}
trace ("There are "+count+" elements in myArray");
#include of a code
This is very scarcely used by coders, but it exists... it
can be useful if you use the same code many times, so
instead of copying and pasting it which can be painful if
you want to correct something, you can import the as file
and make your corrections once for all. Actually, this
advantage is not really obvious now that Flash MX allows you
to turn everything into a function.
#include "name_File.as"
easy random color
Some of you may have read Kirupa's tutorial about random
colors, and you may have found that it was very very
complicated. Well don't worry, there is a much easier method
that I will explain here.
First you have to know that colors in Flash are represented
by hexadecimal values, that is to say numbers that look
like:
myColor = 0xFF0055;
The 0x means it's
hexadecimal, followed by 6 digits going from 0 to 15, except
they are noted A=10, B=11, C=12, D=13, E=14 and F=15. The 2
first digits code the red (FF is totally red, 00 is no red),
the 2 middle digits code the green and the last 2 code the
blue.
Now to get a random color, all we have to do is take a
random hexadecimal value, between 0x000000 and 0xFFFFFF, and
then round it. Then we can do whatever we want with it
(check the setRGB() tutorial for more information about that
function). Here I tint an object called square:
myColor =
Math.round(
Math.random()*0xFFFFFF );
myColoredObject = new Color (_root.square);
myColoredObject.setRGB(myColor);
_root, _parent and this
- _root
_root is an alias, just as _parent and this. It is used to
access the root of the current level. For instance, if you
write this in the first frame of your movie:
MovieClip.prototype.whichRoot =
function () {trace (_root);}
_root.createEmptyMovieClip("firstClip",1);
firstClip.createEmptyMovieClip("secondClip",1);
firstClip.secondClip.whichRoot();
Quite normal, since the default level is 0. But if you
load a movie in _level1, and if that movie is refering to
_root, it will mean _level1. So be careful about that: to
access the _root of the master movie from the loaded
movie, you have to write:
_level0._root.myVariable = ...
- _parent
OK, now _parent is quite similar, except it refers to the
clip that is one "layer" higher in the tree. In this
example, _root creates (hence contains) firstClip,
so it is his parent, firstClip creates
secondClip, which creates thirdClip:
MovieClip.prototype.whichParent =
function () {trace (this._parent);}
_root.createEmptyMovieClip("firstClip",1);
firstClip.createEmptyMovieClip("secondClip",1);
firstClip.secondClip.createEmptyMovieClip("thirdClip",1);
firstClip.whichParent();
firstClip.secondClip.whichParent();
firstClip.secondClip.thirdClip.whichParent();
- this
this refers to the current object. It is particularly
useful in Flash MX when you build a prototype, as we will
see later.
It is also vital now that Flash handles variables scope
differently. In Flash 5, declaring a variable in an
onClipEvent(enterFrame) made the variable relative to
the clip. It's over now, since all the variables left
alone are relative to the current timeline. That's why if
several objects use the same method, prototype or function
at the same time, they can all modify the same variables,
so the animation cannot run normaly.
That's why you have to tell Flash when your variables
depend on the current object by declaring them as part of
this:
onClipEvent (enterFrame)
{
this.myVar = 5;
}
If you hadn't put this, and that there was a
variable called myVar on
the _root, this variable would have been replaced by that
one. You see the problem?