MIDP提供兩類UI:
本文採用Canvas+Graphics實現通用遊戲菜單。
拒絕硬編碼座標,動態計算:
高級UI自動處理焦點,Canvas需手動實現:
selected索引記錄當前焦點項目keyPressed()處理上下鍵循環切換package com.j2medev.chapter3;
import javax.microedition.lcdui.*;
public class MenuCanvas extends Canvas {
private int selected = 0;
private int preferWidth = -1;
private int preferHeight = -1;
public static final int[] OPTIONS = {0,1,2,3};
public static final String[] LABELS = {"New Game", "Settings", "High Scores", "Exit"};
public MenuCanvas() {
// 計算項目尺寸
Font font = Font.getDefaultFont();
for (String label : LABELS) {
int w = font.stringWidth(label);
if (w > preferWidth) preferWidth = w;
}
preferWidth += 16; // 左右padding 8+8
preferHeight = font.getHeight() + 8; // 上下padding 4+4
}
protected void paint(Graphics g) {
// 清屏
int bgColor = 0xFFFFFF;
g.setColor(bgColor);
g.fillRect(0, 0, getWidth(), getHeight());
// 計算菜單區域
int menuWidth = preferWidth;
int menuHeight = preferHeight * LABELS.length;
int x = (getWidth() - menuWidth) / 2;
int y = (getHeight() - menuHeight) / 2;
// 繪製邊框與分隔線
g.setColor(0x000000);
g.drawRect(x, y, menuWidth, menuHeight);
for (int i = 1; i < LABELS.length; i++) {
g.drawLine(x, y + preferHeight * i, x + menuWidth, y + preferHeight * i);
}
// 繪製項目文本與選中高亮
for (int i = 0; i < LABELS.length; i++) {
if (selected == i) {
g.setColor(0x6699CC); // 高亮背景色
g.fillRect(x + 1, y + i * preferHeight + 1, menuWidth - 1, preferHeight - 1);
g.setColor(0x000000);
}
g.drawString(LABELS[i], x + 8, y + i * preferHeight + 4,
Graphics.LEFT | Graphics.TOP);
}
}
protected void keyPressed(int keyCode) {
int action = getGameAction(keyCode);
switch (action) {
case Canvas.FIRE:
System.out.println("選中: " + LABELS[selected]);
break;
case Canvas.DOWN:
selected = (selected + 1) % LABELS.length;
break;
case Canvas.UP:
selected = (selected - 1 + LABELS.length) % LABELS.length;
break;
}
repaint();
serviceRepaints();
}
protected void showNotify() {
System.out.println("showNotify() called");
}
}
| 技術點 | 實現要點 |
|---|---|
| 字體測量 | Font.stringWidth()獲取文本像素寬度,Font.getHeight()獲取行高 |
| 雙緩衝繪製 | MIDP Canvas默認雙緩衝,repaint()+serviceRepaints()確保即時刷新 |
| 鍵碼映射 | getGameAction()將設備鍵碼映射為UP/DOWN/FIRE等標準游戲動作 |
| 模運算循環 | (index + 1) % length實現焦點循環切換 |
drawImage()繪製項目前圖標pointerPressed()處理點擊座標判斷Canvas菜單開發核心在於幾何計算自適應與狀態驅動繪製。掌握paint()繪製邏輯與keyPressed()交互邏輯的分離協作,即可構建專業級J2ME遊戲界面。