先来看简单的单个按键捕获:
package { import flash.display.Sprite; import fl.controls.Label; import flash.events.KeyboardEvent; import flash.ui.Keyboard; public class KeyDown extends Sprite { private var lbl:Label; private var ball:Sprite; public function KeyDown():void { init(); } private function init():void { stage.focus=this;//N多资料上说要先设置焦点,但是在实际测试中,发现不加这一行,好象也能处理键盘事件? lbl = new Label(); lbl.text="请按键,这里将显示您的按键值,按方向键可以移动小球"; lbl.autoSize="center"; addChild(lbl); lbl.width=stage.stageWidth; lbl.height=20; lbl.move(0,10); ball = new Sprite(); addChild(ball); //画小球 ball.graphics.beginFill(0xff0000); ball.graphics.drawCircle(0,0,30); ball.graphics.endFill(); //定位到舞台中心 ball.x=stage.stageWidth/2; ball.y=stage.stageHeight/2; stage.addEventListener(KeyboardEvent.KEY_DOWN,KeyDownHandler); } public function KeyDownHandler(e:KeyboardEvent):void { lbl.text="您的按键值是:"+e.keyCode.toString()+";按键是:"+String.fromCharCode(e.keyCode); switch (e.keyCode) { case Keyboard.UP : ball.y-=10; break; case Keyboard.DOWN : ball.y+=10; break; case Keyboard.LEFT : ball.x-=10; break; case Keyboard.RIGHT : ball.x+=10; default : break; } if (e.ctrlKey) { lbl.text="您按下了Ctrl键!"; } if (e.shiftKey) { lbl.text="您按下了Shift键!"; } //注:实际上,在很多浏览器,包括flash播放器里,Alt都是默认用做菜单激活键的,所以Alt键会被他们拦截,从而导致Flash无法捕获 if (e.altKey) { lbl.text="您按下了Alt键!"; } } } }
再来看下类似: A + B + C 的这种组合键捕获:
先分析一下过程,比如用户按下Ctrl + A 时,实际上是先按下Ctrl键,同时触发KeyDown事件,然后在Ctrl不放的同时,再按下A键,再次触发KeyDown事件,然后松开(触发KeyUp事件),这是一个顺序的过程。
思路:在用户按下键且尚未松开任何键时,可以考虑用一个数据,把本次按下的所有的键值都存储起来,然后等待用户松开,一旦松开,就可以认为本次组合键 输入完成,这时再清空数据,准备下次使用,这样数组中保存的就是用户按下的组合键。
按这个思路把上面的代码改进一下:
package { import flash.display.Sprite; import fl.controls.Label; import flash.events.KeyboardEvent; import flash.ui.Keyboard; import flash.ui.*; public class KeyDown extends Sprite { private var lbl:Label; private var ball:Sprite; private var keyValueArr:Array;//捕获组合键时,用来存放本次(在未触KeyUp事件前)所有按下的所有键值 private var keyNameArr:Array;//按键值对应的字符 public function KeyDown():void { init(); } private function init():void { stage.focus=this;//N多资料上说要先设置焦点,但是在实际测试中,发现不加这一行,好象也能处理键盘事件? lbl = new Label(); lbl.text="请按键(支持Ctrl,Shift组合键),这里将显示您的按键值,按方向键可以移动小球"; lbl.autoSize="center"; addChild(lbl); lbl.width=stage.stageWidth; lbl.height=20; lbl.move(0,10); ball = new Sprite(); addChild(ball); //画小球 ball.graphics.beginFill(0xff0000); ball.graphics.drawCircle(0,0,30); ball.graphics.endFill(); //定位到舞台中心 ball.x=stage.stageWidth/2; ball.y=stage.stageHeight/2; stage.addEventListener(KeyboardEvent.KEY_DOWN,KeyDownHandler); stage.addEventListener(KeyboardEvent.KEY_UP,KeyUpHandler); keyValueArr = new Array(); keyNameArr = new Array(); } public function KeyDownHandler(e:KeyboardEvent):void { //注:既然Alt总是被浏览器或播放器菜单栏 拦截,干脆就不检测了 if (!(e.keyCode==Keyboard.SHIFT||e.keyCode==Keyboard.CONTROL)) { keyValueArr.push(e.keyCode); keyNameArr.push(String.fromCharCode(e.keyCode)); } lbl.text="您的按键值是:" + e.keyCode.toString()+";按键是:" + String.fromCharCode(e.keyCode); switch (e.keyCode) { case Keyboard.UP : ball.y-=10; break; case Keyboard.DOWN : ball.y+=10; break; case Keyboard.LEFT : ball.x-=10; break; case Keyboard.RIGHT : ball.x+=10; default : break; } if (e.ctrlKey) { if (keyValueArr.length>0) { lbl.text="您按下了Ctrl + "+keyNameArr.join(','); } } if (e.shiftKey) { if (keyValueArr.length>0) { lbl.text="您按下了Shift + "+keyNameArr.join(','); } } } public function KeyUpHandler(e:KeyboardEvent):void { keyValueArr.length=0; keyNameArr.length=0; } } }
最后再来看看所谓的"八方向"移动:很多小游戏都可以用方向键控制人物的移动方向,上面的示例中,只能沿水平垂直四个方向移动,如果要做到8方向移动,就要用到组合键,仍然在上面的代码基本上做些修改:
package { import flash.display.Sprite; import fl.controls.Label; import flash.events.KeyboardEvent; import flash.ui.Keyboard; import flash.ui.*; public class KeyDown extends Sprite { private var lbl:Label; private var ball:Sprite; private var keyValueArr:Array;//捕获组合键时,用来存放本次(在未触KeyUp事件前)所有按下的所有键值 private var keyNameArr:Array;//按键值对应的字符 public function KeyDown():void { init(); } private function init():void { stage.focus=this;//N多资料上说要先设置焦点,但是在实际测试中,发现不加这一行,好象也能处理键盘事件? lbl = new Label(); lbl.text="请按键(支持Ctrl,Shift组合键),这里将显示您的按键值,按方向键可以移动小球(支持8方向)"; lbl.autoSize="center"; addChild(lbl); lbl.width=stage.stageWidth; lbl.height=20; lbl.move(0,10); ball = new Sprite(); addChild(ball); //画小球 ball.graphics.beginFill(0xff0000); ball.graphics.drawCircle(0,0,30); ball.graphics.endFill(); //定位到舞台中心 ball.x=stage.stageWidth/2; ball.y=stage.stageHeight/2; stage.addEventListener(KeyboardEvent.KEY_DOWN,KeyDownHandler); stage.addEventListener(KeyboardEvent.KEY_UP,KeyUpHandler); keyValueArr = new Array(); keyNameArr = new Array(); } public function KeyDownHandler(e:KeyboardEvent):void { //注:既然Alt总是被浏览器或播放器菜单栏 拦截,干脆就不检测了 if (!(e.keyCode==Keyboard.SHIFT||e.keyCode==Keyboard.CONTROL)) { if (keyValueArr.indexOf(e.keyCode)==-1) { keyValueArr.push(e.keyCode); keyNameArr.push(String.fromCharCode(e.keyCode)); } } lbl.text="您的按键值是:"+ keyValueArr.join(',') +";按键是:" + keyNameArr.join(','); //单方向移动 if (keyValueArr.length==1) { switch (e.keyCode) { case Keyboard.UP : ball.y-=10; break; case Keyboard.DOWN : ball.y+=10; break; case Keyboard.LEFT : ball.x-=10; break; case Keyboard.RIGHT : ball.x+=10; default : break; } } else if (keyValueArr.length>1) { //trace(keyValueArr.join(',')); if (keyValueArr.indexOf(Keyboard.UP)!=-1 && keyValueArr.indexOf(Keyboard.LEFT)!=-1) { //左上 ball.x -= 10; ball.y -= 10; } else if (keyValueArr.indexOf(Keyboard.UP)!=-1 && keyValueArr.indexOf(Keyboard.RIGHT)!=-1) { //右上 ball.x += 10; ball.y -= 10; } else if (keyValueArr.indexOf(Keyboard.DOWN)!=-1 && keyValueArr.indexOf(Keyboard.RIGHT)!=-1) { //右下 ball.x += 10; ball.y += 10; } else if (keyValueArr.indexOf(Keyboard.DOWN)!=-1 && keyValueArr.indexOf(Keyboard.LEFT)!=-1) { //左下 ball.x -= 10; ball.y += 10; } } if (e.ctrlKey) { if (keyValueArr.length>0) { lbl.text="您按下了Ctrl + "+keyNameArr.join(','); } } if (e.shiftKey) { if (keyValueArr.length>0) { lbl.text="您按下了Shift + "+keyNameArr.join(','); } } } public function KeyUpHandler(e:KeyboardEvent):void { keyValueArr.length=0; keyNameArr.length=0; } } }