我looking for这个答案没有运气。 One place I looked实际上有一个非常令人沮丧的答案:“你不能强迫鼠标或键盘事件 - 他们必须来自鼠标或键盘。”
咦?
我试过'蛮力'并想出了这个解决方案。也许我会错误或愚蠢地去做;有更好的方法吗?
我有一个键盘事件,它启动了一个类,并希望在舞台上放一个sprite来启动同样的动作 - 点击sprite会启动键盘事件(Escape键)。
在eventListener函数中,我traced
事件 e 本身:
private function keys(e:KeyboardEvent):void {
trace("EscapeKey: ",e);
if (e.keyCode == 27) {
...
}
}
输出
EscapeKey: [KeyboardEvent type="keyDown" bubbles=true cancelable=false eventPhase=2 charCode=27 keyCode=27 keyLocation=0 ctrlKey=false altKey=false shiftKey=false]
然后我使用mouseClick侦听器创建并使用从上面的跟踪中获取的值调度新的keyboardEvent:
private function pauseClick(e:MouseEvent):void {
var a:KeyboardEvent = new KeyboardEvent("keyDown", true, false, 27, 27, 0, false, false, false);
stage.dispatchEvent(a);
}
的Presto!
希望这篇文章对于那些寻找这些类型的鼠标/键盘事件冗余的人来说会派上用场。
编辑 ---评论中要求的完整类示例:
package{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
public class KeyboardMouse extends Sprite {
private var pauseInfo:PauseInfo;
private var escapeKey:EscapeKey;
public function KeyboardMouse() {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keys);
escapeKey = new EscapeKey();
stage.addChild(escapeKey);
pauseInfo = new PauseInfo();
pauseInfo.x = stage.stageWidth;
pauseInfo.y = stage.stageHeight;
pauseInfo.addEventListener(MouseEvent.CLICK,pauseClick);
addChild(pauseInfo);
}
private function keys(e:KeyboardEvent):void {
trace("KeyboardEvent ",e);
if (e.keyCode == 27) { // esc key
if (stage.contains(escapeKey)){
trace("remove escape");
escapeKey.visible = false;
}
else {
trace("show escape");
escapeKey.visible = true;
}
}
}
private function pauseClick(e:MouseEvent):void {
// The trace in 'keys' gives this:
//[KeyboardEvent type="keyDown" bubbles=true cancelable=false eventPhase=2 charCode=27 keyCode=27 keyLocation=0 ctrlKey=false altKey=false shiftKey=false]
var a:KeyboardEvent = new KeyboardEvent("keyDown", true, false, 27, 27, 0, false, false, false);
stage.dispatchEvent(a);
}
}
}
答案 0 :(得分:0)
好的,现在我明白了。我只是不明白它的目的。我认为,代码中还有一个恼人的错误。
首先:你已经表明你可以基本上“转换”一种类型的事件(例如MouseEvent)作为另一种事件(KeyboardEvent)。但是你仍然为每种事件类型注册了一个监听器函数(在某些时候,你必须为了内存管理目的而删除)和一个新调度的事件,所以你并没有完全最小化代码。究竟什么是这个技巧的价值?为什么不只注册一个具有多种事件类型的侦听器函数?在该函数中,您可以区分事件类型并相应地执行操作,例如使用如下行:
if(e.type == 'keyDown' || e.type == 'click')
第二:你说: if(stage.contains(escapeKey))然后你试图让escapeKey的'visible'属性依赖于它。但是通过使 escapeKey.visible = false ,您不会改变舞台仍然包含escapeKey的事实。所以escapeKey永远不会再次出现,因为其他'条件不存在。我相信你想说“ removeChild(escapeKey)”然后“ addChild(escapeKey)”而不是设置“ escapeKey.visible = false “然后” escapeKey.visible = true “。那么你的小程序会做我认为你想要的。
答案 1 :(得分:0)
为@Neal Davis提供+1和大道具的评论!
正如他所建议的那样,使用参数(e:Event)为两个事件设置一个监听器是一种更简洁,更简单的方法来实现相同的结果:
pauseInfo.addEventListener(MouseEvent.CLICK,keys);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keys);
private function keys(e:Event):void {
trace("EscapeKey: ",e);
if (e.keyCode == 27) {
...
}
}
但是,在某些时候,两个侦听器仍然必须被删除,即使只有一个侦听器函数正在处理这两个,当然!