< Day Day Up >
Finding and Fixing Run-Time Bugs
You've made it through the process of exporting an application without a compile-time
error. So far, so good. But as you begin to work with the exported application, you
discover that it's just not working properly. Perhaps displayed data is not correct, text and
graphics onscreen are not positioned correctly, or when you press a button that's
supposed to send information to the server, nothing (or the wrong thing) happens. These
kinds of bugs are known as run-time bugs because they're not obvious until the
application is run and put through the ringer.
Run-time bugs typically result from spelling or logic errors, such as mistakenly referring
to a movie clip instance named miMovie_mc instead of myMovie_mc, or using a less-
than operator (<) rather than the intended greater-than operator (>) in a conditional
statement. Or a function might contain a script that's logically but not syntactically faulty,
so that when executed the function has a very bad effect on the rest of the application.
Unfortunately, information about these kinds of bugs doesn't automatically show up in
the Output window; a bit of sleuthing and logical deduction is required to find and
eliminate such errors.
Fortunately, Flash provides several tools to help you perform various deductive reasoning
tasks with your project while it plays. The two most widely used tools are the trace()
action and the Debugger. We'll look at both of these tools in the following sections.
Using the trace() action
The trace() action allows you to output a custom message to the Output panel in response
to a script's execution. This is useful to get a behind-the-scenes look at how a script is
functioning—primarily to test interactivity and to output custom messages that tell you
what's happening with the data in a movie at any point in time. Consider the following
simple example.
Imagine you want to place the following script on Frame 10 of your movie:
trace ("The movie is currently on Frame " + _currentframe);
This step converts the square to a movie clip.
7. With the Property Inspector open, select the square movie clip instance and give it
an instance name of myClip_mc.
Now we'll do some scripting.
8. With the Actions panel open, select Layer 1 and add the following script:
9.
10. myButton_btn.onPress = function(){
11.
12. trace("Activation button is pressed");
13.
14. myTraceTest();
15.
16. }
17.
This script is executed when the myButton_btn is clicked. The script performs two
functions. First it uses a trace() action to output a message to the Output panel
indicating that the button has been pressed; then the script calls a function we have
yet to define, named myTraceTest(). Let's define that function next.
9. Add the following function definition at the end of the current script:
10.
11. function myTraceTest(){
12.
13. trace ("myTraceTest function is executed");
14.
15. myClop_mc.onMouseDown = function(){
16.
17. trace("I now have POWER!");
18.
19. }
script on the button was executed, and the function was executed, but something
went wrong with the part of the script that assigns the onMouseDown event
handler to myClip_mc. We know where to look for a bug!
Sure, we gave it away in Step 9, when we told you that the event handler method
assignment had a spelling error. But even without this help you could have quickly
deduced that something was wrong with that section of code by simply realizing
that everything leading up to the event handler assignment worked as designed, as
indicated by the trace() messages we used. trace() messages are very useful in
tracking down bugs.
11. Close the test movie to return to the authoring environment. Select Frame 1, open
the Actions panel, and fix the spelling error in the function definition by changing
myClop_mc to myClip_mc. Choose Control > Test Movie.
In the testing environment, click the myButton_btn instance. The Output panel
will open and display this message:
Activation button is pressed
myTraceTest function is executed This indicates that the button worked, and that the function call the button made to
myTraceTest() was executed.
Now click anywhere on the stage. The message "I now have POWER!" will
appear in the Output window, indicating that the entire project is now working as
it should.
12. Close the test movie, return to the authoring environment, and save this file as
Testing1.fla.
We will build on this file in the next section.
This has been a simple demonstration of the trace() action. You can see how
trace("age is greater than 100");
}else{
trace("age is exactly 100");
} and so on.
These little hints throughout your code can provide insight into how things are
working behind the scenes.
TIP
trace() actions can be turned on or off individually by commenting the action, as in the
following example:
//trace("Let me speak my peace!") This strategy can be helpful if you're using several trace() actions in your code, but you
only want to focus on the output of an individual trace() action.
Using the Debugger
Normally, you can't see either the data in variables or the values associated with movie
properties while your movie is playing; however, this data plays a crucial role in
determining how your interactive movie looks and works. Visual bugs are easy to spot,
but bugs in ActionScripts can be trickier to track down and correct. Not only is the data
usually invisible; it can also be changing constantly. This is where Flash's Debugger
comes in: with the Debugger, you can view the real-time values of variables and
properties while a movie is playing, as well as change values at will to see how such
variables included in the movie that's selected in the Display list. Double-clicking
a value allows you to change it and view the immediate results of that change in
the movie. Because variables provide the foundation of most ActionScripts, using
the Debugger to change individual values can help you track down the problems
that might occur when a movie is fed a certain piece of data. Although you can see
the values of Object and Array variables on this tab, you can't change them, nor
can you use expressions when entering new variable values from the Debugger.
New values can be strings (remember to use quotes), numbers, or a Boolean (true
or false).
•
Locals tab. This tab contains a list of local (temporary) variables that are used
within a function when that function block is being stepped through using
breakpoints. Breakpoints are explained in greater detail in the exercise for this
section.
•
Watch list tab. The Watch list tab contains a list of variables that you've
designated to be "watched," meaning that their values are constantly monitored on
this tab. You can add variables from multiple movies to this list so that you can
manage all of them from a single tab.
•
Call Stack. When a script calls a function—and even when a function calls another
function that may call yet another function (enough already!)—this pane displays
a hierarchical list of those calls. This list helps you determine the path the project
takes to perform a certain task, enabling you to possibly optimize your code a bit
so that it requires fewer steps to perform a task, with the end goal of helping it run
faster.
•
Breakpoint controls. These buttons control the execution of scripts when using
breakpoints (markers in a script that indicate a pause in the script's execution).
These buttons are discussed in more detail in the exercise for this section.