Actionscript 3.0 - Custom Events with Parameters

2019-09-01 09:18发布

问题:

Is there any simple -- or suggested -- way in order to send a parameter along with a custom event? Or even just a way to pass variables between two classes?

My program is a sort of simple Civ/Age of Empires kind of game, where you can place buildings on tiles. This would work as follows:

  • Player clicks on the icon on the HUD, which creates an dispatches an event which is received by the PLAYER class.
  • The PLAYER class changes a value depending on which building is held (clicked on).
  • Player clicks on the tile in the grid to place it, which dispatches an event which is received by the PLAYER class.
  • The PLAYER class creates a building object and adds it to an array within the PLAYER class.

An example of how I'd want the code to work:

icon.as

private function onMouseClick(e:MouseEvent = null):void {
        var iconClickedEvent:Event = new Event("BUILDING_HELD", buildingType);  // passes "buildingType" through the event somehow
        stage.dispatchEvent(iconClickedEvent);
}

tile.as

private function onMouseClick(e:MouseEvent = null):void {
        var buildingPlacedEvent:Event = new Event("BUILDING_PLACED", xRef, yRef);// passes "xRef" & "yRef", the tile's co-ordinate
        stage.dispatchEvent(buildingPlacedEvent);
}

player.as

private function init(e:Event):void {
        stage.addEventListener("BUILDING_HELD", buildingHeld(buildingType));
        stage.addEventListener("BUILDING_PLACED", placeBuilding(xRef, yRef));
}

private function buildingHeld(building:int):void {
        buildingType = building;
}

private function placeBuilding(xRef:int, yRef:int):void {
        switch(buildingType){
                case 1: // main base
                        MainBaseArray.push();
                        MainBaseArray[length-1] = new MainBase(xPos, yPos);     // create new object with the references passed
                        break;
        }
}

回答1:

The best way to manage this is to create custom event classes for each of your events (or event types). If you create a class that inherit Event, it will be usable in the same ways that a standard Event, but can contain custom values or methods.

Here's an example of such class :

public class BuildingEvent extends Event {

  // contains an event name. Usefull to ensure at compile-time that there is no mistape in the event name.
  public static const BUILDING_HELD:String = "BUILDING_HELD";

  private var _buildingType:int;

  // the constructor, note the new parameter "buildingType". "bubbles" and "cancelable" are standard parameters for Event, so I kept them. 
  public function BuildingEvent(type:String, buildingType:int, bubbles:Boolean = false, cancelable:Boolean = false) {
    super(type, bubbles, cancelable);
    _buildingType = buildingType;
  }

  // using a getter ensure that a listening method cannot edit the value of buildingType.
  public function get buildingType() {
    return _buildingType;
  }
}

We can then use this class like this :

// to dispatch the event
private function onMouseClick(e:MouseEvent = null):void {
  var iconClickedEvent:BuildingEvent = new BuildingEvent(BuildingEvent.BUILDING_HELD, buildingType);
  stage.dispatchEvent(iconClickedEvent);
}

// to listen to the event
private function init(e:Event):void {
  stage.addEventListener(BuildingEvent.BUILDING_HELD, buildingHeld);
}
private function buildingHeld(event:BuildingEvent):void {
  buildingType = event.buildingType;
}