我一直在研究自定义事件(听众)很长一段时间,但从未成功制作过。有很多不同的方法,扩展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。
答案 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)
我只是使用强盗笔友信号。非常容易使用。