as3如何发送特定的键盘事件

时间:2017-01-25 17:23:00

标签: actionscript-3 mouseevent keyboard-events

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

2 个答案:

答案 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) {
        ...    
        }
   }

但是,在某些时候,两个侦听器仍然必须被删除,即使只有一个侦听器函数正在处理这两个,当然!