自定义事件派遣地点

时间:2010-12-30 19:25:45

标签: actionscript-3 event-listener custom-event event-dispatching

我一直在研究自定义事件(听众)很长一段时间,但从未成功制作过。有很多不同的方法,扩展Event类,还扩展EventDispatcher类,非常混乱! 我想一劳永逸地解决这个问题并学习适当的技巧。

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();
 }
 }
}

据我所知,您需要设置一个自定义类来设置要调度的事件的要求:

package 
{
    import flash.display.MovieClip;

    public class TestClass extends MovieClip 
    {

        public function TestClass():void {


            if (ConditionForHoldToComplete == true) {

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

        }

    }

}

我不确定这是否正确,但它应该是这样的。

现在我想要的是像mouseevent,它可以应用于目标,不需要特定的类。

它必须像这样工作:

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));
          }
     }

}

这显然不起作用,但应该让你知道我想要实现的目标。这应该是可能的,因为mouseevent可以应用于任何事情。主要的问题是我不知道应该在哪里设置要执行的事件的要求,以便能够将它应用于movieclips和sprite。

2 个答案:

答案 0 :(得分:1)

你几乎就在那里,只是在最后一部分,这不是一个与OOP相关的问题,而不是对使用自定义事件的方式的严重混淆吗?

通常,AS3中的事件是值对象,其唯一责任是将信息从事件调度程序传输到侦听器。每次达到定义的动量时,调度员都会调度该事件,并且当发生这种情况时,听众可能会或可能不会做出反应。

在上面的示例中,我想由侦听器启动计时器等等,当检测到鼠标按下时。在更复杂的上下文中,Event可以独立地触发多个侦听器执行单独的任务,Dispatcher和Event本身都不应该为此烦恼,这可能是为什么值得避免以任何逻辑来修改调度程序或事件本身。

对于您的示例,您可以创建一个处理程序来检查鼠标是否被按下?

以下只是伪代码,显然有很多其他方法可以得到相同的结果:

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));
    }
}

可以通过这种方式重复使用:

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

......或者这样:

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
    }
}

答案 1 :(得分:0)

我只是使用强盗笔友信号。非常容易使用。

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