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

J2ME Canvas 繪製遊戲選單完整實作教學 (低階 UI 精細控制)

     編輯:J2ME

高階 vs 低階 UI 選擇

遊戲選單需求:焦點高亮、動畫、自訂版面 → **必須使用 Canvas**。

核心類別:Canvas 與 Graphics

  • Canvas:繪圖畫布,提供 paint(Graphics)、按鍵事件 keyPressed/Released/Repeated、遊戲動作映射 getGameAction
  • Graphics:畫筆,提供幾何繪製、文字、影像渲染、裁剪、色彩、字體操作

選單設計關鍵點

1. 相對座標計算 (適配多解析度)

  • 項目高度 = 字體高度 + 上下 padding
  • 項目寬度 = 最長文字寬度 + 左右 padding
  • 選單總寬/高 = 單項尺寸 × 項目數
  • 選單左上角 = ((螢幕寬 - 選單寬)/2, (螢幕高 - 選單高)/2) → 置中顯示

2. 焦點管理

  • 整數變數 selected 記錄當前焦點索引 (0-based)
  • keyPressed 中透過 getGameAction(keyCode) 判斷 UP/DOWN/FIRE
  • 索引環狀遞增/遞減:(selected + 1) % count、(selected - 1 + count) % count
  • 修改 selected 後呼叫 repaint() 觸發重繪

3. 繪製邏輯 (paint 方法)

  1. 清除畫面:g.fillRect(0,0,w,h) (白底)
  2. 繪製外框矩形
  3. 繪製分隔線 (for 迴圈)
  4. 繪製各項目文字,焦點項目前繪製高亮背景矩形

完整原始碼:MenuCanvas.java


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() {
        selected = OPTIONS[0];
        
        // 計算項目尺寸
        Font f = Font.getDefaultFont();
        for (int i = 0; i < LABELS.length; i++) {
            int w = f.stringWidth(LABELS[i]);
            if (w > preferWidth) preferWidth = w;
        }
        preferWidth += 2 * 8;  // 左右 padding 8px
        preferHeight = f.getHeight() + 2 * 4; // 上下 padding 4px
    }

    protected void paint(Graphics g) {
        // 保存原色
        int oldColor = g.getColor();
        
        // 清除背景 (白)
        g.setColor(0xFFFFFF);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(oldColor);
        
        // 選單幾何計算
        int rectWidth = preferWidth;
        int rectHeight = preferHeight * LABELS.length;
        int x = (getWidth() - rectWidth) / 2;
        int y = (getHeight() - rectHeight) / 2;
        
        // 外框
        g.drawRect(x, y, rectWidth, rectHeight);
        
        // 分隔線
        for (int i = 1; i < LABELS.length; i++) {
            g.drawLine(x, y + preferHeight * i, x + rectWidth, y + preferHeight * i);
        }
        
        // 項目文字與焦點高亮
        for (int j = 0; j < LABELS.length; j++) {
            int itemY = y + j * preferHeight;
            if (selected == j) {
                // 高亮背景 (淺藍)
                g.setColor(0x6699CC);
                g.fillRect(x + 1, itemY + 1, rectWidth - 1, preferHeight - 1);
                g.setColor(oldColor);
            }
            // 文字 (左上對齊,留 8px 左邊距, 4px 上邊距)
            g.drawString(LABELS[j], x + 8, itemY + 4, Graphics.LEFT | Graphics.TOP);
        }
    }

    protected void keyPressed(int keyCode) {
        int action = getGameAction(keyCode);
        switch (action) {
            case Canvas.FIRE:
                printLabel(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");
    }

    private void printLabel(int idx) {
        System.out.println("Selected: " + LABELS[idx]);
    }
}

進階擴充方向

特性高階 UI (List, Form, ChoiceGroup...)低階 UI (Canvas, Graphics)
開發難度低高
可移植性強 (由實作商適配)需自行處理螢幕尺寸差異
控制力弱 (外觀由系統決定)強 (像素級控制)
適用場景表單、清單、一般應用遊戲、自訂元件、特效介面

效能與相容性提醒

  • serviceRepaints():某些裝置 (如早期 Nokia) 若不呼叫,repaint() 可能不會立即觸發 paint()
  • 字體取得:Font.getDefaultFont() 保證存在;自訂字體需 Font.getFont() 捕捉例外
  • 影像資源:Image.createImage("/icon.png") 放入 res/ 打包進 JAR
  • 記憶體:避免在 paint() 中建立新物件 (String, Image, Font),預先建立為欄位

總結

掌握 Canvas 繪製、座標計算、焦點狀態機、按鍵映射四大核心,即可實作專業級遊戲選單。低階 UI 雖開發成本較高,但能創造高階 UI 無法實現的獨特體驗,是 J2ME 遊戲開發必備技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
功能實作要點
焦點動畫引入 focusAnimOffset,在 run() 執行緒中漸變顏色/位移,配合 repaint()
二級選單狀態機管理:MENU_MAIN, MENU_SETTINGS...,FIRE 切換狀態並重設 selected=0
Tabbed 選單頂部標籤列 + 內容區,左右鍵切換標籤,上下鍵操作內容
圖示支援每項目關聯 Image,drawImage 繪製於文字左側
觸控支援 (MIDP 2.0+)實作 pointerPressed/Released/Dragged,計算點擊區域對應項目索引