在MIDP2.0里,我们可以摆脱这样的限制。它提供了新的GameCanvas,支持新的按键处理模式:按键状态字。
首
先使用一个GameCanvas,构造函数参数suppressKeyEvents表示是否抑止keyPressed等按键事件,抑止的话会减少系统不必
要的函数调用,带来性能上的提高。然后,在线程每次循环的初始,使用GameCanvas.getKeyStates()方法得到系统的按键状态。这个状
态字是一个int值,其中每一位表示一个按键是否是按下状态。这样既支持了多按键,又完全不会抢用系统调用paint的时间,还在一定程度上提高了性能。
得到keyState之后,一般采用位运算来判断某键是否按下:
int keyState = getKeyStates();
if ((keyState & LEFT_KEY) != 0) {//如果左键按下
//处理代码
}
else if ((keyState & RIGHT_KEY) != 0) {//如果右键按下
//处理代码
}
通过位运算,还可以得到其他好处。比如,如果你记录上次按键信息的话,那么
newKeys=~lastKeyState&curKeyState; //上次检测之后新按下的键,相当于keyPressed捕获到的键
lostKeys=lastKeyState&~curKeyState; //上次检测之后松开的键,相当于keyReleased捕获到的键
changedKeys=lastKyeState^curKeyState; //改变了状态的按键
还有几个要注意的问题:
如果当前GameCanvas不是正在显示的Displayble对象,那这个方法总返回0。
当你在保持按键的时候将GameCanvas重新显示在屏幕上时,getKeyState不会立即得到当前按下的键的信息,而是仍然保持为0,直到保持的按键松开再重新按下的时候,这时才可以得到正确的按键状态信息。
目
前Foma和Vodafone下很多程序的按键处理都是用MIDP1.0的keyPressed和keyReleased还有commandAction
来做的。最近在VT603等新机型上测出来一个bug,软键切换菜单或状态时如果按下软键不放,这个键将会不停的产生效果,最常见的就是游戏中Pause
状态的切换。初步猜测是系统自动实现软键的连续按键,多次回调commandAction函数所致。
一个暂时的解决办法是把
keyPressed、keyReleased改为keyPressedEx、keyReleasedEx,去除commandListener接口,把
按键接收改为在每次线程刷新的初始主动查询keyState,根据具体的位判断哪个按键按下,然后手动调用keyPressedEx、
keyReleasedEx、commandAction函数。
注意:以后写新游戏请大家尽量改为使用getKeyStatus的方式来处理按键。
Foma下按键状态:
Canvas的getKeypadState()方法。此函数不像MIDP2.0的,不管canvas是否是当前正在显示的canvas,都返回按键值。
返回的int共32位,第15位和16位为soft1和soft2。
其余键对应位参见文档Display类。
Vodafone下按键状态:
首先用DeviceControl.getDefaultDeviceControl()得到一个DeviceControl对象的实例dc。
然后调用dc.getDeviceState(DeviceControl.KEY_STATE)得到按键状态。
返回的按键状态值第17位和18位位soft1和soft2。
其余键对应位参见文档DeviceControl类。