0

I read a lot of topics about dispatching event but I can't make my code work. This topic and this topic are closed to what I would like to do, but it's not working in my case.

Here is the situation :

  • My scene is a battle field and has two ships
  • Each ship knows when it is touched by a fire, so it has to inform the scene that contains the graphic interface
  • So the ship dispatch a custom event with itself as parameter, so the scene knows when a ship is touched and which ship

I have 3 classes :

  1. The custom event class is an event that has a property "Ship"
  2. The EventDispatcher class
  3. The symbole class that corresponds to my scene and listen to the event

1) CustomEvent class

public class FightEvent extends Event
    {
        public static const SHIP_TOUCHED:String = "SHIP_TOUCHED"; //type
        public var object:Ship = null; //object to pass

        public function FightEvent(type:String, pObject:Ship, bubbles:Boolean=true, cancelable:Boolean=false)
        {
            super(type, bubbles, cancelable);
            object = pObject;
        }

        public override function clone():Event
        {
            return new FightEvent(type, object, bubbles, cancelable);
        }
    }

2) EventDispatcher

public class Ship extends EventDispatcher
{
    private function updateDamages():void
    {
        //compute damages
        dispatchEvent( new FightEvent( FightEvent.SHIP_TOUCHED, this ) );
    }
}

3) Scene

public class Fight extends customMovieClip
{
    private var playerShip:Ship; //I have two ships, player and enemy
    private var enemyShip:Ship;

    public function init():void
    {
         stage.addEventListener(FightEvent.SHIP_TOUCHED, onShipTouched);
         //I made a test : the event listener is correctly added
    }

    private function onShipTouched(e:FightEvent):void
    {
        //update the graphic interface to show damages
    }
}

My event listener is added, the code passes on the dispatch line, but onShipTouched is not called.

Please help, what did I miss ?

What is the element I didn't understand ?

Is it a good way to use events like this ? or should I set a reference to the scene inside the Ship class ?

10
  • 1
    You need to add the eventlistener to the object that is dispatching the event, that is, one of your ships. the stage is not dispatching the event, the Class Ship does that. Commented Nov 13, 2014 at 12:20
  • Most likely you are changing frames between addEventListener and dispatchEvent, or probably even scenes, thus the stage is different at the time of attaching the listener and the time when the event is fired, so the event reaches wrong stage and is dropped with no reaction. Commented Nov 13, 2014 at 12:37
  • ship is not a displayobject so stage can't magically catch those events. btw this: "public var object:Ship = null;" and this "public var object:Ship;" give ship the same value: null. Since ship is not a displayobject only ship object can listen to their own dispatch. Commented Nov 13, 2014 at 13:26
  • @DodgerThud "You need to add the eventlistener to the object that is dispatching the event". I don't understand this, why would I need an eventlistener on the dispatcher that already know what is happening to itself ? Commented Nov 13, 2014 at 13:53
  • @Vesper I am not sure if I understand, do you mean that the onEnterFrame method could be a source of problem here ? I have a KeyboardEvent listener added to the stage (in my class Fight), and it works perfectly. I don't really get the difference between the way the keyboard event is handled and the way my fight event is handled. Commented Nov 13, 2014 at 13:58

2 Answers 2

0

Your Ship class is not a MovieClip, Sprite or their subclass in order for your event to bubble up the display list, just because they don't participate in a display list. So, you change your Ship to Sprite subclass (this one already inherits EventDispatcher), add graphics and addChild() both ships to the stage, this way your stage will receive events properly.

Sign up to request clarification or add additional context in comments.

2 Comments

An object doesn't have to be a displayobject in order to work correctly with the event system. Your answer kind of imply that all objects should be displayobject and added to the display list just so that the stage can catch those events. That would be a terrible way to code a project.
@BotMaster See, I agree that this approach isn't correct in this case, but I mean that in order for the event to bubble up to stage, the object that dispatches this event should be on the display list. Apparently this is not the case in OP's code.
0

My logic was wrong :

I was doing this : the eventdispatcher is dispatching the event, and the stage is listening to the event. That is incorrect.

The right solution is : the eventdispatcher is dispatching the event, and is also listening to its own dispatched event. The eventlistener is added to the eventdispatcher in the scene, that contains the function to call.

As Vesper said, the parameter in FightEvent is useless, as the eventdispatcher is actually the event target.

DodgerThud, BotMaster, you gave me this answer, thank you for your help (Looks like I can't set a comment as "answer accepted").

Here the right code for the Fight class :

public class Fight extends customMovieClip
{
    private var playerShip:Ship; //I have two ships, player and enemy
    private var enemyShip:Ship;

    public function init():void
    {
        enemyShip.addEventListener(FightEvent.SHIP_TOUCHED, onShipTouched);
        playerShip.addEventListener(FightEvent.SHIP_TOUCHED, onShipTouched);
    }

    private function onShipTouched(e:FightEvent):void
    {
        //e.target == the ship that dispatched the event
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.