开发者

Custom event dispatchment location

I've been looking into custom event (listeners) for quite some time, but never succeeded in making one. There are so many different methods, extending the Event class, but also Extending the EventDispatcher class, very confusing! I want to settle with this once and for all and learn the appropriate technique.

package{

 import flash.events.Event;
 public class CustomEvent extends Event{

 public static const TEST:String = 'test'; //what exac is the purpose of the value in the string?
 public var data:Object;

 public function CustomEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, data:Object = null):void
 {
 this.data = data;
 super();
 }
 }
}

As far as I know a custom class where you set the requirements for the event to be dispatched has to be made:

package 
{
    import flash.display.MovieClip;

    public class TestClass extends MovieClip 
    {

        public function TestClass():void {


            if (ConditionForHoldToComplete == true) {

                dispatchEvent(new Event(CustomEvent.TEST));
            }

        }

    }

}

I'm not sure if this is correct, but it should be something along the lines of this.

Now What I want is something like a mouseevent, which can be applied to a target and does not require a specific class.

It would have to work something like this:

package com.op_pad._events{
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.EventDispatcher;
import flash.events.Event;

public class HoldEvent extends Event
     {
          public static const HOLD_COMPLETE:String = "hold completed";
          var timer:Timer;

          public function SpriteEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
          {
                super( type, bubbles, cancelable );

                timer = new Timer(1000, 1);
                //somehow find the target where is event is placed upon -> target.addEventlistener
                target.addEventListener(MouseEvent.MOUSE_DOWN, startTimer);
                target.addEventListener(MouseEvent.MOUSE_UP, stopTimer);
          }

          public override function clone():Event
          {
                return new SpriteEvent(type, bubbles, cancelable);
          }
          public override function toString():String
          {
                return formatToString("MovieEvent", "type", "bubbles", "cancelable", "eventPhase");
          }



            //////////////////////////////////
            /////   c o n d i t i o n s  /////
            //////////////////////////////////

            private function startTimer(e:MouseEvent):void 
          {
              timer.start();
              timer.addEventListener(TimerEvent.TIMER_COMPLETE, complete);
          }

          private function stopTimer(e:MouseEvent):void 
          {
              timer.stop()
          }

          public function complete(e:TimerEvent):void {

              dispatchEvent(new HoldEvent(HoldEvent.HOLD_COMPLETE));
          }
     }

}

This obviously won't work, but should give you an idea of what I want to achieve. This should be possible because mouseevent 开发者_如何学Pythoncan be applied to about everything.The main problem is that I don't know where I should set the requirements for the event to be executed to be able to apply it to movieclips and sprites.


You are almost there actually, just for the last part, wouldn't this be more of an OOP related issue than stricly a confusion about the way of using custom events ?

Usually, Events in AS3 are value objects whose sole responsibility is to transport information from the event dispatcher to the listener(s). The dispatcher dispatches the event each time a defined momentum is reached, and the listener(s) may or may not react when this happens.

In the example above, I guess it is up to the listener to start a timer and so on when a mouse-down has been detected. In a more sophisticated context the Event could independently trigger more than one listeners actioning separate tasks which neither the Dispatcher nor the Event itself should have to bother about, that is probably why it's worth avoiding amending the dispatcher or the event itself with any soever logic.

For your very example, you could maybe create a handler checking if the mouse has been held down?

The following is just pseudocode, and there are obviously tons of other ways to get to the same result:

public class MouseDownHandler
{
    // ...

    public function( target:Sprite ) {
         this.target = target;
         start();
    }

    public function start():void{
        // Listen for the target's mouseUp event
    }

    public function dispose():void{
        // Stop listeners and eventually the timer
    }

    private function onMouseDown(e:MouseEvent):void{
       // Start timer + listening for the stage's mouse up event (target.stage)
    }

    private function onMouseUp(e:Event):void{
        // Cancel timer
    }

    private function onTimerComplete(e:TimerEvent):void {
        dispatchEvent(new HoldEvent(HoldEvent.HOLD_COMPLETE));
    }
}

Which could be reused for example this way:

var mc:MovieClip = new MovieClip(); ...
var mouseHandler:MouseDownHandler = new MouseDownHandler(mc);
mouseHandler.addEventListener(HoldEvent.HOLD_COMPLETE, onMcHoldComplete);

... or this way :

public class TestMovieClip extends MovieClip
{
    private var mouseHandler:MouseDownHandler;

    public function TestMovieClip() {
        mouseHandler = new MouseDownHandler(this);
        mouseHandler.addEventListener(HoldEvent.HOLD_COMPLETE, onMouseHoldComplete);
    }

    private function onMouseHoldComplete(e:HoldEvent):void {
        // Do something
    }
}


I just use robber penners signals. Very easy to use.

http://github.com/robertpenner/as3-signals

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