AS3 101: Functions – Basix

This entry is part 2 of 18 in the AS3 101 Session
« PreviousNext »

This is part 2 of the introduction to ActionScript 3.0 series. We’ll be talking about functions. Just like last time, when we focused on variables, we’ll be primarily targeting the neophyte programmer, who has little to no experience with functions. However, even if you’re relatively comfortable with functions, you may want to skim through this tutorial if certain aspects of them – like datatypes and default values – aren’t quite sitting well with you.

We’ll spend the first half of the tutorial covering things at a more theoretical level, then put some of those ideas to use in the second half. We’ll be building a very simple piece with a series of buttons which swap out the content on another part of the page. There’ll be a few functions in use to accomplish this, primarily one that handles the setting of the content. Make yourself comfortable, go and take a look at the demo, then get stuck into the tut..

Step 1: What is a Function?

If you read the AS3 101 tutorial on variables, then you’ll know that programming variables have their root in mathematics. Functions actually share the same lineage, which is fitting, as variables and functions are the two most fundamental building blocks in any programming language.

In mathematics, a function takes a single value and produces a related single value. That is to say, the function of x is the value y. Feeding x into the function produces a new value y. The same value for x should always produce the same value of y.

In programming, a function can perform the exact same task as in math, but is far less dependent on the input and output values. The idea though, is the same: a more complex task is encapsulated in some kind of wrapper, which we can then execute by simply calling the function.

That is, say we have a little bit of code to draw a star and we need lots of stars drawn in our program. Maybe it takes 10 lines of code to actually draw the star. Rather than writing those 10 lines (or variants of them) over and over again, we can put them into a function. If we do so, every time we need to draw a star we simply call our function by name, rather than copy and paste in those 10 lines every time.

Put another way, in the same manner that variables can give a name to a value, functions give names to tasks. Once defined, the task can be repeated easily by calling it by name.

For those of you who have arrived at ActionScript from other programming backgrounds, or those of you who may be starting here but will dabble in other languages, you may be interested to know the following. What ActionScript calls a "function" is a very foundational concept in all programming, but may go by other names in other languages. For example, in object-oriented programming (OOP) you’ll hear the term "method" much more than function, even through they are essentially the same. Also, the terms "subroutine," "subprogram" and "procedure" are all just synonyms for the same idea.

For more information (or a refresher!) on mathematical functions, please visit Wikipedia’s entry on the subject. To play around with mathematical functions a bit more, Wolfram has an excellent collection of functions and visualizations. For more basic information on programmatic function, again, please refer to Wikipedia.

Step 2: Make a Function Already!

OK, let’s see what it takes to write a function in ActionScript 3.0.

Open up a new Flash document (ActionScript 3, naturally), click in the first frame of the first layer (it should be the only frame available) and press F9 (Windows) or Opt-F9 (Macintosh) to bring up the Actions panel. Go ahead and pin the script so we don’t lose our place if you need to click around elsewhere in the document.

Let’s write the bare minimum we can possibly get away with and still call it a valid function:

function doSomething() {
trace("Doing something.");
}

Now let’s break that down. First, there is a keyword function. This is a reserved word in the ActionScript language and it’s kind of like the var keyword. When you use it, you’re saying that the next thing to follow will be the name of the function (much like the next thing after var is the name of the variable).

In this case, "doSomething" is the name of the function. The rules for naming a function are the same as the rules for naming variables: alphanumeric characters, the underscore and the dollar sign are the only characters allowed and the name cannot start with a number. If you recall the discussion on naming variables, the same sorts of conventions and recommendations apply: Err on the side of descriptive names rather than short names, use camel case (and start with a lowercase letter), etc.

After the name comes a set of empty parentheses. We’ll talk more about these later, but for now, just be aware that they are a required part of the function declaration (and are often considered part of the name, but really aren’t).

Then we have an opening curly brace. At the very end of our snippet we have a closing curly brace. These braces set aside the body of the function. Anything inside the body is code that can be executed. This code is executed when the function is executed (or called). In our case, the function simply traces out a certain message. In our star-drawing scenario, we would have several lines of drawing code in between the braces.

To summarize, the following image shows the anatomy of a (minimal) function:

Step 3: Understanding When the Body Executes

Note that while the code in the function executes when it gets called, the code does NOT execute when the function gets defined. Go ahead and try it by testing the movie right now. At the moment, your script only defines the function, but does not call it. When you test the movie, you should see…nothing! That means everything is working and is to be expected. Mind you, a function is of no use if we don’t call it, so let’s do that next.

Step 4: Call the Function

To call our function we simply write the following into the script:

doSomething();

If you test the movie, adding this line results in a trace being sent to the Output panel:

A few things to understand about the syntax: First, to refer to the function, we simply use its name. Remember, a function can be thought of as a named task. If we changed the name of the function to, say, "doSomethingElse", we’d call it by writing "doSomethingElse()". This is very similar to how variables are named and used.

Secondly, the parentheses at the end are required. They’re known as the execution operator. Without them, we’ve simply referred to the function itself, without asking that it be executed. This is actually a very useful technique, which is why you have to go to the extra step to actually call the function. However, this non-calling technique is beyond the scope of this tutorial and we’ll have to find another opportunity to discuss that. If you want to try it, just remove the parentheses, leaving the function name by itself and run the movie. You’ll see that your trace disappears, because you are no longer actually calling (executing) the function.

Often, the point of a function is to encapsulate a certain task so it can be called not once but any number of times, with the same results each time. Let’s try this: go ahead and copy and paste the doSomething(); line as many times as you like and run the movie. You should see the equivalent number of traces in the Output panel.

Also, note that the order of the function definition and the function call don’t matter. The entire script could look like this:

function doSomething() {
trace("Doing something.");
}
doSomething();

Or this

doSomething();
function log() {
trace("Doing something.");
}

Compare this to variables. If you tried to use a variable before it was declared, that would cause problems and probably errors that would bring your whole program down. ActionScript actually parses through your script and makes sure the functions are defined and available before actually running the rest of the script. There is no real consensus on which one of the above scripts is "correct". Trust your feelings on this one.

Step 5: Understanding Execution Order

Let’s look a little bit more at how and when a function executes. The body of the function executes when it gets called; we know that already. However, it’s important to understand that the script basically treats a function call as if the body of the function were copied and pasted onto the line where the call happens. To illustrate this, let’s write a small script that uses our doSomething function.

function doSomething() {
trace("Doing something.");
}

trace("This happens first.");
doSomething();
trace("This happens last.");

When you run this, you’ll see the following in the Output panel:

