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:

    // This is a commentary, but it
    // only works on 1 line.

    And the other:

    /* I can put as many things as I want,
    on as many lines as I want */

    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

    1. 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--;
      // equivalent to myValue = myValue - 1;

    2. 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);
    // returns false

    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");
    }
    // returns myValue us 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();
    // returns 5
    trace (i);
    // returns undefined

     


    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]);
    }
    /* returns
    j : j
    $version : WIN 6,0,21,0
    secondClip : _level0.secondClip
    firstClip : _level0.firstClip */
     

    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);
    }
    /* returns
    firstClip */

    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();
    /* returns
    firstClip
    secondClip */

    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");
    /* returns There are 7 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");
    /* returns there are 8 elements in myArray
    This includes the prototype, even tough
    there is nothing in it */


    #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.

    // The file should be names name_File.as
    #include "name_File.as"
    // Notice that there's no ; at the end

     


    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

     

    1. _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();
      // returns _level0

      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 = ...

    2. _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();
    // returns _level0, aka _root
    firstClip.secondClip.whichParent();
    // returns _level0.firstClip
    firstClip.secondClip.thirdClip.whichParent();
    // returns _level0.firstClip.secondClip
     

    1. 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?

     


     

     




    SUPPORTERS:

    kirupa.com's fast and reliable hosting provided by Media Temple.