J2ME游戏按键处理方法简述

J2ME游戏按键处理方法简述 

摘要:在游戏当中很多时候,要求按键有更多的响应方式,我们的问题就多起来了。

  正文:

1.ScanKey()方法
这种方法使在keyPressed()、keyRelease()回调中记录按键的情况,每次Game Loop之前使用ScanKey()函数获得需要的记录情况,这次GameLoop都会使用它产生的按键结果。
这种方法的缺陷是两次Scankey()的时间间隔内,按键的记录可能会被漏掉,这个时间间隔越长(Gameloop运行时间长),这种现象出现的机会就越大。当然,改变按键的记录和读取方法,可以解决大部分出现的问题。
 
ScanKey()方法根据调用时的keyNow值,确定当前的键值。
     public static final void scanKey (){
          int know = keyNow ;
          keyEdge = know & (~ keyPrev );
          if ( know == 0 || know != keyPrev ) {
               keyRepWk = 0;
               keyRep = 0;
          } else {
               if (++ keyRepWk > keyRepWait ) {
                   -- keyRepWk ;
                   keyRep = know ;
               } else {
                   keyRep = 0;
               }
          }
          keyPrev = know ;
     }
KeyNow的记录方法如下:
     public final int getGameKey( int keyCode ){
          // Zero is defined to be an invalid key code.
          if (keyCode == 0)
               return 0;
         
          switch ( keyCode ){
          case KEY_NUM2 :      return K_UP ;
          case KEY_NUM4 :      return K_LEFT ;
          case KEY_NUM5 :      return K_SELECT ;
          case KEY_NUM6 :      return K_RIGHT ;
          case KEY_NUM8 :      return K_DOWN ;
          case SOFT1_KEYCODE : return K_SOFT1 ;
          case SOFT2_KEYCODE : return K_SOFT2 ;
          case KEY_NUM7 :      return K_NUM7 ;
          case KEY_NUM9 :      return K_NUM9 ;
          case KEY_NUM0 :      return K_NUM0 ;
          case KEY_NUM1 :      return K_NUM1 ;
          case KEY_STAR :      return K_STAR ;
          default :
               int act = getGameAction( keyCode );
               if ( act != 0 ){
                   switch ( act ){
                   case Canvas. FIRE :     return K_SELECT ;
                   case Canvas. UP :       return K_UP ;
                   case Canvas. DOWN :     return K_DOWN ;
                   case Canvas. LEFT :     return K_LEFT ;
                   case Canvas. RIGHT :    return K_RIGHT ;
                   }
               }
          }
         
          return 0;
    
     }
 
     protected synchronized void keyPressed( int keyCode ){
          int key = getGameKey( keyCode );
          keyNow |= key;
     }
 
     protected synchronized void keyReleased( int keyCode ){
          int key = getGameKey(keyCode);
          keyNow &= ~key;
     }
这种方法会漏掉在 scanKey() 调用后,到下次调用前,按下又松开的 Click 事件。
这里有个假定,就是 scanKey() 函数会瞬时执行完毕, keyNow 不会在调用过程中被改变,事实上,这种情况是很少出现的。
加入 keyPress 记录在两个 scankey() 之间被按下的键值, scanKey() 完毕后,添加到 keyEdge 中。
 
2.GameCanvas.getKeyStatus()方法
如果只在每次循环之前调用getKeyStatus(),缺陷同样存在,同时还缺少了其他特殊要求的按键事件的记录。如果在循环中需要获取按键情况的地方调用getKeyStatus(),造成的问题是一个GameLoop的处理其实面对着随时变化的键输入,一部分代码处理时是一个键键值,另一部分代码处理了另一个键值。具有如此之高灵活性的代码是写不出来的。
 
 
3.在keyPressed()回调方法中处理按键
在keyPressed()方法中修改需要响应按键的变量,例如,ARPG中主角的位置、方向、状态等,这就要求GameLoop中的代码肯定会读取这些变量,也很有可能改变它们,同时GameLoop代码要面对这些变量随时改变的情况,即使程序运行不会出问题,也留下了很大隐患。
 
总结:
我认为2,3两种方法对于状态时刻改变的游戏不能使用,由游戏的复杂程度决定的计算量不会因为分开处理而减少,反而带来了很多不易检查的同步问题。如果程序本身很负责,占用CPU时间长,对应按键的响应必然会延时或者忽略。
 
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值