我举个例子:有这样一个游戏角色移动的游戏,需要角色具有八方向移动,如果用户先按下←键,游戏角色向左移动,这时候用户又按下↓键(←键不抬起),这时候游戏角色要向左下角移动,接下来,如果用户抬起↓键(←键不抬起),游戏角色转为继续左行,如果用户抬起←键(↓键不抬起),游戏角色转为继续下行。同样的,向上,向右按键也是类似的需求,而且这时候,如果用户按下了其它的按键,或按下多于三个光标键时,最后按下的键要忽略。
对于这种涉及复合键的处理,大家可以写一个试试是否容易,或者说是否足够完美。
这就是今天想说的内容,也是我在Flash 游戏开发中对按键控制的一点小经验,希望能对从事Flash游戏开发的同行们有所帮助。
一、先熟悉一下与制作按键相关的事件和语法
1).Key 类A).Key类的事件i) onKeyDown = function() {}
当按下某按键时获得通知。同时只能由一个按键触发,如果有多个按键按下,以先后次序触发。若要使用 onKeyDown,必须创建一个侦听器对象。然后可以为 onKeyDown 定义一个函数,并使用 addListener() 向 Key 对象注册该侦听器,如下面的示例所示:
var keyListener:Object = new Object();
keyListener.onKeyDown = function() {
trace("DOWN -> Code: "+Key.getCode()+"\tACSII: "+Key.getAscii()+"\tKey: "+chr(Key.getAscii()));
};
keyListener.onKeyUp = function() {
trace("UP -> Code: "+Key.getCode()+"\tACSII: "+Key.getAscii()+"\tKey: "+chr(Key.getAscii()));
};
Key.addListener(keyListener);
ii) .onKeyUp = function() {}
当释放某按键时获得通知。同时只能由一个按键触发,如果有多个按键按下后再抬起,以最后按下的键触发。若要使用 onKeyUp,必须创建一个侦听器对象。然后可以为 onKeyUp 定义一个函数,并使用 addListener() 向 Key 对象注册该侦听器,示例同上。
这二个按键事件,在四方向游戏中,配合Key.isDown,完全够用了。今天主要重点是在八方向键的处理上,下边继续说。
B).Key类的方法
i) Key.isDown 方法
如果按下 keycode 中指定的键,则返回 true;否则返回 false。
如:
car_mc.onEnterFrame = function() {
if (Key.isDown(Key.RIGHT)) {
this._x += 10;
} else if (Key.isDown(Key.LEFT)) {
this._x -= 10;
}
};
常见keycode(是Key类的静态属性):
修饰符 | 属性 | 说明 |
---|
static | BACKSPACE:Number | Backspace 键的键控代码值 (8)。 |
static | CAPSLOCK:Number | Caps Lock 键的键控代码值 (20)。 |
static | CONTROL:Number | Ctrl 键的键控代码值 (17)。 |
static | DELETEKEY:Number | Delete 键的键控代码值 (46)。 |
static | DOWN:Number | 下箭头键的键控代码值 (40)。 |
static | END:Number | End 键的键控代码值 (35)。 |
static | ENTER:Number | Enter 键的键控代码值 (13)。 |
static | ESCAPE:Number | Esc 键的键控代码值 (27)。 |
static | HOME:Number | Home 键的键控代码值 (36)。 |
static | INSERT:Number | Insert 键的键控代码值 (45)。 |
static | LEFT:Number | 左箭头键的键控代码值 (37)。 |
static | _listeners:Array [只读] | 一个引用列表,引用对象是向 Key 对象注册的所有侦听器对象。 |
static | PGDN:Number | Page Down 键的键控代码值 (34)。 |
static | PGUP:Number | Page Up 键的键控代码值 (33)。 |
static | RIGHT:Number | 右箭头键的键控代码值 (39)。 |
static | SHIFT:Number | Shift 键的键控代码值 (16)。 |
static | SPACE:Number | 空格键的键控代码值 (32)。 |
static | TAB:Number | Tab 键的键控代码值 (9)。 |
static | UP:Number | 上箭头键的键控代码值 (38)。 |
其它的字母键并没有定义成静态属性,需要使用数字的键控代码值来使用,有人写了一个所有按键的Key类,我复制在下边,可做参考:
自定义Key类 ii) Key.getCode 方法返回按下的
最后一个键的键控代码值,并且不会区分字母的大小字,即使用此方法时,任何一个按键,只有一个Code值。
2).MovieClip的事件i) MovieClip.onKeyDown 当影片剪辑
具有输入焦点并且用户按下某个键时调用。
ii) MovieClip.onKeyUp当释放按键时调用。仅当影片剪辑的输入焦点被启用和设置后,onKeyUp 事件处理函数才能起作用。即要求影片剪辑
具有输入焦点。
二、Flash中对按键捕获处理,拔开按键的迷雾
1).Flash中,如果你使用Key.onKeyDown 事件侦听器,则不管焦点在Flash内的那个对象上,按键均能被捕获,这里有一种情况,当先后按下多个键(二个以上的按键)时,onKeyDown事件是按先后次序触发的,而onKeyUp事件只能由最后按下的键触发。举例:
我先按下A键,再接着按下S键,同时A键不抬起,则这时候,onKeyDown先被A键触发一次,接着被S键触发一次,而这时候,不管你把那个键抬起,
onKeyUp事件始终是由最后按下的那个键触发的。这点一定要注意,这时候A键的onKeyUp事件已经被后按的键“冲”掉了,就算抬起A键,onKeyUp也不会被触发。可以使用本文开头那段代码测试就知道了。
2).使用
Key.isDown,可以知道有那些键被按下,不管按键的先后(其实是有先后的,只是先后时间差别太小,isDown方法并判断不出先后次序,要判断次序,需要借助其它方法),只要按下,此方法就能检测出,如:
当你先后同时按下a,s,d,f这四个键时,都会被检测到。
利用这点,我们就可以制作游戏中的复合键,比如八方向键,或快捷键,如Ctrl+F等。
3).如果同时按下了多个键,那么如何知道先后次序呢?
还记得
Key.getCode的用法说明吗?“返回按下的最后一个键的键控代码值”,同样的,此方法也不能获得按键的先后次序,但是它可以获得最后一个按键,使用它的这一特性,我们可以写出自己的检测类,用来当按下多键时,检测按键的次序。如:
使用此段代码,你可以尝试着同时按下a,s,d,f键,可以看看按键次序。
4).其实Flash按键的难于处理,主要是在于复合键的处理上,在多复合键中,如果用户有意按下多键,如何抛弃或“不理睬”不想关注的按键呢?
比如光标键吧,我们想在按下左光标+上光标键时,人物向左上角斜方向移动,那如果这时候,用户又按下向下的光标键呢,或者又按了其它的字母键呢?这时候往往会出现我们不想要的结果。即最后按键会干扰已按下的组合键。处理这种情况,除了写较复杂的if判断之外,就可以使用上边说的检测按键次序,这样只有前两个按键有效,后边再按下的键就无效,从而达到控制的目的。
5).其实很多时候,我们是通过光标控制一个MovieClip的移动的,那么如果在此使用MovieClip的按键事件下处理按键,就要注意MovieClip是与焦点相关的,如果有多个对象,那就得处理焦点一定在要移动的对象上头,按键才有效,除此之外,它的按键事件使用原理同Key的按键事件原理,所以大多数时候,我们并不使用MovieClip的按键事件,而改用MovieClip.onEnterFrame来侦听按键。下边我给了一个示例,就是使用的这个方法。
三、八方向按键示例
新窗口打开>>四、八方向按键源码下载
点此下载(6K)>>