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

J2ME 低層圖形系統深度解析:Display、Graphics、Canvas、Font、Image 五大核心類完整指南

     編輯:J2ME

MIDP 低層圖形架構總覽

javax.microedition.lcdui 封裝了完整的低層繪圖體系,五大核心類各司其職:

類別角色核心職責
Display螢幕管理器單例、管理當前顯示物件、查詢螢幕屬性 (彩色/灰階/尺寸)
Canvas繪圖畫布低層 UI 基類、提供 paint(Graphics) 回調、按鍵事件、全螢幕模式
Graphics繪圖上下文所有繪圖原語 (線/矩形/圓弧/文字/圖片)、顏色/字體/裁切區/錨點狀態
Font字體描述面貌/風格/大小、度量方法 (高度/寬度/基線)
Image圖片資源不可變 (資源/網路) / 可變 (離屏緩衝)、建立/繪製/度量

Display:螢幕控制中樞


// 取得單例
Display display = Display.getDisplay(midlet);

// 切換顯示物件
display.setCurrent(canvas);           // Canvas
display.setCurrent(form);             // 高層 UI
display.setCurrent(alert, nextScreen); // Alert 後自動轉回

// 查詢螢幕特性
boolean isColor = display.isColor();           // 是否彩屏
int numColors = display.numColors();           // 色數 (2=黑白)
int width = display.getWidth();                // 螢幕寬 (僅全螢幕模式準確)
int height = display.getHeight();              // 螢幕高

Canvas:遊戲主迴圈載體


public class GameCanvas extends Canvas {
    public GameCanvas() {
        setFullScreenMode(true); // 隱藏標題/軟鍵欄 (MIDP 2.0)
    }

    // 核心繪圖回調 (由系統自動調用,不可手動呼叫)
    protected void paint(Graphics g) {
        // 所有繪圖邏輯在這裡
    }

    // 按鍵事件
    protected void keyPressed(int keyCode) { /* 邏輯幀 */ }
    protected void keyReleased(int keyCode) { /* 釋放 */ }
    protected void keyRepeated(int keyCode) { /* 長按 */ }

    // 遊戲動作映射 (跨裝置統一)
    int action = getGameAction(keyCode); // UP, DOWN, LEFT, RIGHT, FIRE...
}

Graphics:繪圖原語大全

顏色與灰階


// RGB 24-bit
g.setColor(0xFF0000); // 紅
g.setColor(255, 0, 0); // 同義

// 灰階 (0-255)
g.setGrayScale(128); 
int gray = g.getGrayScale();

文字繪製


g.setFont(font);
g.drawString(str, x, y, anchor);           // 字串
g.drawChars(chars, offset, len, x, y, anchor); // 字元陣列
g.drawChar(ch, x, y, anchor);              // 單字元

圖片繪製


g.drawImage(img, x, y, anchor);            // 完整繪製
g.drawRegion(img, srcX, srcY, w, h, transform, x, y, anchor); // 區域+變換
// transform: TRANS_NONE, ROT90, ROT180, ROT270, MIRROR, MIRROR_ROT90...

幾何圖形

類別空心實心參數
線段drawLine(x1,y1,x2,y2)-端點座標
矩形drawRect(x,y,w,h)fillRect(x,y,w,h)左上角、寬高
圓角矩形drawRoundRect(x,y,w,h,aw,ah)fillRoundRect(...)+ 圓角寬高
圓弧/扇形drawArc(x,y,w,h,start,arc)fillArc(...)外接矩形、起始角、掃過角

裁切區


g.setClip(x, y, w, h); // 設定可繪製區域
g.clipRect(x, y, w, h); // 與現有區域取交集
// 恢復全螢幕
g.setClip(0, 0, getWidth(), getHeight());

座標系與錨點

  • 原點 (0,0) = 左上角,X 右增,Y 下增。
  • 座標為像素格線交點,線寬 1 像素佔據格線間空間。
  • 錨點組合:LEFT|TOP (預設)、HCENTER|VCENTER (中心)、RIGHT|BOTTOM 等。

Font:字體度量與選擇


// 取得字體
Font f = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE);

// 度量 (佈局必備)
int h = f.getHeight();                    // 行高
int baseline = f.getBaselinePosition();   // 基線
int w = f.stringWidth("Hello");           // 字串寬
int cw = f.charWidth('中');               // 單字寬
int sw = f.substringWidth(s, 0, 3);       // 子串寬
int cwArr = f.charsWidth(arr, 0, len);    // 陣列寬

Image:兩種模式與建立方式

模式建立方式可變性用途
不可變Image.createImage("/res/img.png")
createImage(byte[], offset, len)
createImage(InputStream)
createImage(Image src)
只讀資源圖、網路下載圖、精靈幀
可變Image.createImage(w, h)可寫入 (離屏緩衝)雙重緩衝、動態合成、文字渲染到圖

可變 Image 繪製範例


// 建立離屏緩衝
Image buffer = Image.createImage(176, 208);
Graphics bg = buffer.getGraphics();
bg.setColor(0xFFFFFF);
bg.fillRect(0, 0, 176, 208);
bg.drawString("預渲染文字", 10, 10, Graphics.LEFT | Graphics.TOP);

// 主畫布直接繪製 buffer (極快)
protected void paint(Graphics g) {
    g.drawImage(buffer, 0, 0, Graphics.TOP | Graphics.LEFT);
}

MIDP 2.0 進階建立


// 從源圖裁切並變換 (保留透明度、標準 API)
Image frame = Image.createImage(sourceImage, 
    srcX, srcY, frameW, frameH, Sprite.TRANS_NONE);

雙重緩衝與效能優化

  • canvas.isDoubleBuffered() 查詢硬體支援 (MIDP 2.0)。
  • 軟體雙重緩衝:自建可變 Image 做離屏渲染,paint() 只 drawImage 一次。
  • 批次繪製:同顏色/字體連續繪製,減少狀態切換。
  • 裁切區優化:setClip 限制重繪區域 (局部更新)。
  • 避免在 paint() 內建立物件 (new Font, new String, 運算) — 預先緩存。

完整遊戲渲染迴圈範架


public class GameCanvas extends Canvas implements Runnable {
    private Image offscreen; // 軟體雙重緩衝
    private Graphics offG;
    private Thread gameLoop;
    private volatile boolean running = true;

    public GameCanvas() {
        setFullScreenMode(true);
        offscreen = Image.createImage(getWidth(), getHeight());
        offG = offscreen.getGraphics();
        gameLoop = new Thread(this);
        gameLoop.start();
    }

    public void run() {
        while (running) {
            long t0 = System.currentTimeMillis();
            updateLogic();      // 邏輯更新
            renderOffscreen();  // 離屏繪製
            repaint();          // 排程 paint()
            long dt = System.currentTimeMillis() - t0;
            if (dt < 40) try { Thread.sleep(40 - dt); } catch (Exception ignored) {} // ~25 FPS
        }
    }

    private void renderOffscreen() {
        offG.setColor(0x000000);
        offG.fillRect(0, 0, getWidth(), getHeight());
        // 繪製所有遊戲物件到 offG...
    }

    protected void paint(Graphics g) {
        // 只需一張圖貼上去
        g.drawImage(offscreen, 0, 0, Graphics.TOP | Graphics.LEFT);
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved