1

我研究自定义事件(监听器)已经有一段时间了,但从未成功过。有这么多不同的方法,扩展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 可以应用于几乎所有内容。主要问题是我不知道我应该在哪里设置要执行的事件的要求,以便能够将其应用于电影剪辑和精灵。

4

2 回答 2

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
    }
}
于 2010-12-30T22:20:14.713 回答
0

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

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

于 2010-12-30T21:49:06.530 回答