Notice that even though the first thing in the script is the function definition, the first thing to actually happen in the program is the trace statement which occurs after the function definition. Then, because we call the function after that trace, we see the trace from the function second and finally the second trace that we make follows that. Again: a function does not execute when it gets defined; it needs to be called in order to run the code.

Step 6: Understanding Parameters

Sometimes, functions can exist in their own isolated world, run a few lines of code and never do anything different. For example, you might have some functions to start and stop playing a video, the logic of which never really changes from use to use.

However, most of the time you want to have a function do a task and vary it slightly from call to call. For instance, loading a video might involve the same steps every time, with the exception of which video file to load. With the help of parameters, we can make a function more flexible by letting us set certain values differently for each function call.

To use a built-in function as an example, consider any one of the mathematical functions, such as Math.max(). max takes two numbers, compares them and returns the one with the higher value. To use max, you have to supply it with two numbers in the form of parameters. Otherwise, it wouldn’t be a very useful function.

It’s important to note that parameters are really just variables. They’re special in that they only last for the duration of the function and the next time the function gets called they will be recreated with (potentially) new values. Once the function exits (finishes), the parameters are swept away. Whilst inside the function they are used exactly in the same way that you use variables. If you need a refresher on the ins and outs of variables, I might suggest you check out my previous AS3 101 tutorial on variables.

To take a tangent into esoterica, you will often hear the term "argument" used synonymously with the term "parameter." However, there’s a subtle difference between the two terms. Technically, a parameter is the variable that the function defines and an argument is the value passed to the parameter when the function is called. In other words, the parameter is the variable name and the argument is the value set to that variable. However, this distinction is largely ignored and most any programmer will know what you’re talking about regardless of the term you use.

What if our doSomething function didn’t simply trace out "doing something", but instead let us customize the message that was traced? Let’s make it so (and, while we’re at it, let’s turn the function name into something a little more pragmatic):

function log(message) {
trace("Log: " + message);
}

See what just happened? We snuck a parameter in between the parentheses. That’s where parameters go (at least in ActionScript). You simply type the name you want the parameter (variable) to have and then you use that name where ever you want that value. That is, it’s just like a variable, only without the "var" keyword.

To call this function and pass along an argument (remember, arguments are the values that get sent to parameters…but that’s splitting hairs), we pull a similar stunt and put the value we want to pass in between the parentheses (the call operator) when we call the function:

log("This isn't just a trace, it's a log.");

When the above function and function call are run, we get the following in the Output panel:

What’s more, we can call log again, but pass in a different value to the message parameter and get similar but varied results. The following full script:

function log(message) {
trace("Log: " + message);
}
log("This isn't just a trace, it's a log.");
log("Here we go again.");

Results in two traces to the Output panel, both prepended with "Log: ", but after that it’s a custom message. We have the beginnings of a custom logging tool that could possibly provide richer and more flexible traces.

If we wanted to include more than one parameter, we could simply put commas between them, making sure they all go between the parentheses. For example, let’s add a level parameter:

function log(message, level) {
if (level >= 1) {
trace("Log: " + message);
}
}

Now we have two parameters. The first is exactly the same as before and we’ve added a level parameter. This will be a number that, if greater than 1, allows the trace to happen. In theory, we could keep log messages active but suppress them by setting their level to 0.

To call the function, we again use a comma to separate the argument list:

log("This isn't just a trace, it's a log.", 2);
log("Here we go again.", 0);

If you run the movie with these changes, you’ll only see the first log message. You can then play around with the idea of log levels by changing the numbers involved, both when calling the function and in the function itself. That is, by changing the line

if (level >= 1)

to

if (level >= 3)

You end up with no traces. Changing it to

if (level >= 0)

gives you two traces. Imagine if you had several dozen log messages peppered throughout your application; you could turn up or down the verbosity of your output by changing a single number in the function. This is just another example of why functions are useful in their ability to encapsulate code and reuse it. A change in one place can change the behavior of several other things.

Step 9: Datatyping Parameters

As you learned in the variables tutorial, a variable can (and should) have a datatype. If you need a brush up on datatypes, I’ll refer you back to the variables tutorial, but the 10 cent summary is this: A variable without a datatype is simply a name referring to some value. By adding a datatype, we can guarantee that the value held by the variable is of a certain type, such as String, Number, MovieClip, or XML. In ActionScript, it looks like this:

var totalPigeons:Number;

The colon designates that the variable on the left will have the type that is declared on the right.

In functions, it’s a good idea to datatype your parameters, for exactly the same reasons that it’s a good idea to type your variables. And it looks awfully similar. We know that our message parameter should be of type String. We also know that the level parameter is numeric, but not only that, it would ideally be a non-negative integer, meaning a uint is a good candidate for a datatype. We’ll modify the function to look like this:

function log(message:String, level:uint) {
if (level >= 1) {
trace("Log: " + message);
}
}

The datatyping of parameters has pretty much the same effect as datatyping normal variables. The most notable is it prevents misuse of the function. Let’s say we got the order of the parameters mixed up and tried to call it like this:

log(2, "This isn't just a trace, it's a log.");

Because we’ve tried to pass a numeric value to a parameter typed as a String and a String to a parameter typed as a uint, we get the following compiler errors when we go to test the movie:

1067: Implicit coercion of a value of type int to an unrelated type String.
1067: Implicit coercion of a value of type String to an unrelated type uint.

"Coercion" is a somewhat nefarious term for the act of trying to change the type of a value. "Implicit coercion" is when we try to do it without explicitly casting the value. This is possible on related types, such as Number, int and uint, but on unrelated types, like Strings and uints, this fails and we get the error. The compiler isn’t smart enough to suggest that perhaps you got the arguments in the wrong order, but you do get a notification that something is wrong and you are forced to correct the mistake.

Step 10: Optional Parameters

Sometimes you need a parameter and sometimes you don’t. In such a case, you can make the parameter optional. To help make things simpler, ActionScript 3.0 provides a method for providing default values to parameters that don’t get passed a value. In fact, it is this default value mechanism that is what makes a parameter optional.

Let’s make the level parameter optional, so that if it’s not passed in, the function can still operate, but assume that we wanted a level of 0. We need to simply change the function signature like so:

