首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME Canvas 繪製遊戲功能選單:從原理到完整源碼實現

     編輯:J2ME

為什麼不用高級 UI (List)?

List 雖簡單,但**樣式固定、無法全屏沉浸、動畫/音效受限**。遊戲主選單通常需:

  • 全屏背景圖 + 動態特效
  • 自定義選項高亮動畫(縮放、閃爍、粒子)
  • 按鍵音效、方向鍵導航手感
  • 無標題欄/軟鍵欄干擾(全屏模式)

故採用 Canvas 手繪,掌握每一像素。

核心實現原理

  1. 背景圖:g.drawImage(bg, 0, 0, TOP|LEFT)
  2. 選項矩形:g.drawRect(x, y + index*itemHeight, w, h) 表示當前選中
  3. 鍵盤導航:KEY_NUM2 (上) / KEY_NUM8 (下) 修改 index,循環
  4. 確認執行:KEY_NUM5 (確定) 根據 index 分發動作
  5. 即時重繪:每次按鍵後 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;
        }
    }
}

MIDlet 控制器配合


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),隱藏標題/軟鍵欄

    真機測試清單

    • ☐ 方向鍵/數字鍵 2/8/5 全部響應正確
    • ☐ 選項循環邏輯正確(首尾相接)
    • ☐ 背景圖顯示正常(無拉伸變形、無白邊)
    • ☐ 進入遊戲/設置/幫助/退出流程暢通
    • ☐ 來電/短信中斷後返回選單狀態保持
    • ☐ 記憶體佔用 < 200KB(含背景圖)

    結語

    Canvas 手繪選單雖代碼量稍大,但**完全掌控視覺與交互細節**,是商業級 J2ME 遊戲的標配。掌握「背景+高亮矩形+狀態機+鍵盤映射」核心模板,可快速構建主選單、暫停菜單、關卡選擇、商店界面等所有全屏 UI。

    1. 上一篇文章:
    2. 下一篇文章:
    Copyright © 程式碼之家 All Rights Reserved