List 雖簡單,但**樣式固定、無法全屏沉浸、動畫/音效受限**。遊戲主選單通常需:
故採用 Canvas 手繪,掌握每一像素。
g.drawImage(bg, 0, 0, TOP|LEFT)g.drawRect(x, y + index*itemHeight, w, h) 表示當前選中KEY_NUM2 (上) / KEY_NUM8 (下) 修改 index,循環KEY_NUM5 (確定) 根據 index 分發動作repaint()
package welcomecanvas;
import javax.microedition.lcdui.*;
public class MainCanvas extends Canvas {
private Image bgImage = null;
private int selectedIndex = 0; // 0~3 對應 4 個選項
private static final int ITEM_COUNT = 4;
private static final int ITEM_TOP = 24;
private static final int ITEM_HEIGHT = 30;
private static final int RECT_X = 39;
private static final int RECT_W = 100;
private static final int RECT_H = 27;
public MainCanvas() {
try {
// 放入 /res/menu.png 到 JAR 根目錄
bgImage = Image.createImage("/res/menu.png");
} catch (Exception e) {
// 失敗時備用:純色背景
bgImage = null;
}
}
protected void paint(Graphics g) {
// 1. 清屏
int w = getWidth(), h = getHeight();
g.setColor(0xFFFFFF);
g.fillRect(0, 0, w, h);
// 2. 繪製背景
if (bgImage != null) {
g.drawImage(bgImage, 0, 0, Graphics.TOP | Graphics.LEFT);
} else {
g.setColor(0x0000FF);
g.fillRect(0, 0, w, h);
}
// 3. 繪製選中高亮矩形
g.setColor(0x000000); // 黑框
int rectY = ITEM_TOP + selectedIndex * ITEM_HEIGHT;
g.drawRect(RECT_X, rectY, RECT_W, RECT_H);
// 進階:可在此繪製選項文字、圖標、動畫幀
// g.drawString(options[selectedIndex], ...);
}
protected void keyPressed(int keyCode) {
switch (keyCode) {
case Canvas.KEY_NUM2: // 上
selectedIndex = (selectedIndex - 1 + ITEM_COUNT) % ITEM_COUNT;
repaint();
break;
case Canvas.KEY_NUM8: // 下
selectedIndex = (selectedIndex + 1) % ITEM_COUNT;
repaint();
break;
case Canvas.KEY_NUM5: // 確定
executeSelection();
break;
// 兼容部分機型方向鍵映射
case Canvas.UP:
case Canvas.KEY_NUM2:
selectedIndex = (selectedIndex - 1 + ITEM_COUNT) % ITEM_COUNT;
repaint();
break;
case Canvas.DOWN:
case Canvas.KEY_NUM8:
selectedIndex = (selectedIndex + 1) % ITEM_COUNT;
repaint();
break;
case Canvas.FIRE:
case Canvas.KEY_NUM5:
executeSelection();
break;
}
}
private void executeSelection() {
switch (selectedIndex) {
case 0: // 新遊戲
CanvasMIDlet.startGame();
break;
case 1: // 設置
CanvasMIDlet.showSettings();
break;
case 2: // 幫助
CanvasMIDlet.showHelp();
break;
case 3: // 退出
CanvasMIDlet.quitApp();
break;
}
}
}
public class CanvasMIDlet extends MIDlet {
private static MainCanvas mainCanvas;
private static GameCanvas gameCanvas;
public void startApp() {
if (mainCanvas == null) mainCanvas = new MainCanvas();
Display.getDisplay(this).setCurrent(mainCanvas);
}
public static void startGame() {
if (gameCanvas == null) gameCanvas = new GameCanvas();
Display.getDisplay(getInstance()).setCurrent(gameCanvas);
}
public static void showSettings() { /* ... */ }
public static void showHelp() { /* ... */ }
public static void quitApp() { notifyDestroyed(); }
}
| 功能 | 實現要點 | 預載入 Font,g.drawString(option[i], x, y, anchor),選中項換色/加粗
| 引入 animFrame,paint() 根據幀繪製縮放/閃爍矩形
| Manager.createPlayer(getClass().getResourceAsStream("/click.wav"), "audio/x-wav"),player.start()
| 覆寫 pointerPressed(x,y),檢測點擊區域映射到 index
| setFullScreenMode(true) (MIDP 2.0),隱藏標題/軟鍵欄
|
|---|
Canvas 手繪選單雖代碼量稍大,但**完全掌控視覺與交互細節**,是商業級 J2ME 遊戲的標配。掌握「背景+高亮矩形+狀態機+鍵盤映射」核心模板,可快速構建主選單、暫停菜單、關卡選擇、商店界面等所有全屏 UI。