function log(message:String, level:uint=0) {

Note the =0 after the declaration and datatype of the second parameter. By typing an equals sign and then some value, we declare that the parameter is optional and provide the default value if the argument is left out.

If we were to then log a few messages:

log("This is an important message", 1);
log("This is another important message");
log("This is a so-so message", 0);

We’ll see that only the first message actually logs. The second one leaves out the level agrument and therefore the function assumes we wanted a value of 0, resulting in no trace.

This brings up the question: what happens when we leave out the message? The message parameter is implicitly declared as required, because it is not declared as optional. If you try to run the movie with the following log in it:

log();

You’ll get this error:

1136: Incorrect number of arguments.  Expected 1.

Which is fairly self-explanatory. There is a total of one required parameter, but we sent along no arguments. Therefore, the number of arguments is not right. This brings up one more item worth mentioning and that is if we had passed along three parameters, we’d get essentially the same error:

1137: Incorrect number of arguments.  Expected no more than 2.

Just keep in mind that the parameters you set down for a function are written in stone and it’s assumed that for a function to work properly, all required parameters must be passed along.

There are, of course, a few rules when it comes to optional parameters. The easiest one to forget is that optional parameters must come after required parameters. For example, this is no good:

function log(level:uint=0, message:String):void {

Lastly, the default values must be compile-time constants, which is a fancy phrase that you can simply think of as meaning nothing too complex. The numeric value 0 is fine. The mathematical expression 1 + 3 is also fine. But Math.sin(0) needs to be calculated at runtime (because Math.sin is a function), is too complex and will throw an error. I won’t lay down the rulebook for what works and what doesn’t. Just try it and if Flash doesn’t like it you’ll hear about it through the Compiler Errors panel.

Step 11: Return Values

Our log function is a sort of button or switch. Like a doorknob that opens a door, it has a function that results in some action being performed. This is fine, normal and expected. Some functions will simply do stuff. However, it’s good to know that a function may not only do something, but may also give you something back. This is called returning a value. If we ever need some math performed, for example, calling a function that returns a value is a good way to go about that.

ActionScript gives us trigonometric functions, such as Math.sin and Math.cos, which are good examples of functions that return a value (as are all of the Math functions). One thing about the trig functions that tends to throw people off is that the angle parameter is a Number which is supposed to be in radians. Most people think in terms of degrees, so a conversion is usually necessary. We can write a function that allows us to pass in a value in degrees and get back the sine value as a return.

function degSin(degrees:Number):Number {
var radians:Number = degrees * Math.PI / 180;
}

A few things happened here. First, notice we have a ":Number" at the very end of the function signature, after the parentheses. This is ActionScript’s way of saying that this function returns a value and that it will be of type Number (or whatever you specify). By specifying a return type, not only are we saying that this function will return a value, we are ensuring that we actually do return a value. Failing to return a value will cause an error, as will returning an error of the wrong type.

The second thing that happened was in the last line, we introduced the return keyword. This does what you might already be thinking it does. It returns the thing to its right. In this case, we figure out the sine of the angle after the degrees have been converted to radians and then we return that value. We’ve actually got some layering going on; when we call degSin, it calls Math.sin, which returns a value to degSin, which then returns a value back to the original calling spot.

Using return values is simple; just call the function where you want the value to be evaluated. For example:

trace("The sine of 45 degrees is " + degSin(45));

What if we don’t return a value, like in our log function? Well, best practice suggests that we still declare those intentions. We can do so by datatyping our function just like we did with the last one, only we use a special type known as "void", like this;

function log(message:String, level:uint=0):void {

This states that the given function will not return any value and attempting to do so will cause an error. It may seem like a trivial thing, but ensuring that all of your functions are properly typed, including the non-returning ones, can actually speed up development by alerting you to problems that arise when the rules aren’t followed.

Lastly, a third thing happened in this step, which I sort of smuggled into the code, but it bears mentioning. Do you know what it is? Of course you do, you’ve got a sharp eye! That’s right, I created a local variable in the degSin function. This doesn’t have much to do with returning values directly, but it’s an important concept and now’s a great time to mention it. When a variable is created within the body of a function, it’s called a local variable. That means it is "local" to the function itself and nothing else has access to it. In other words, they are throw-away variables. This is an important distinction to make because sometimes you want a variable solely for the purposes of the function (as in this case: we just need a temporary conversion from degrees to radians). Then again, sometimes you want the variable to persist, in which case you might wonder why the value you’re setting in a function isn’t available outside of the function.

It boils down to one basic rule: a variable defined outside of a function is available from within the function; a variable defined within a function is not available outside of the function. To clarify; a variable defined within one function is not available within a different function. This starts to get into the topic of scope, which can be hard to grasp, so we’ll stop talking about this here.

For further reading, I again point you to Wikipedia. Twice, in fact. Plus a bonus mention for local variables.

Step 12: The Expanded Function Signature

Let’s recap the anatomy of a function, as it’s expanded quite a bit from where we started.

Step 13: Knowing When to Write a Function

In theory, you could build a complete application where everything in it is a function (in fact, modern OOP applications tend very much toward that extreme). Likewise, it is in theory possible to build a complete application that doesn’t once use a function (although this is actually very difficult in ActionScript, for an application of any useful size).

If you’re just getting started with functions, you should keep in mind that you will absolutely need to write a function to handle events, such as mouse clicks or data loads (more on this later). Beyond that, you should remember my golden rule for knowing when to write functions:

Never write the same thing twice.

That is, if you find yourself writing the exact same thing, or even something very similar, more than once, you can probably put that into a function and just call the function twice.

The primary reason for this is that if you ever need to make an update to that bit of code, you can make the change in a single location. Likewise, if you need to do the same thing in a third location, you can much more easily simply call the function a third time, rather than copying and pasting the code into a third location (which, again, further complicates the maintainability of that chunk of code). Remember our star-drawing example. However, it applies to much less obvious situations, as well.

To make an analogy, reusing the behavior of a function is similar to the idea of reusing the artwork of a symbol in a separate movie clip instance. Just as two instances of the same symbol will both update when the symbol gets changed, two executions of the same function will have different behavior if the task defined by the function is changed.

Incidentally, this concept is more formally known as the DRY principle: Don’t Repeat Yourself.

The only time to not write a function is for performance-critical applications, such as games or audio processors. Functions have an inherent overhead that is incurred by merely calling the function. So, you may choose to sacrifice maintainability for performance in some situations. Those situations tend to be far less common.

Step 14: Build a Content Control Function

We’ll put our knowledge of functions to use by building a simple site that displays a handful of pages, each following a similar template. This will be an extremely simple site and in the real world you’d be putting a lot more care and detail into your functions, but this will serve as a practical demonstration of (one of the many) uses of functions.

As we develop this piece, keep in mind the rule stated in the last step. Imagine how much more tedious and unmaintainable this would be without the functions that we write in the following steps.

If you like, I have provided a starter project for you, with the initial FLA file and the images that we will be loading. Feel free to use it, or feel just as free to go in your own direction with the artwork and images.

I’ve provided a starter project for you, with the initial FLA file and the images that we will be loading. I’m not going to go into great detail on how to create the artwork and set non-code things up. You can feel free to use this FLA file as is, or use it as a point of reference for your own artwork and images. The point is not to achieve a certain style, but to become familiar with functions in a practical setting.

Step 15: Take a Tour of the FLA

There are a number of movie clip buttons created, most of which are on the stage in a column on the left. These are set up to use the same background artwork, just with a different text label inside. Each button is named rather unimagitively: button1_mc through button5_mc.

On the right is the content area. On top of the white background there are two text fields, one with a large bold font for the headline and one with a normal body font for the description. The fields are both set to be dynamic text, so we can work with them through ActionScript. They are also given instance names: title_tf and body_tf. There’s another movie clip button towards the bottom, which will activate a link to the full article. This has an instance name of link_mc. Where’s the image, you ask? Since we are loading images with ActionScript, we’ll go ahead and create a Loader with ActionScript, as well. It doesn’t exist in the FLA where you can see it. We’ll do it all in the code.

Looking past the FLA, you’ll see that there is a directory called images in the same folder. Inside of this are some images that we’ll be loading. Whether you’re using the starter file from the download or creating your own, make sure the FLA is in the same folder as your images folder. To keep things simple we’ll simply publish the SWF to the same folder and expect to load the images from the images folder.

(A quick side note, before we move on to the code: you’ll find that the more you use ActionScript to drive your projects, the less you use the FLA file and the stage in the way that you’re probably used to. This can be disconcerting, but as you get better at setting up your assets through code, the more flexibility you’ll have and the easier it gets to facilitate changes down the road.)

Step 16: Set up the Buttons

We need to set the content of the main piece when the buttons are clicked, so we’ll begin coding by setting up an event listener for the CLICK event on each button. There’s a good chance we’ll do an AS3 101 tutorial on events down the line, so I’ll save in depth discussion on this for later. However, it’s worth noting that in order to add an event listener, we need a function. The function itself is known as the listener or handler. It gets called automatically by the thing causing the event (in our case, a movie clip that was clicked on).

Note that while we define our functions normally, however, we use the name only when using addEventListener. That is, we leave off the call operator (the parentheses). This lets us tell the thing causing the events which function to call, without calling it during set up.

button1_mc.addEventListener(MouseEvent.CLICK, onButton1Click);

function onButton1Click(event:MouseEvent):void {
trace("button 1");
}

function onButton2Click(event:MouseEvent):void {
trace("button 2");
}

function onButton3Click(event:MouseEvent):void {
trace("button 3");
}

function onButton4Click(event:MouseEvent):void {
trace("button 4");
}

function onButton5Click(event:MouseEvent):void {
trace("button 5");
}

Also worth noting, in regards to the ActionScript 3 event system, is that all event listeners (the functions) will get passed exactly one parameter, called an Event object. This object carries useful information about the event that just happened, but we will be largely ignoring it here. However, it is required and so we need to declare it in the function definition or we’ll run into errors similar to the count mismatch errors we saw earlier.

We’ll come back to this section and make the buttons do something far more meaningful than trace out station identification, but for now, test your movie and make sure that it works. You should be able to click on the five main buttons and see the correct output.

Step 17: Write a Content Function

Let’s turn our attention to the content piece. Before we write the function, let’s examine what needs to happen when we populate the template.

• Headline text needs to go into title_tf
• Body text needs to go into body_tf
• An image needs to get loaded into a Loader object (which also needs created)
• The "Read More" button needs to go to a different URL when clicked

Now, let’s be clear on what needs to happen when one of our buttons is clicked and what needs to happen only once, during initialization.

The headline and body text need to get filled in with each click. That one’s easy, but the image will be a little trickier. We need a Loader object, but we don’t need a new Loader object every time. We can reuse the same Loader and just use a new URL each time. For the "Read More" button, the CLICK handler doesn’t need to get recreated every time; we just need a way of using a new URL with each set of content.

We can turn this thought experiment into something practical. If we determine the bits of data that will change with each button click and what remains the same, we have an idea of what pieces need to be passed in to parameters and what pieces can be hard-wired into the body of the function. If you need to, re-read the previous paragraph and try to come up with a list of datum that will customize each function call through parameters.

Here’s my list:

• Body text
• Image URL

Let’s start small and just write a function that will take the pieces we need and simply trace them out.

function setContent(title:String, body:String, imageUrl:String, link:String):void {
trace("title: " + title);
trace("body:  " + body);
trace("image: " + imageUrl);
}

As luck would have it, all of our data is of String type. That’s pure coincidence and this technique will work with any datatype. We could have required a URLRequest object for the URL parameters, but that would have been contrived and you would have known it.

Step 18: Call the Content Function

Back in the onButtonNClick functions, let’s call the setContent function so we can see it in action. Remember, we’re passing in four arguments: the title text, the body text, the image URL and the link URL, in that order. Now, because the body text can be a little long, the resulting code gets a little awkward. If I were to simplify it and use dummy data, a single function call might look something like this:

function onButton1Click(event:MouseEvent):void {
setContent("1", "One", "one.jpg", "http://www.one.com");
}

It just replaces the trace from the previous version of onButton1Click with a call to setContent, passing in four arguments.

However, if we were to pass in actual data, that call would look like this:

function onButton1Click(event:MouseEvent):void {
setContent("Create an Impressive Magnifying Effect with ActionScript 3.0",
"In this tutorial we’ll create a magnifying glass effect, demonstrating use of the displacementMapFilter. The effect can be achieved in a relatively short space of time and with very little code.",
"maginfy.jpg",
"http://flash.tutsplus.com/tutorials/effects/create-an-impressive-magnifying-effect-with-actionscript-30/#more-354"
);
}

It’s messy, but it’s really the same thing. The only differences are that the Strings that we are passing are significantly longer and that I’ve added some returns between the arguments to help with the fact that the Strings are so long. ActionScript doesn’t usually care too much about whitespace. As long as there’s a comma between any two arguments, you can slip in as much or as little whitespace as you like.

OK, now we know what to expect. It’s not that bad; you know not to freak out when you see the following listing, which replaces our previous block of onButtonNClick functions:

function onButton1Click(event:MouseEvent):void {
setContent("Create an Impressive Magnifying Effect with ActionScript 3.0",
"In this tutorial we’ll create a magnifying glass effect, demonstrating use of the displacementMapFilter. The effect can be achieved in a relatively short space of time and with very little code.",
"maginfy.jpg",
"http://flash.tutsplus.com/tutorials/effects/create-an-impressive-magnifying-effect-with-actionscript-30/#more-354"
);
}

function onButton2Click(event:MouseEvent):void {
setContent("Build a Dynamic Flash Gallery with Slider Control",
"In this tutorial, we’ll create a gallery which displays all image files in a given directory. A slider is used to browse easily through the images.",
"slider.jpg",
"http://flash.tutsplus.com/tutorials/xml/build-a-dynamic-gallery-with-actionscript-30-and-php/#more-509"
);
}

function onButton3Click(event:MouseEvent):void {
setContent("Build a Dynamic Guest Book with XML and ActionScript 3.0",
"Guest books are a great thing to enhance the online experience your viewers receive. The ability for the viewer to talk to you and others, respond to questions you’ve raised, comment on your work or just to socialize means a guest book is a must have for most web sites. Let’s see how we can build our own guest book with ActionsScript 3.0, XML and PHP.",
"guestbook.jpg",
"http://flash.tutsplus.com/tutorials/xml/build-a-dynamic-guest-book-with-xml-and-actionscript-30/#more-539"
);
}

function onButton4Click(event:MouseEvent):void {
setContent("Create Your Own Pseudo 3D Pong Game",
"In this tut I’ll describe how to create a basic 3D scene using the new 3D options of Flash Player 10. Then I’ll explain how to add interactivity to the elements and set up a basic pong game. Let’s go..",
"pong.jpg",
"http://flash.tutsplus.com/tutorials/games/create-a-pseudo-3d-pong-game/#more-620"
);
}

function onButton5Click(event:MouseEvent):void {
setContent("Build a Wiimote Controlled Lightsaber Using WiiFlash and Papervision3D",
"Today we’re going to build a wiimote controlled lightsaber using WiiFlash and Papervision3D. The goal of this tutorial will be to learn how to use a wiimote within flash and how to combine it with papervision3D. Afterwards, of course, you can use this app to train for your Jedi mastership.",
"wiimote.png",
"http://flash.tutsplus.com/tutorials/games/build-a-wiimote-controlled-lightsaber-using-wiiflash-and-papervision3d/#more-634"
);
}

Normally I suggest that when you’re learning a programming language, you’re best off typing everything in rather than copying and pasting. In this case, though, so much of it is simply arbitrary data that I would encourage you to go ahead and copy and paste this block of code, unless you really want to type it out. If you want, you can always type in your own, less intense data to get practice in the concepts, then copy and paste when you feel you’ve got it.

However you get this code into your script, it let’s us test the setContent function while passing along different values for each button click. Test the movie and click on the buttons. You should see relevant information show up in the Output panel. The setContent function is only just beginning.

Step 19: Fill in the Text

Let’s hop back to the setContent function. We’re ready to make it do something more significant. Rather than trace the title, let’s fill in the on-screen TextField. In setContent, replace the line that traces the title with this:

title_tf.text = title;

Likewise, we can fill in the body text field, too, replace that body trace with:

body_tf.text = body;

Dynamic text fields have a text property that lets you set or get the text contents of the field. We’re just passing the title and body text from the parameters to the respective text fields.

If you run the movie again, you should at least see a headline and body show up in the content area. Now we’re getting somewhere!

Note that at this point, we’re calling setting content from a total of five places, yet we are making changes in a single location in our script and it’s affecting how all five of those content setting actions are behaving. This is because we have encapsulated the task of setting content into a named function and we call it by name, rather than by copying and pasting code around.

Before we can load an image, we need something to load it into. Outside of our function, perhaps towards the top of the script, create a variable that holds a Loader. While we’re at it, add it as a child to content_mc and position it.

var image:Loader = new Loader();
image.x = 170;
image.y = 34;

Remember, we’re going to reuse the Loader and simply load a new image into it when we switch out the content. To do that, hop back to the setContent function and add the following:

var url:URLRequest = new URLRequest("images/" + imageUrl);
image.load(url);

Note that we are using two variables, "url" and "image", in two different scopes. The url variable is declared in the function and so it’s a local variable for the function and ceases to exist once the function ends. The image variable, on the other hand, is declared in the main body of the script, so it persists from function call to function call. Also, we don’t declare it in the function, we simply use it. Therefore, when we use it, we are referencing the Loader object we created initially and reusing it every time we want to load an image.

Go ahead and test. You should now have images with your content. Excellent work!

Notice another advantage of using a function here. We are ultimately merely passing the image name and letting the function dictate where to look for the image. We’re putting "images/" in front of the image name, which means all images (at least for this content piece) should be in the images directory. If we ever needed to change the name or location of the image directory, then we just need to update that information in one place – the function.

Step 21: Set up the Link

The link URL is a slightly different beast. It’s similar to the Loader in that we need to create the button outside of the function so that it persists. Setting it up involves another function; this one to handle the button’s CLICK.

Again, in the main part of the script, add an event listener to the button:

link_mc.addEventListener(MouseEvent.CLICK, onReadMoreClick);

Also, while we’re there, define that function:

function onReadMoreClick(me:MouseEvent):void {

}

For now, we’ll fill it in with some hard-coded functionality, to illustrate what we’re going to do. All we really need to do is open a link in a new browser window. This is fairly simple to do, but it will get a little more complicated when we make it dynamic, so let’s take it in phases.

We need to create another URLRequest pointing at our desired URL (we’ll just use the FlashTuts+ home page fo now) and then feed that into the navigateToURL function, along with a directive to open a new browser window:

function onReadMoreClick(me:MouseEvent):void {
var url:URLRequest = new URLRequest("http://flash.tutsplus.com");
navigateToURL(url, "_blank");
}

If you test the movie, you’ll see that clicking the button will open up a browser and take you to the FlashTuts+ site.

In anticipation of being more dynamic with this, let’s create another variable that will live in the main application scope (that is, where it can persist, alongside the Loader, etc).

var linkUrl:String;

Then use that variable instead of the literal String we used in the function:

function onReadMoreClick(me:MouseEvent):void {
navigateToURL(url, "_blank");
}

Finally, we need to set that linkUrl variable in the setContent function. This is as simple as setting the value to the value passed in to the link parameter:

linkUrl = link;

The final setContent function should look something like this:

function setContent(title:String, body:String, imageUrl:String, link:String):void {
title_tf.text = title;
body_tf.text = body;
var url:URLRequest = new URLRequest("images/" + imageUrl);
}

You can now test the movie and you should have a fully functional "featured article" piece. This is no small feat and you should be proud of yourself!

Step 22: Add a Sixth Button

You did a great job getting this far, but let’s go one step further. For such a simple site, it’s not wholly unreasonable to think that we could get away without this whole function business. However, to illustrate the general usefulness for encapsulating functionality into a parameterized function, let’s add a sixth button that will add a sixth bit of content.

Before we finalize it, though, let’s imagine what we’d have to do if we didn’t have a setContent function.

• Adding another instance of the button movie clip, with a new label
• Setting up its click handler
• Setting the body text

However, we can cut that workload in half by utilizing our setContent function. With that in place, our tasks become:

• Adding another instance of the button movie clip, with a new label
• Setting up its click handler
• Calling setContent with the appropriate information

At this point in our development, updating the code is simplified. You can find an image for the 6th button in the starter files (already in the images folder) and there is already a Button6 symbol in the library of the starter FLA. Drag it to the stage and give it an instance name of button6_mc. Everything else can be handled with code. Here is the button section of the script, with additions in bold:

button1_mc.addEventListener(MouseEvent.CLICK, onButton1Click);

function onButton1Click(event:MouseEvent):void {
setContent("Create an Impressive Magnifying Effect with ActionScript 3.0",
"In this tutorial we’ll create a magnifying glass effect, demonstrating use of the displacementMapFilter. The effect can be achieved in a relatively short space of time and with very little code.",
"maginfy.jpg",
"http://flash.tutsplus.com/tutorials/effects/create-an-impressive-magnifying-effect-with-actionscript-30/#more-354"
);
}

function onButton2Click(event:MouseEvent):void {
setContent("Build a Dynamic Flash Gallery with Slider Control",
"In this tutorial, we’ll create a gallery which displays all image files in a given directory. A slider is used to browse easily through the images.",
"slider.jpg",
"http://flash.tutsplus.com/tutorials/xml/build-a-dynamic-gallery-with-actionscript-30-and-php/#more-509"
);
}

function onButton3Click(event:MouseEvent):void {
setContent("Build a Dynamic Guest Book with XML and ActionScript 3.0",
"Guest books are a great thing to enhance the online experience your viewers receive. The ability for the viewer to talk to you and others, respond to questions you’ve raised, comment on your work or just to socialize means a guest book is a must have for most web sites. Let’s see how we can build our own guest book with ActionsScript 3.0, XML and PHP.",
"guestbook.jpg",
"http://flash.tutsplus.com/tutorials/xml/build-a-dynamic-guest-book-with-xml-and-actionscript-30/#more-539"
);
}

function onButton4Click(event:MouseEvent):void {
setContent("Create Your Own Pseudo 3D Pong Game",
"In this tut I’ll describe how to create a basic 3D scene using the new 3D options of Flash Player 10. Then I’ll explain how to add interactivity to the elements and set up a basic pong game. Let’s go..",
"pong.jpg",
"http://flash.tutsplus.com/tutorials/games/create-a-pseudo-3d-pong-game/#more-620"
);
}

function onButton5Click(event:MouseEvent):void {
setContent("Build a Wiimote Controlled Lightsaber Using WiiFlash and Papervision3D",
"Today we’re going to build a wiimote controlled lightsaber using WiiFlash and Papervision3D. The goal of this tutorial will be to learn how to use a wiimote within flash and how to combine it with papervision3D. Afterwards, of course, you can use this app to train for your Jedi mastership.",
"wiimote.png",
"http://flash.tutsplus.com/tutorials/games/build-a-wiimote-controlled-lightsaber-using-wiiflash-and-papervision3d/#more-634"
);
}

function onButton6Click(event:MouseEvent):void {
setContent("Intro to Flash Camo: Part 1",
"Welcome to an introduction of the Flash Camouflage Framework. Flash Camo (for short) is a graphics framework that is broken down into 3 core areas: \"Decals\", the \"CSS Parser\" and the \"CamoDisplay\". These systems can be used individually or combined to fit your needs. When used together they form a powerful set of tools to help skin and style any Flash application. With Camo’s modular approach, you can use as little or as much of the framework as you want.\n\nIn this two part tutorial we’re going to build a simple website to show how easy it is to incorporate Flash Camo into your next project.",
"flashcamo.jpg",
"http://flash.tutsplus.com/tutorials/workflow/intro-to-flash-camo-part-1/#more-776"
);
}

From here, it’s not a far leap to externalize our data into an XML document (or even a database) and build our buttons on the fly. A set up like that makes it far easier to keep your content current, but it’s starting to get to be beyond the bounds of this tutorial. Stay tuned, though, as there is an AS3 101 XML tutorial planned.

Step 23: The Finishing Touch

Well, everything looks pretty good, except for one little niggle: the content area is pretty empty when you first start up the movie. You’re probably thinking that we could resolve this by throwing in an extra call to setContent with, say, the first button’s worth of content. For example, if you put this at the very end of your script, you should see it working.

setContent("Create an Impressive Magnifying Effect with ActionScript 3.0",
"In this tutorial we’ll create a magnifying glass effect, demonstrating use of the displacementMapFilter. The effect can be achieved in a relatively short space of time and with very little code.",
"maginfy.jpg",
"http://flash.tutsplus.com/tutorials/effects/create-an-impressive-magnifying-effect-with-actionscript-30/#more-354"
);

But do you remember the principle I mentioned back when I talked about when you should write a function? The one called DRY – don’t repeat yourself? We are repeating ourselves in a big way by adding the above code. What would happen if we needed to change the content displayed by the first button? We’d have to remember to update it in two places. That isn’t good. It would be great if we could just use reuse the function call already written to set the content for the first button.

Well, we can! That function call is itself in another function, the event handler for the first button’s click event. We can just call that function. The only catch is that it’s expecting an Event object as a parameter and the function call will cause errors if we don’t pass it one argument. Here’s one last trick for you: we aren’t even using the event parameter, we are just required to have the parameter because an event will get passed by the click event. However, if we don’t always need a parameter, we can make it optional. If we rewrite the function signature to look like this:

function onButton1Click(event:MouseEvent=null):void {

We can then simply call:

onButton1Click();

At the end of our script to trigger the equivalent of a click on button1, thus making sure the first page of content shows up when we start the movie. Here’s the whole script for reference:

var image:Loader = new Loader();
image.x = 170;
image.y = 34;

navigateToURL(url, "_blank");
}

function onButton1Click(event:MouseEvent=null):void {
setContent("Create an Impressive Magnifying Effect with ActionScript 3.0",
"In this tutorial we’ll create a magnifying glass effect, demonstrating use of the displacementMapFilter. The effect can be achieved in a relatively short space of time and with very little code.",
"maginfy.jpg",
"http://flash.tutsplus.com/tutorials/effects/create-an-impressive-magnifying-effect-with-actionscript-30/#more-354"
);
}

function onButton2Click(event:MouseEvent):void {
setContent("Build a Dynamic Flash Gallery with Slider Control",
"In this tutorial, we’ll create a gallery which displays all image files in a given directory. A slider is used to browse easily through the images.",
"slider.jpg",
"http://flash.tutsplus.com/tutorials/xml/build-a-dynamic-gallery-with-actionscript-30-and-php/#more-509"
);
}

function onButton3Click(event:MouseEvent):void {
setContent("Build a Dynamic Guest Book with XML and ActionScript 3.0",
"Guest books are a great thing to enhance the online experience your viewers receive. The ability for the viewer to talk to you and others, respond to questions you’ve raised, comment on your work or just to socialize means a guest book is a must have for most web sites. Let’s see how we can build our own guest book with ActionsScript 3.0, XML and PHP.",
"guestbook.jpg",
"http://flash.tutsplus.com/tutorials/xml/build-a-dynamic-guest-book-with-xml-and-actionscript-30/#more-539"
);
}

function onButton4Click(event:MouseEvent):void {
setContent("Create Your Own Pseudo 3D Pong Game",
"In this tut I’ll describe how to create a basic 3D scene using the new 3D options of Flash Player 10. Then I’ll explain how to add interactivity to the elements and set up a basic pong game. Let’s go..",
"pong.jpg",
"http://flash.tutsplus.com/tutorials/games/create-a-pseudo-3d-pong-game/#more-620"
);
}

function onButton5Click(event:MouseEvent):void {
setContent("Build a Wiimote Controlled Lightsaber Using WiiFlash and Papervision3D",
"Today we’re going to build a wiimote controlled lightsaber using WiiFlash and Papervision3D. The goal of this tutorial will be to learn how to use a wiimote within flash and how to combine it with papervision3D. Afterwards, of course, you can use this app to train for your Jedi mastership.",
"wiimote.png",
"http://flash.tutsplus.com/tutorials/games/build-a-wiimote-controlled-lightsaber-using-wiiflash-and-papervision3d/#more-634"
);
}

function onButton6Click(event:MouseEvent):void {
setContent("Intro to Flash Camo: Part 1",
"Welcome to an introduction of the Flash Camouflage Framework. Flash Camo (for short) is a graphics framework that is broken down into 3 core areas: \"Decals\", the \"CSS Parser\" and the \"CamoDisplay\". These systems can be used individually or combined to fit your needs. When used together they form a powerful set of tools to help skin and style any Flash application. With Camo’s modular approach, you can use as little or as much of the framework as you want.\n\nIn this two part tutorial we’re going to build a simple website to show how easy it is to incorporate Flash Camo into your next project.",
"flashcamo.jpg",
"http://flash.tutsplus.com/tutorials/workflow/intro-to-flash-camo-part-1/#more-776"
);
}

function setContent(title:String, body:String, imageUrl:String, link:String):void {
title_tf.text = title;
body_tf.text = body;
var url:URLRequest = new URLRequest("images/" + imageUrl);
}

onButton1Click();

Step 24: Extra Credit

You may want to take the concept that was covered in the Variables tutorial (working with a group of buttons and making only one selectable at a time) and apply it to this project. That’s when things start to get interesting: you take a little bit of knowledge here, a little bit there, mix them together and come up with something awesome.

Conclusion

Hopefully at this point, you, the aspiring ActionScripter, are comfortable with the concept of functions and the crazy things that can be done with them. This tutorial hasn’t even talked about the rest parameter, the call() and apply() methods, function closures, the call stack, recursion and the idea of a function as a first-class object. That will come later. However, you should be armed with enough knowledge about the fundamental usage of functions to start compartmentalizing your programs into reusable chunks of code.

Just remember, if you ever find yourself typing the same (or very similar) thing twice, you should think about using functions!

Tags: Basix
• Rhett Lowe

I am a Java programmer at heart, but have been letting that rust and go by the way side for a couple of years. I love your tutorials. they are helping me to remember some of the smaller nuances of my loved programming language.

after typing the name of my button method into end of my script, I received an expected arguments error. I understand why I got it (i.e. the button function is expecting a MouseEvent event to be passed) so I tried creating a new mouse event

magnify(new MouseEvent(“MouseEvent.CLICK”));

This works to throw off the computer but still doesn’t populate the event with a target for later on when I added the mouseEnable and Alpha changing function.

Here are my questions:
1) is there a way to call the button function (in my case “magnify();” without the MouseEvent that I am missing?
2) How would I instill the MovieClip into the artificial MouseEvent?

• ATJ

You’re Awesome !

• Keith

Dru,

This tute was easy to follow in a project that can be used in a real scenario.

Thanks heaps.

• torm

YOU rule maaan! :)

• torm

i’ve just got one question… is it possible to make Extra Credit with DRY ?

• mickatron

Rad tutorial! I’m learning a load with this series and I’m not 100% new to AS or Flash – freaken awesome!

For others the only thing that I had a tid bit of a hard time understading was the Loader – the code just seemed so simple I didnt understand how this was achieving an actual loading bar on the page which is what I assumed it would do.

But then I remembered that flash has pre built loader componant (its been in there for quite some time now) which is what you used here right and just calling the prebuilt Loader() function call?

Again – freaken awesome!

• http://www.krenzgaming.webs.com Kyler

Great tutorial but I got confused on some parts. Sometimes you say: “Post this in the “blah function” (or replace the trace event)” and I took out a vital part of the code and I didn’t find out until I went down and looked at the full code.

• Chud37

Alo,

useful i guess, Im coming over from VB, ASP, PHP and im finding AS3 slightly confusing in parts.. But i dont see why you didnt have one button function and simply just do a long IF or SELECT or SWITCH (whatever it is in AS3), you could pass the var thru in the eventListener line.

Anyway, when would i need to use to Actionscript files, and why arnt they used in these basic tutorials?

:)

