按键事件的处理
2010-06-07 09:56
197 查看
接下来要说的是:
按键事件的处理。
所谓按键处理,就是在游戏中,玩家按了一个键。
你把它记录下来,然后在程序中判断,按了
什么键,要完成什么相应的功能。
这个按键处理系统也是十分巧妙,实现的方式不一样,照顾的方面也不一样。
我现在只能说些简单的例子。
一个简单的键盘处理系统,可能会经过很长期的完善才能变得成熟。
因为这个东西实现起来很复杂。(对我来说^^)
在
Game.java中添加如下代码:
public void keyPressed(int keyCode) {
//
系统事件,当键盘被按下,系统会调用这个方法,并把你按得键值keyCode传进来。
// 注意,这个
keyCode键值不是数值,就是说你按
number
1,不一定是1。在手机上,每个键都有一个独特的keyCode,这和生产厂商
有关。
//
不同的手机,keyCode可能不相同。模拟器的keyCode和真实手机的也可能不相同.
:)
}
public void keyReleased(int keyCode) {
//
同上,当一个键被松开,系统会调用这个方法。
}
public void keyRepeated(int
keyCode) {
//
同上,当一个键被持续按着,系统会调用这个方法。
//
大
多数手机不支持这个方法,反而支持keyPressed方法。
//
就是说,如果你一直按着某个
键,keyPressed方法会被持续调用,而不是这个方法。
}
所以我们就只看
public void
keyPressed(int keyCode) {
}
public void keyReleased(int
keyCode) {
}
这两个方法就够了。一个好的设计完全可以用这两个方法满足所有需要。
在上次的
Game.java中,第二个状态是这样:
case 2:
ourGraphics.setColor(0);
ourGraphics.fillRect(0, 0,
128, 128);
ourGraphics.setColor(0xffffff);
ourGraphics.drawString("Fuck Man! It's New Game!", 128
>> 1,
128 >> 1, Graphics.TOP | Graphics.HCENTER);
//
我们在这里添上键盘处理件:
/**
if (keyValue == NUM6) {
gameState = 3; // 如果按了6键,就跑到状态3里面.
}
*/
break;
然后我们再添一个状态3,
case
3:
ourGraphics.setColor(0);
ourGraphics.fillRect(0, 0, 128, 128);
ourGraphics.setColor(0xffffff);
ourGraphics.drawString("Haha, dao 3 le!", 128 >> 1, 128
>>
1, Graphics.TOP | Graphics.HCENTER);
// 我们在这里添上键盘处理事件:
/**
if (keyValue == NUM4) {
gameState = 2; // 如果按了4键,又跑回状态2里面.
}
*/
break;
上面的代码先就那样把注释加着, /** */
定义一
个变量,
int keyValue;
//然后在这里面
public void keyPressed(int
keyCode) {
//加上一句:
System.out.println("The keycode
of the key you pressed is " +
keyCode);
//这样你每按一个键,控制台就会把这个键对应的键
值打印出来. //把这个键值赋给这个变量,作为以后判断按键事件的依据。
keyValue = keyCode;
}
现在可以试试这个程序,按一下4,或6,看看他们的键值是多少,然后定义以下两个变量:
final static
int NUM4 = 52; //在这里写按4时得到的键值
final static int NUM6 = 54;
//在这里写按6时得到的键值
// final 就意味不可改变。static final就是一个常量。
一般来说,这些键值都事先
定义好。手机不同,只需要改变这些常量的值就可以了。
现在可以把case 2 和 case 3的注释去掉。运行程序:
这样
在到达状态2以后,按6键,游戏就会跑到状态3。
然后再按4,就会返回到状态2。
为了避免keyValue这个值一直保存,在
case
2的里面加上:
/**
if (keyValue == NUM6) {
gameState = 3; // 如果按了6键,就跑到状态3里面.
keyValue = -1; //
随便搞个负数给它,免得这个值在其它状态还可能起作用.意思就是判断完了就不要了.
}
*/
一个简单的键盘处理的例子就完成了。:)
但是这个键盘处理的方法非常不完善。
case
2运行的时候,如果很快的按6再按4,
这时keyValue变成NUM4,然后在 case
2的判断中,就判断不到你按过6。
看
来现在的问题就是用一个keyValue变量存储按过的键,只能存储一个。
有个办法:
假设 keyValue
用2进制表示,他就有很多位可以利用。
int keyValue = 0; // 0000 00000 0000.....
假设第
四位表示按键4,第六位表示按键6......依此类推。
那么如果按了 NUM6, 就把
keyValue的第6位表示成1,表示按
下。
那么如果按了 NUM4, 就把
keyValue的第4位表示成1,表示按下。
只要存储的位置不同,那么一个整数就可
以同时存储多个按键的状态了。
现在定义两个变量,表示某个键在这个整形中的位置:
static final int
GAME_NUM4 = 1 << 4; // 意思是二进制的10000,
把1向右移4位。
static final
int GAME_NUM6 = 1 << 6; // 意思是二进制的1000000,
把1向右移6位。
修
改 这个函数。
public void keyPressed(int keyCode) {
switch (keyCode)
{
case NUM4:
keyValue |= GAME_NUM4; //
如果二进制keyValue的值是 0,
那么|(或)了之后,keyValue = 10000.
// 如果 keyValue = 0010
0000,那么|(或)了之后,keyValue = 0011
0000.就是右数第
5位改变了,其他位不变。
break;
case NUM6:
keyValue
|= GAME_NUM6;
break;
// case
....完整的游戏代码里,后面还有很多
case,要把所有手机上的按键都给写全了。java的整型是32位的。应该能存32个键。足够了。
}
}
存
储按键值得方法变了,判断的方法也要变。
修改case 2中的
if (keyValue == NUM6) {
gameState = 3;
keyValue = -1;
}
变成
if ((keyValue & GAME_NUM6) != 0 ) {
//
如果按了6键那一位是1,就表示6被按下了。
// 0 & 1 = 0, 1 & 1
= 1
//
那么keyValue的每一位和GAME_NUM6的每一位 &
// 1111 1010
keyValue (随便写的值)
// 0100 0000
GAME_NUM6
//
这样看来那么keyValue &
GAME_NUM6的值就决定在第7位。其他位&的结果肯定是0。
//
如果keyValue的第7位是1,就意味着keyValue & GAME_NUM6 != 0.
gameState = 3;
keyValue &= ~GAME_NUM6; //
使用完之后,把这一个按键位清空,其他位保留。
// ~符号的意思是取反.
GAME_NUM6 的二进制是 0100 0000, 取反之后等于1011 1111
// 再跟keyValue
&,就相当于其他为保持不变,第7位变成0了。
}
可
以试试看了,现在的话,很快的按6再按4,6仍然是起作用的。
一般在
keyReleased方法中,也要把释放的键位给清空,也用上
面的方法。
恩,我举的例子似乎不是很好。没能表现key系统的处理。
按键可能随时发生,所以keyValue的值可
能会随时改变。这样的话,直接用keyValue来进行判断就非常不稳定了。
现在的解决办法是:
使用keyValue来记录按键的状
态。
按下-->打开相应的位, 释放-->清空相应的位
然后再搞一个变量专门进行判断。
假设这个变量
是frameKey.
在每一桢开始时,frameKey = keyValue.
那么对这一桢来说,frameKey是不变的!不管
你怎么按键,变得都是keyValue.
在这一桢里,我们始终用frameKey来进行按键的判断。因此,按键的状态变得稳定了。
然
后在下一桢,又把变过的keyValue赋给frameKey,再使用frameKey进行判断。
呵呵。这样的判断也可能漏掉某些按
键。
其实我很长时间都没有去认真研究代码,去理解代码了。
成天忙于改bug,对游戏开发本身的知识简直蜕变为0了。
只
有以后动手做。如果碰到具体的不能满足的需要,就再去研究。
就讲这么多。
按键事件的处理。
所谓按键处理,就是在游戏中,玩家按了一个键。
你把它记录下来,然后在程序中判断,按了
什么键,要完成什么相应的功能。
这个按键处理系统也是十分巧妙,实现的方式不一样,照顾的方面也不一样。
我现在只能说些简单的例子。
一个简单的键盘处理系统,可能会经过很长期的完善才能变得成熟。
因为这个东西实现起来很复杂。(对我来说^^)
在
Game.java中添加如下代码:
public void keyPressed(int keyCode) {
//
系统事件,当键盘被按下,系统会调用这个方法,并把你按得键值keyCode传进来。
// 注意,这个
keyCode键值不是数值,就是说你按
number
1,不一定是1。在手机上,每个键都有一个独特的keyCode,这和生产厂商
有关。
//
不同的手机,keyCode可能不相同。模拟器的keyCode和真实手机的也可能不相同.
:)
}
public void keyReleased(int keyCode) {
//
同上,当一个键被松开,系统会调用这个方法。
}
public void keyRepeated(int
keyCode) {
//
同上,当一个键被持续按着,系统会调用这个方法。
//
大
多数手机不支持这个方法,反而支持keyPressed方法。
//
就是说,如果你一直按着某个
键,keyPressed方法会被持续调用,而不是这个方法。
}
所以我们就只看
public void
keyPressed(int keyCode) {
}
public void keyReleased(int
keyCode) {
}
这两个方法就够了。一个好的设计完全可以用这两个方法满足所有需要。
在上次的
Game.java中,第二个状态是这样:
case 2:
ourGraphics.setColor(0);
ourGraphics.fillRect(0, 0,
128, 128);
ourGraphics.setColor(0xffffff);
ourGraphics.drawString("Fuck Man! It's New Game!", 128
>> 1,
128 >> 1, Graphics.TOP | Graphics.HCENTER);
//
我们在这里添上键盘处理件:
/**
if (keyValue == NUM6) {
gameState = 3; // 如果按了6键,就跑到状态3里面.
}
*/
break;
然后我们再添一个状态3,
case
3:
ourGraphics.setColor(0);
ourGraphics.fillRect(0, 0, 128, 128);
ourGraphics.setColor(0xffffff);
ourGraphics.drawString("Haha, dao 3 le!", 128 >> 1, 128
>>
1, Graphics.TOP | Graphics.HCENTER);
// 我们在这里添上键盘处理事件:
/**
if (keyValue == NUM4) {
gameState = 2; // 如果按了4键,又跑回状态2里面.
}
*/
break;
上面的代码先就那样把注释加着, /** */
定义一
个变量,
int keyValue;
//然后在这里面
public void keyPressed(int
keyCode) {
//加上一句:
System.out.println("The keycode
of the key you pressed is " +
keyCode);
//这样你每按一个键,控制台就会把这个键对应的键
值打印出来. //把这个键值赋给这个变量,作为以后判断按键事件的依据。
keyValue = keyCode;
}
现在可以试试这个程序,按一下4,或6,看看他们的键值是多少,然后定义以下两个变量:
final static
int NUM4 = 52; //在这里写按4时得到的键值
final static int NUM6 = 54;
//在这里写按6时得到的键值
// final 就意味不可改变。static final就是一个常量。
一般来说,这些键值都事先
定义好。手机不同,只需要改变这些常量的值就可以了。
现在可以把case 2 和 case 3的注释去掉。运行程序:
这样
在到达状态2以后,按6键,游戏就会跑到状态3。
然后再按4,就会返回到状态2。
为了避免keyValue这个值一直保存,在
case
2的里面加上:
/**
if (keyValue == NUM6) {
gameState = 3; // 如果按了6键,就跑到状态3里面.
keyValue = -1; //
随便搞个负数给它,免得这个值在其它状态还可能起作用.意思就是判断完了就不要了.
}
*/
一个简单的键盘处理的例子就完成了。:)
但是这个键盘处理的方法非常不完善。
case
2运行的时候,如果很快的按6再按4,
这时keyValue变成NUM4,然后在 case
2的判断中,就判断不到你按过6。
看
来现在的问题就是用一个keyValue变量存储按过的键,只能存储一个。
有个办法:
假设 keyValue
用2进制表示,他就有很多位可以利用。
int keyValue = 0; // 0000 00000 0000.....
假设第
四位表示按键4,第六位表示按键6......依此类推。
那么如果按了 NUM6, 就把
keyValue的第6位表示成1,表示按
下。
那么如果按了 NUM4, 就把
keyValue的第4位表示成1,表示按下。
只要存储的位置不同,那么一个整数就可
以同时存储多个按键的状态了。
现在定义两个变量,表示某个键在这个整形中的位置:
static final int
GAME_NUM4 = 1 << 4; // 意思是二进制的10000,
把1向右移4位。
static final
int GAME_NUM6 = 1 << 6; // 意思是二进制的1000000,
把1向右移6位。
修
改 这个函数。
public void keyPressed(int keyCode) {
switch (keyCode)
{
case NUM4:
keyValue |= GAME_NUM4; //
如果二进制keyValue的值是 0,
那么|(或)了之后,keyValue = 10000.
// 如果 keyValue = 0010
0000,那么|(或)了之后,keyValue = 0011
0000.就是右数第
5位改变了,其他位不变。
break;
case NUM6:
keyValue
|= GAME_NUM6;
break;
// case
....完整的游戏代码里,后面还有很多
case,要把所有手机上的按键都给写全了。java的整型是32位的。应该能存32个键。足够了。
}
}
存
储按键值得方法变了,判断的方法也要变。
修改case 2中的
if (keyValue == NUM6) {
gameState = 3;
keyValue = -1;
}
变成
if ((keyValue & GAME_NUM6) != 0 ) {
//
如果按了6键那一位是1,就表示6被按下了。
// 0 & 1 = 0, 1 & 1
= 1
//
那么keyValue的每一位和GAME_NUM6的每一位 &
// 1111 1010
keyValue (随便写的值)
// 0100 0000
GAME_NUM6
//
这样看来那么keyValue &
GAME_NUM6的值就决定在第7位。其他位&的结果肯定是0。
//
如果keyValue的第7位是1,就意味着keyValue & GAME_NUM6 != 0.
gameState = 3;
keyValue &= ~GAME_NUM6; //
使用完之后,把这一个按键位清空,其他位保留。
// ~符号的意思是取反.
GAME_NUM6 的二进制是 0100 0000, 取反之后等于1011 1111
// 再跟keyValue
&,就相当于其他为保持不变,第7位变成0了。
}
可
以试试看了,现在的话,很快的按6再按4,6仍然是起作用的。
一般在
keyReleased方法中,也要把释放的键位给清空,也用上
面的方法。
恩,我举的例子似乎不是很好。没能表现key系统的处理。
按键可能随时发生,所以keyValue的值可
能会随时改变。这样的话,直接用keyValue来进行判断就非常不稳定了。
现在的解决办法是:
使用keyValue来记录按键的状
态。
按下-->打开相应的位, 释放-->清空相应的位
然后再搞一个变量专门进行判断。
假设这个变量
是frameKey.
在每一桢开始时,frameKey = keyValue.
那么对这一桢来说,frameKey是不变的!不管
你怎么按键,变得都是keyValue.
在这一桢里,我们始终用frameKey来进行按键的判断。因此,按键的状态变得稳定了。
然
后在下一桢,又把变过的keyValue赋给frameKey,再使用frameKey进行判断。
呵呵。这样的判断也可能漏掉某些按
键。
其实我很长时间都没有去认真研究代码,去理解代码了。
成天忙于改bug,对游戏开发本身的知识简直蜕变为0了。
只
有以后动手做。如果碰到具体的不能满足的需要,就再去研究。
就讲这么多。
相关文章推荐
- c进程读取按键输入,通过socket传输给qt,qt按键线程接收到后,提交到Qt的事件处理系统中
- Android按键事件处理流程 -- KeyEvent
- 王学岗按键事件的处理
- J2ME MIDP2.0 GameCanvas中对多个按键同时按下事件处理的一种方法
- 按键事件(KeyEvent)的监听与处理
- Android按键事件处理流程
- 按键分析--APP部分-- OnTouch事件处理流程
- ListView的长按键事件的处理
- 添加按键事件处理及事件处理的参数传递
- BREW按键及其他事件的处理
- Android按键事件处理流程 -- KeyEvent
- #646 – 在按键按下事件处理程序中判断按键开关状态(Detecting a Key’s Toggle State in a Keypress Handler)
- Android 系列 6.22处理活动中的按键事件
- Cocos2dx事件处理机制之按键事件
- Android+按键事件处理详解
- android按键连续按下事件处理
- Android按键事件处理分析
- Java处理按键事件
- android按键事件和触屏事件(四)-listview的setOnItemClickListener点击无效的处理
- QML按键事件处理