Debugging (ActionScript tutorial)

From Whirled Club Wiki
Jump to: navigation, search

Template:Update

ActionScript Tutorial
Learn how to debug AS3 code using a simple avatar.
Difficulty Level
Beginner
Requirements
Icon-Programming.png ActionScript 3.0, Whirled SDK, debugging version of Flash Player or plug-in
Other Information

Status : Beta (See http://forums.whirled.com/thread.jspa?threadID=560&tstart=0)

This tutorial uses code from the simple avatar (ActionScript tutorial). If you have not worked through the examples in that tutorial, it is highly recommended that you do.

Things in this tutorial:

  • Debug ActionScript code using Flash Player pop up messages.
  • Add text to your avatar and put it to use to debug code.

Prerequisites

You will need the debugging version of the Flash Player or plug-in.

Regular

The regular Flash Player and plug-in can be obtained usually within a few clicks of arriving at the Adobe website.

The current direct link to the Flash Player may also be used.

Debugging

Debugging versions of the Flash Player or plug-in may be found currently at this Flash Player support webpage at Adobe.

Which version of the plugin do I have?

Firefox

Type in the URL about:plugins, you should see something like the image below. At present, there is no indication that the plug-in is debugging or not.

About plugins.png

Debugging using the Flash Player

There is probably more elegant methods to debugging your avatar code. This tutorial will try to make them useful as another tool to track down problems in your ActionScripts.

If someone knows how to debug this stuff at the command line, I'd love to hear about it. But, since Whirled scripts are compiled against the Whirled SDK, I don't see any other methods at present other than having to upload the compiled SWFs to Whirled and testing live.

Code

We will make the avatar display a box with Beep in it while it is also playing the MP3 clip.

Add these code snippets to the appropriate areas, compile and upload. This code has two errors. Can you find them?

If you want the error messages to match line numbers below, here is the full listing:

<actionscript> ... // Text support import flash.text.TextField; import flash.text.TextFieldAutoSize; ...

   public function Rooster ()
   {

...

       // We should erase the chatBox after a second
       _chatBoxTimer = new Timer(1000, 1);
       _chatBoxTimer.addEventListener(TimerEvent.TIMER, doneBeeping);
       // Prepare message
       _msg = new TextField();
       _msg.border = true;
       _msg.background = true;
       _msg.autoSize = TextFieldAutoSize.LEFT;

...

   /**
    * It's time to stop showing our chat box.
    */
   protected function doneBeeping (event :TimerEvent) :void
   {
       /* Clear the container */
       _container.removeChild(_msg);
   }

...

   protected function handleAction (event :ControlEvent) :void
   {
       // Reset the chatBox timer in case an event is
       // retriggered before the timer goes off.
       _chatBoxTimer.reset();
       switch (event.name) {
       case "Beep":
           _msg.text = "Beep"
           _container.addChild(_msg);
           _beep.play();
           break;
       case "Double Beep":
           _beep.play(0, 2);
           break;
       default:
           trace("Unknown action: " + event.name);
           break;
       }
       _chatBoxTimer.start();
   }

...

   /** Controls the timing of our chat box. */
   protected var _chatBoxTimer :Timer;
   /** Message variable and a container for the message */
   protected var _msg :TextField;
   protected var _container :Sprite;

</actionscript>

Error I

Rooster AS error container.png

Error #1009 in Rooster/handleAction() on line 176 of our Rooster.as (hey, that is our code!). As an additional bonus, it also tells you where the source code was when it was locally compiled. Full path is between the brackets [ ].

Here is that section of code: <actionscript> 166 protected function handleAction (event :ControlEvent) :void ... 173 switch (event.name) { 174 case "Beep": 175 _msg.text = "Beep" 176 _container.addChild(_msg); 177 _beep.play(); 178 break; </actionscript>

This error is caused as we tried to use a _container variable that is not defined (null object reference). You might think this where it is defined: <actionscript> 206 /** Message variable and a container for the message */ 207 protected var _msg :TextField; 208 protected var _container :Sprite; </actionscript> This is a declaration. This declares a variable name to a specific type. To finish the job you also need to aasign it a sprite object using new Sprite(). Until you assign it a value, you cannot reference it or it will generate a null object reference error as you have just seen. However, you can still test it for the value null.

You will also need to add the _container to the avatar using addChild. You need two additional lines of code: <actionscript>

       // Prepare message
       _container = new Sprite();
       addChild(_container);
       _msg = new TextField();

</actionscript>

Error II

Rooster AS error.png

This is more due to misplaced timers. If an event action is "Double Beep" or an undefined action, then the timer is started anyway. Because "Beep" is the only one adding a child to the _container object, when the timer expires an error will be thrown in the doneBeeping function to remove the child from the chatbox that does not exist.

Solution

The _chatBoxTimer.reset() is fine where it is. The state of the timer is unaffected. However, if the timer is running, this will reset it back to zero. This is good if the action is invoked again before the timer expires.

The solution here is to invoke _chatBoxTimer.start() only within the switch/case blocks. Or an even better solution is to define _msg.text in all the case and default sections and add _container.addChild(_msg) before or after the _chatBoxTimer.start().

The solution we will use the former suggestion in this example. Moving _chatBoxTimer.start() to the "Beep" block: <actionscript>

       case "Beep":
           _msg.text = "Beep"
           _container.addChild(_msg);
           _beep.play();
           _chatBoxTimer.start();
           break;

</actionscript>

A bit of optimization

We actually do not need an extra Sprite to do all this work. We can actually add the the Textfield to the existing sprite imageHolder. Lets do some optimization.

Things of note:

  • The variable imageHolder does not have a leading _ which is purely optional, but generally indicates a more global scope of the variable.
  • We will rename imageHolder to _avatarSprite and give it a prototype definition at the bottom of the script. This will make it more accessible to methods and functions.
  • Replace all _container references with _avatarSprite
    • Be sure to remove the second assignment of new Sprite()
  • Define a message for all actions for the select/case statement in handleAction() and we always add a message and start the timer.

The resultant code listing : Debugging Listing 2 (ActionScript tutorial)

Testing

If all goes well, the avatar should be bug free. You now have a "Test" action that should result in this:

Rooster test.png

Contacts

Please feel free to add and adjust content or contact Template:User in Whirled.