But good though, thanks.

• http://www.2c2b.net/tezt/yoyo.html Rustin

awesome tutorial :-)

did the var tut this morning:: awesome as well = been forcing myself to write custom classes piecing together code that I vaguely understood, forcing myself & projects on my software engineering contact that relieves my anxiety of xml, php, asp…

ThankYOU so much, it’s finally starting to make sense, I’m ready and you’ve arrived!!! please keep up the good work….

with some simple addOns to this code such as import tween & ease classes

function setContent(title:String, body:String, imageUrl:String, link:String):void {
title_tf.text = title;
body_tf.text = body;
var url:URLRequest = new URLRequest(“images/” + imageUrl);
}

I’ll rework http://www.2c2b.net/tezt/yoyo.html so all the text & thumbnails images are Strings from the custom class = smaller file size and easily modified

• http://everythingfla.com/ EverythingFLA

Dru Fantastic in depth article,

if any of the readers here wants to add into this great article and other related topics check out this video :
http://everythingfla.com/courses/video/10/84

or roam around on the site for many more free goodies as well ;)

• Rehor

• http://stateofbliss.us Firsh

Never write someting twice.

Step 16: you’ve just wrote something 5 times :) Maybe it’s a bit advanced(?) but I’d write a loop for adding the event handlers and using only one click function. Differentiating the clicks based on the event.target or event.target.name.

