A book companion site by Chris Griffith
RSS icon Email icon Home icon
  • Chapter 4

    Posted on July 26th, 2009 Chris 6 comments

    In Chapter 4, I give a crash course in ActionScript 3 programming, covering topics such as Classes, Events, and Errors.  While this is not a comprehensive course in AS3, but should be enough for developers coming from other programming backgrounds or earlier versions of Flash.  For AS1/2 devs, I also recommend this tutorial to aide in the transition.  There are also a number of great articles by Grant Skinner on topics like garbage collection.

    Chapter 4 Files

     

    6 responses to “Chapter 4”

    1. Custom Events

      There was an article on how to pass data in a Custom Event at:

      http://flexcomps.wordpress.com/2008/04/29/dispatching-custom-events-in-as3-with-data-or-object/

      The data that I needed to transfer was added to an array and the array was the data item used. I’m trying to understand your implementation. An override clone function was not used in the article.

      Could you please post an example showing the Event Listener and how the data is added at the dispatchEvent and how the data is extracted at the listener.

    2. Hi Barry,
      That article covers the process fairly well of passing a piece of data (or pointer to a piece of data, like an object or array) along with an event, but you are correct that they do not implement a clone function override. The reason for overriding this function is so that if the event was re-dispatched (passed through another dispatchEvent method call), the new event object will retain its data. This is from the AS3 language reference on the clone method:

      Returns a new Event object that is a copy of the original instance of the Event object. You do not normally call clone(); the EventDispatcher class calls it automatically when you redispatch an event—that is, when you call dispatchEvent(event) from a handler that is handling event.

      The new Event object includes all the properties of the original.

      When creating your own custom Event class, you must override the inherited Event.clone() method in order for it to duplicate the properties of your custom class. If you do not set all the properties that you add in your event subclass, those properties will not have the correct values when listeners handle the redispatched event.

      The clone method will always have a generic return type of Event, from which all custom events extend, but the actual event object will be of whatever custom type you’ve created if you override it. Does this make sense?

      Say you had a game engine that was dispatching events about the current game state; player health, ammo levels, etc. Rather than having all the individual elements of the HUD have to be attached via listeners to the engine itself (which might be infeasible depending on your architecture and level of abstraction), you might have a controller/wrapper class that receives all of those events and re-dispatches them to the appropriate destinations. In this instance you would absolutely need the clone method overridden to make sure all of the custom data went along for the ride. In general, I don’t often add data to custom event types – I prefer to make whatever data is needed publicly available (like through an accessor “get” method) on the object dispatching the event. This is because I might have multiple types of data I want to be able to access (Booleans, ints, strings, arrays) and I don’t want to create custom events for each data type (or create a ton of properties on the event object itself for all the possible cases). Instead, I try to use the basic Event object, extended to include type enumerations, like so:

      package
      {
      import flash.events.Event;

      public class GameEvent extends Event
      {
      public static const GAME_OVER:String = "gameOver";
      public static const GAME_START:String = "gameStart";
      public function GameEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false)
      {
      super(type, bubbles, cancelable);
      }
      }
      }

      In this case, a GameEvent is not really different behaviorally from a normal Event, other than to act as an enumeration class for the specific event types and to allow other classes to differentiate between it and a generic Event. Some might argue that a GAME_OVER event object could include a score property:
      private function onGameOver(e:GameEvent):void
      {
      scoreText.text = e.score.toString();
      }

      I prefer to call back to the event’s target instead, as this saves memory from being allocated for a piece of data that is simply traveling the event hierarchy. In this case, let’s assume the target object is of type GameEngine, which has a public property “score”.
      private function onGameOver(e:GameEvent):void
      {
      var engine:GameEngine = GameEngine(e.target);
      scoreText.text = engine.score.toString();
      }

      This really comes down to a combination of preference and practicality for the application. Sometimes it may make sense to pass data along in an event object, such as when retrieving data from a remote service or a local file. Other times your game might be running in a constrained environment, like on a mobile device, where memory and CPU resources are precious; creating additional references or copies of any superfluous data can bog you down severely.

    3. In chapter 4, on page 39 there’s a code snippet under the “Getter/Setter Methods” section. Here’s the code in the book:

      [code]
      package {
      public class MyClass {
      protected var _maxNameLength:int = 8;
      protected var _name:String;
      protected var _lives:int = 3;
      public function get name():String {
      return _name;
      }
      public function set name(value:String):void {
      name = value.substr(0, maxNameLength);
      }
      public function get live():int {
      return _lives;
      }
      }
      }
      [/code]
      =-=-=-=-
      I think that the code is missing underscores on the variables on one line, and it should be this:
      [code]
      package {
      public class MyClass {
      protected var _maxNameLength:int = 8;
      protected var _name:String;
      protected var _lives:int = 3;
      public function get name():String {
      return _name;
      }
      public function set name(value:String):void {
      _name = value.substr(0, _maxNameLength); //underscores added to "name" and "maxNameLength"
      }
      public function get live():int {
      return _lives;
      }
      }
      }
      [/code]

      Thanks for writing an awesome book :)

    4. On page 54 I believe the third line of code should be:

      “public class GameEvent extends Event {”

      … “extends Event” is missing in the book.

      Thank you for a great book :-)

    5. Tyson is right! I also confused by this missing.If readers hadn’t idea about the AS,they would be tripped up.

    6. Hi, Chris. oh….Just a little booboo in the P69:
      “When the load has completed,
      the resources variable is assigned to the content of the Loader.”

      I think it would be better as that :

      “the content of the Loader is assigned to the resources variable .”

      Thanks for your book which has brought so many tips to me…

      yah…I forgot to introduce me, I am translating your book into Chinese. Your awesome book has been imported into China by Turing Press(Bei Jing). I think it is a great honour to be able to intranslate your book.

    Leave a reply