Getting used to new features (and discovering them) in AS3 will take some time. My friends over at 8BitRocket realize this just as much as I do.
Something I heard about over and over again was event bubbling. I knew what it did; I knew it would be a good thing to use in my programs… But… I never used it. So I whipped up a quick test tonight after thinking about a common “code smell” problem I have been finding myself doing. In the game in question I constantly pass in references of parent classes into children (don’t laugh). In a true event driven program event bubbling takes care of this. Why pass in a reference when a child should dispatch an event when there is a change and naturally the parent should hear it. Makes sense.
Here would be a typical parent-child relationship in a game of mine: Main –> World –> Player –> Ship.
When a ship would get hit, die or shoot, the parents should know about it via event bubbling not references. The parents would then listen to events that they would care about and just not to ones that are irrelevant.
The code demos a ship making a circle clickable and the world hearing it. It also dispatches an event at 100ms and the world hears that as well. Remember in your event dispatch to have event bubbling set to true. Example: dispatchEvent(new Event(”shipEvent”, true));
Here is the code for the four classes: (sorry for the shitty code formatting, copy and paste into an IDE)
Main:
package
{
public class Main extends Sprite
{
private var _world:World;
public function Main()
{
_world = new World();
addChild(_world);
}
}
}
World:
package com.pacyga.world {
import flash.display.Sprite;
import com.pacyga.player.Player;
import flash.events.MouseEvent;
import flash.events.Event;
public class World extends Sprite {
private var _player:Player;
public function World() {
_player = new Player();
addChild(_player);
this.addEventListener(MouseEvent.CLICK, clickHandler);
this.addEventListener("shipEvent", shipEventHandler);
}
private function clickHandler(evt:MouseEvent):void {
trace("[World].clickHandler()");
}
private function shipEventHandler(evt:Event):void {
trace("[World].shipEventHandler()");
}
}
}
Player:
package com.pacyga.player {
import flash.display.Sprite;
import com.pacyga.gameobjects.ship.PlayerShip;
public class Player extends Sprite {
private var _playerShip:PlayerShip;
public function Player() {
_playerShip = new PlayerShip();
addChild(_playerShip);
}
}
}
Ship:
package com.pacyga.gameobjects.ship {
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.Event;
public class PlayerShip extends Sprite {
private var _shape:Shape;
public function PlayerShip() {
_shape = new Shape();
_shape.graphics.beginFill(0xFF8800);
_shape.graphics.drawCircle(100, 100, 50);
this.addChild(_shape);
var timer:Timer = new Timer(100, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, timerComplete);
timer.start();
this.addEventListener(MouseEvent.CLICK, clickHandler);
}
private function clickHandler(evt:MouseEvent):void {
trace("[PlayerShip].clickHandler()");
}
private function timerComplete(evt:TimerEvent):void {
trace("[PlayerShip].timerComplete()");
this.dispatchEvent(new Event("shipEvent", true));
}
}
}