Anyway where could I find some examples of using a function witout execution operator?

• Ben

Can someboy explain to me how I could put the whole selected button transparency from the first lesson into this lesson?

• http://www.thebrowncrayon.com Justin

It seems like this was a long time ago but just in case you or others still may want to know. :0) I just figured it out for myself so I thought I might share.

Its pretty much the same code set up as before but if you wanted to keep in the spirit of not repeating yourself you could set up a different function to be called from each of the button clicks, I called mine toggleButton(). This function would accept a Movieclip. So my function definition looks like this..

function toggleButton( thisButton:MovieClip ) : void

“thisButton” is the variable for the “event.target as MovieClip” we will end up sending from inside any of the buttonclick functions.

The function toggleButton would pretty much be the exact same as the previous lesson with the selected button opacity except we would have to add the line…

currentButton = thisButton;

That line resets the currentButton to the button that just called it the function.

Here would be the whole function

function toggleButton( thisButton:MovieClip ) : void {
if(currentButton){
currentButton.alpha = 1;
currentButton.mouseEnabled = true;
}
currentButton = thisButton;
currentButton.alpha = .7;
currentButton.mouseEnabled = false;

}

Another problem I ran into was that once I got the above code working I was getting an error from the onButton1click() call at the end of the script that set the initial content when the movie first loads. Now that we’ve added a toggleButton() function from inside the oneButton1Click function, it is expecting to send an event target of type MovieClip, but it doesn’t exist yet because nothing has been clicked when we load the movie. I looked it up and ran across the topic of manually dispatching events. Without too much in depth explanation you can manually tell the program that a button has been pressed by replacing your last line with this.

