我們知道MIDP中的低階事件處理是通過keyPressed()、keyReleased()和keyRepeated
()來處理的,分別在按鍵被按下、釋放和重複按鍵的時候被觸發。當方法被呼叫的時候,系統
會把所按下鍵的鍵值傳遞給上述的三個方法,根據按鍵的鍵值我們可以進行相關的處理。在
MIDP中定義瞭如下的按鍵值分別是: KEY_NUM0, KEY_NUM1, KEY_NUM2, KEY_NUM3,
KEY_NUM4, KEY_NUM5, KEY_NUM6, KEY_NUM7, KEY_NUM8, KEY_NUM9, KEY_STAR 和
KEY_POUND。
在遊戲開發中為了保證程式的可移植性,通常我們都會把鍵值轉換為遊戲動作,在MIDP
中定義瞭如下的遊戲動作: UP, DOWN, LEFT, RIGHT, FIRE, GAME_A, GAME_B,
GAME_C,GAME_D。轉換非常簡單,可以通過Canvas提供的方法getGameAction()。
一般來說處理keyPressed()和keyReleased()都比較容易,但是處理按鍵一直被按下的情
況稍微複雜一些。因為我們使用的裝置並不一定支援連續按鍵的事件。你可以通過方法
hasRepeatEvents()來檢測平臺是否支援當按鍵持續按下的時候產生重複事件。如果支援那麼
你可以在keyRepeated()的方法中處理相關邏輯,如果不支援那麼你必須採取其他的方法。
這裡筆者介紹一種通過設定標誌位的方式來處理連續按鍵的方法。其實原理非常的簡單,
我們通過設定標誌位判斷按鍵是否被按下了,比如我們判斷LEFT是不是被按下了。當LEFT被
按下的時候,我們把成員變數leftPressed設定為true,程式碼如下:
public void keyPressed(int keyCode)
{
int action = getGameAction(keyCode);
switch (action)
{
case LEFT:
left();
leftPressed = true;
break;
case RIGHT:
right();
rightPressed = true;
break;
default:
break;
}
repaint();
}
當按鍵被釋放的時候,我們就把相關的標記位設定為false。
public void keyReleased(int keyCode)
{
int action = getGameAction(keyCode);
switch (action)
{
case LEFT:
leftPressed = false;
buttonPressed = "";
break;
case RIGHT:
rightPressed = false;
buttonPressed = "";
break;
default:
break;
}
repaint();
}
這樣我們在重新繪製螢幕的時候就可以根據標記位的狀態進行繪畫了:
if (leftPressed)
{
left();
}
if (rightPressed)
{
right();
}
筆者給出一個簡單的例項來進行論證,我們製作一個MIDlet,當使用者按下LEFT的時候,
J2ME字串向左側移動,當使用者按下RIGHT的時候,J2ME字串向右側移動。簡單起見,我
沒有處理DOWN和UP的情況。下面是應用程式原始碼。
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class KeyActionMIDlet extends MIDlet
{
private Display display;
private MainCanvas mainCanvas;
protected void startApp() throws MIDletStateChangeException
{
display = Display.getDisplay(this);
mainCanvas = new MainCanvas();
new Thread(mainCanvas).start();
display.setCurrent(mainCanvas);
}
protected void pauseApp()
{
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException
{
}
}
package com.j2medev;
import javax.microedition.lcdui.*;
public class MainCanvas extends Canvas implements Runnable
{
private String buttonPressed;
private boolean leftPressed;
private boolean rightPressed;
private int px = getWidth() / 2;
public final int py = getHeight() / 2;
public MainCanvas()
{
buttonPressed = " ";
}
private void left()
{
if (px >= 0)
{
px--;
}
buttonPressed = "LEFT";
repaint();
}
private void right()
{
if (px <= getWidth())
{
px++;
}
buttonPressed = "RIGHT";
repaint();
}
public void run()
{
while (true)
{
if (leftPressed)
{
left();
}
if (rightPressed)
{
right();
}
try
{
Thread.sleep(50);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public void paint(Graphics g)
{
g.setColor(0xFFFFFF);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(0x000000);
g.drawString(buttonPressed, 20, 20, Graphics.LEFT | Graphics.TOP);
g.drawString("J2ME", px, py, Graphics.HCENTER | Graphics.TOP);
}
public void keyReleased(int keyCode)
{
int action = getGameAction(keyCode);
switch (action)
{
case LEFT:
leftPressed = false;
buttonPressed = "";
break;
case RIGHT:
rightPressed = false;
buttonPressed = "";
break;
default:
break;
}
repaint();
}
public void keyPressed(int keyCode)
{
int action = getGameAction(keyCode);
switch (action)
{
case LEFT:
left();
leftPressed = true;
break;
case RIGHT:
right();
rightPressed = true;
break;
default:
break;
}
repaint();
}
public void keyRepeated(int keyCode)
{
int action = getGameAction(keyCode);
switch (action)
{
case LEFT:
left();
break;
case RIGHT:
right();
break;
default:
break;
}
repaint();
}
}