MIDP 2.0 javax.microedition.lcdui.game 套件提供 Layer、LayerManager、Sprite、TiledLayer 實現 2D 遊戲圖層化渲染。本文透過完整範例示範:背景圖層、角色 Sprite 多幀動畫、圖層管理、可視窗口控制與按鍵移動。
TiledLayer (場景磚塊)、Sprite (角色) 繼承。append/insert/remove 動態調整。setViewWindow(x,y,w,h) 實現畫面捲動。Sprite(Image, frameW, frameH) 自動切割幀 (左→右、上→下),setFrame(index) 切換動畫,setPosition(x,y) 定位。public class ExampleLayerManagerMidlet extends MIDlet {
private Display display;
public void startApp() {
try {
display = Display.getDisplay(this);
ExampleGameCanvas gc = new ExampleGameCanvas();
gc.start();
display.setCurrent(gc);
} catch (Exception ex) { System.out.println(ex); }
}
public void pauseApp() {}
public void destroyApp(boolean uc) { exit(); }
public void exit() { System.gc(); destroyApp(false); notifyDestroyed(); }
public Display getDisplay() { return display; }
}
public class ExampleGameCanvas extends GameCanvas implements Runnable {
private boolean isPlay = true;
private long delay = 20;
private int currentX, currentY, width, height;
private Sprite playerSprite, backgroundSprite;
private LayerManager layerManager;
public ExampleGameCanvas() throws Exception {
super(true); // 關閉鍵盤事件自動繪製
width = getWidth(); height = getHeight();
currentX = width/2; currentY = height/2;
// 載入角色 Sprite (5 幀 32x32)
Image playerImg = Image.createImage("/transparent.png");
playerSprite = new Sprite(playerImg, 32, 32);
System.out.println("Frames: " + playerSprite.getRawFrameCount()); // 5
// 背景單一影像 Sprite
Image bgImg = Image.createImage("/background.png");
backgroundSprite = new Sprite(bgImg);
// 圖層管理:角色在上層
layerManager = new LayerManager();
layerManager.append(playerSprite); // 索引 0
layerManager.append(backgroundSprite); // 索引 1 (底層)
}
public void start() { isPlay = true; new Thread(this).start(); }
public void stop() { isPlay = false; }
public void run() {
Graphics g = getGraphics();
while (isPlay) {
handleInput();
render(g);
try { Thread.sleep(delay); } catch (InterruptedException ignored) {}
}
}
private void handleInput() {
int ks = getKeyStates();
playerSprite.setFrame(0); // 預設幀
if ((ks & LEFT_PRESSED) != 0) {
currentX = Math.max(0, currentX - 1);
playerSprite.setFrame(1);
}
if ((ks & RIGHT_PRESSED) != 0) {
if (currentX + 5 < width) { currentX = Math.min(width, currentX + 1); playerSprite.setFrame(3); }
}
if ((ks & UP_PRESSED) != 0) {
currentY = Math.max(0, currentY - 1);
playerSprite.setFrame(2);
}
if ((ks & DOWN_PRESSED) != 0) {
if (currentY + 10 < height) { currentY = Math.min(height, currentY + 1); playerSprite.setFrame(4); }
}
}
private void render(Graphics g) {
g.setColor(0xFFFFFF); g.fillRect(0, 0, width, height);
g.setColor(0x0000FF);
playerSprite.setPosition(currentX, currentY);
layerManager.setViewWindow(55, 20, 140, 140); // 可視窗口
layerManager.paint(g, 20, 20); // 繪製至螢幕 (20,20)
flushGraphics(); // GameCanvas 雙緩衝刷新
}
}
Sprite.collidesWith() 支援像素級/矩形碰撞。setViewWindow 追蹤角色位置。GameCanvas 雙緩衝 + flushGraphics() 消除閃爍,關閉系統鍵盤繪製 (super(true)) 獲完全控制權。