button1_mc.dispatchEvent(new MouseEvent(MouseEvent.CLICK, true, false));

There’s lots of help docs out there on dispatching events. This is were I found this one.

I hope this helps you or someone else.

Happy Scripting :0)

• Pingback: Week 5 | Learning Interactive Media

• Kev Man

I must be retarded.

I didnt understand the last one, i dont understand this one.
After about 5 steps, im just copy and pasting, hoping that it will hit me and ill understand all of this, which isnt happening.

I have yet to find anyone who can give me the same definition for method, function, class, and package. Even after reading this, i cant identify a function unless someone points it out.

What am i missing?

• Kev

Step 17:
“We could have required a URLRequest object for the URL parameters, but that would have been contrived and you would have known it.”

No i wouldnt have. I have no idea what is going on at this point. This, like every other tut i have gone thru, the only people who get anything out of this, are people with a programming or actionscript background.

No one know how to teach an absolute beginner. I have tried many, many times for several years to learn AS3, and its been nothing but frustration. AS3 is pretty useless unless you know a lot of it. The basics, by themselves do nothing but kick errors. The simplest things are so overly complicated, that you pretty much have to parrot what someone else knows how to do rather than being shown the core of how things work, then apply those principles.

If anyone has some constructive advice, i am desperate for it!!!

