为了使程序能在不同的设备上运行,就一定要考虑不同设备间键盘布局的特点,在开发程序时不能假设按键的布局方式。
getKeyState()方法所返回的键盘值
键 值 |
相对应的KeyStates值 |
UP_PRESSED |
0x0002 = 2 |
DOWN_PRESSED |
0x0040 = 64 |
LEFT_PRESSED |
0x0004 = 4 |
RIGHT_PRESSED |
0x0020 = 32 |
FIRE_PRESSED |
0x0100 = 256 |
GAME_A_PRESSED |
0x0200 = 512(并非所有设备支持) |
GAME_B_PRESSED |
0x0400 = 1024(并非所有设备支持) |
GAME_C_PRESSED |
0x0800 = 2048(并非所有设备支持) |
GAME_D_PRESSED |
0x1000 = 4096(并非所有设备支持) |
注意 |
不同的设备对于getKeyStates()方法的调用会略有不同,主要体现在:有的设备支持检测 多个键同时按下的情况,而有的设备的不支持getKeyStates()方法,仅仅是通过调用keyPressed()/keyReleased()方法 来代替,因此会产生一定的时延。 |
由于GameCanvas能够通过getKeyStates()方法主动查询键盘状态,因此也提供了是否抑制传统键盘事件的选择。
如果希望当游戏运行时,禁止调用KeyPressed()/keyReleased() /KeyRepeated()方法,那么就可以在构造GameCanvas时,在super()中传入true值。如果传入false值,那么一旦按键按 下,就会调用传统的键盘事件处理方法。
注意 |
键盘抑制只对当前GameCanvas 有效,并且只能抑制Canvas预定义的键盘事件(例如无法抑制手机上的*号键、#号键,以及接听、挂断、Clear等功能键)。 |
例子代码:
KeyTestGameCanvas.java
import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.game.GameCanvas; public class KeyTestGameCanvas extends GameCanvas implements Runnable{ private boolean isPlay;//值为true时游戏反复执行 private long delay;//线程执行时的延时,控制游戏每帧的时间 private int currentX,currentY;//当前绘图位置 //讲矩形的的颜色变化预先存放到数组中 private int[] preColors = {0xFF0000,0x00FF00,0x0000FF,0xFFFF00,0x00FFFF}; private int currentColor;//当前绘图颜色 private int width,height;//屏幕的宽度和高度 private int counter = 0;//计数器,记录按键的次数 public KeyTestGameCanvas() { super(true);//屏蔽按键事件 width = getWidth(); height = getHeight(); currentX = width/2-10; currentY = width/2-10; currentColor = 0xFF00FF; delay = 20;//游戏每帧的时间 } //启动线程 public void start(){ isPlay = true; Thread t = new Thread(this); t.start(); } public void stop(){ isPlay = false; } public void run() { Graphics g = getGraphics();//获取脱机屏幕缓冲区中的图像对象 long beginTime = 0,endTime = 0; while(isPlay==true){ beginTime = System.currentTimeMillis();//游戏每一帧开始时间 queryKey();//查询按键状态 drawScreen(g);//绘制屏幕 endTime = System.currentTimeMillis();//游戏每一帧结束时间 if(endTime-beginTime<delay){ try { Thread.sleep(delay-(endTime-beginTime)); } catch (InterruptedException e) { e.printStackTrace(); } } } } //主动查询按键状态,进行处理 private void queryKey(){ int keyStates = getKeyStates();//查询游戏按键状态 //按了左键 if((keyStates&GameCanvas.LEFT_PRESSED)!=0){ currentX = Math.max(0, currentX-2); } //按了右键 if((keyStates&GameCanvas.RIGHT_PRESSED)!=0){ currentX = Math.min(width-20, currentX+2); } //按了上键 if((keyStates&GameCanvas.UP_PRESSED)!=0){ currentY = Math.max(0, currentY-2); } //按了下键 if((keyStates&GameCanvas.DOWN_PRESSED)!=0){ currentY = Math.min(height-20, currentY+2); } //按了射击键 if((keyStates&GameCanvas.FIRE_PRESSED)!=0){ currentColor = preColors[counter]; counter = (counter+1)%5; } } private void drawScreen(Graphics g){ g.setColor(currentColor); g.fillRect(currentX, currentY, 20, 20); flushGraphics(); } }
KeyTestGameCanvasMidlet.java
import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener; import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Displayable; import javax.microedition.midlet.MIDlet; import javax.microedition.midlet.MIDletStateChangeException; public class KeyTestGameCanvasMidlet extends MIDlet implements CommandListener{ private Display display; private Command exitCommand; private KeyTestGameCanvas keyTestGameCanvas; public KeyTestGameCanvasMidlet() { } protected void destroyApp(boolean arg0) throws MIDletStateChangeException { // TODO Auto-generated method stub } protected void pauseApp() { // TODO Auto-generated method stub } protected void startApp() throws MIDletStateChangeException { display = Display.getDisplay(this);//获得显示屏幕的对象 keyTestGameCanvas = new KeyTestGameCanvas();//建立GameCanvas对象 //建立Command对象 exitCommand = new Command("退出",Command.EXIT,1); keyTestGameCanvas.addCommand(exitCommand); keyTestGameCanvas.setCommandListener(this); display.setCurrent(keyTestGameCanvas); keyTestGameCanvas.start(); } public void commandAction(Command c, Displayable d) { if(c==exitCommand){ exit(); } } public void exit(){ try { keyTestGameCanvas.stop(); destroyApp(false); notifyDestroyed(); } catch (MIDletStateChangeException e) { e.printStackTrace(); } } }
运行结果