• Bharat

IT is good, But if we add
image.height=285;
image.width=339 ;

it is not working. While I want if my image size is not same then how to manage it ?

Kindly focus this question.

Bharat Tiwari

• http://geekygraphicgirl.com Val

Hey this is a great series of tuts, and I can’t wait to finish them all. I did this and at the end when i put the called the function onButton1Click I got the Incorrect number of arguments. Expected 1. error. If I take out the call to the function, it works.
any idea why?

I am using FlashCS5

anyway, thanks for a great series of tuts!

• http://www.actionscriptinstitute.com Ravi

Nice, great post for new comers,

I can understand you have implemented some of the methods using very vast and comprehensive code while you could do it using a shortest way because you are creating all the things for new comers.

Thanks,

• snick

An extremely useful concept for beginners is that variables can be directly assigned to MovieClip symbols! (unlike other symbols)
This means that the title, body, imageURL, etc… can be dynamic properties assigned to each button, and easily accessible using event.currentTarget in the button click handler.
The MovieClip is essentially working like an AS3 Programming Object. (a collection of properties)

Here’s a basic example to illustrate the concept.
On the stage, two MovieClips with instance names “b1″, “b2″

// for each button on the stage (“b1″, “b2″, etc…);
b1.title = String(“button1 was clicked!”);
b1.body = String(“this is the body copy for button1″);

b2.title = String(“button2 was clicked!”);
b2.body = String(“this is the body copy for button2″);

// only one function is needed to serve all of the buttons
function anyButtonClicked(event:MouseEvent):void
{
var currentButton:MovieClip = MovieClip(event.currentTarget);
trace(currentButton.title + “\n”,
currentButton.body + “\n”,
currentButton.externalLink + “\n” + “.” + “\n”);
}

• KMT

Great tutorial. There are a couple of minor issues that it may help you to be aware of.The URLs given for the Continue Reading (link_mc) button have changed since the tutorial was written. Replace “flash” with “active” in the URLs, or you’ll get a “page not found.” Also, if you are typing the code, you must type “maginfy.jpg” (note the misspelling of magnify) for the button1 image.

• Domhnall O’ Suibhne

Again a dreat tutorial. Had a problem with the beginning of the tutorial though where the log level >=2 was supposed to display only certain mesages. In my case all messages were displayed no matter what was specified.

function log(message, level) {

if(level >= 2);

trace (“Log: “+message);

}

log(“This isnt just a trace its a log”, 1);

log (“here we go again”, 0);

This did not work as it was supposed (say , for example the if (level<=0) is set as stat then only log ("here we go again", 0); should display, im my case all were displayed no matter what changes were made. Where have I gone wrong?

• Kiibo12

Your body structure of the IF statement is formatted incorrectly. Replace the semicolon at if(level >= 2); with an open curly brace and add a close curly brace after trace (“Log: “+message); . In the end your code should look like this:

function log(message, level) {

if(level >= 2) {

trace (“Log: “+message);
}

}

log(“This isnt just a trace its a log”, 1);

log (“here we go again”, 0);

• Kiibo12

If you’re wondering why links don’t work, just replace flash.tutsplus to active.tutsplus

• Jesus de Cos

Very good tutorial. I knew yet part of its contents, but the part about optional parameters and the one about loaders were useful to me. Thanks