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

J2ME 圖像裁切技巧:Graphics.setClip() 實現圖集與精靈繪製

     編輯:J2ME

為何需要 setClip?

J2ME 遊戲為了減少 JAR 體積與降低圖片載入開銷,常將多張小圖(如角色各幀、UI 圖示、數字字型)合併為一張圖集。Graphics.setClip(x, y, width, height) 正是在螢幕上開啟一個「觀察窗」,只繪製圖集中指定矩形區域,實現單一圖檔多重複用。

方法簽名與參數

public void setClip(int x, int y, int width, int height)
參數含義
x裁切矩形左上角 X 座標(螢幕座標系)
y裁切矩形左上角 Y 座標
width裁切區域寬度
height裁切區域高度

基本用法範例

// 假設 image 是 100x100 的圖集,每個小圖 20x30
// 繪製第 2 行第 1 個小圖 (x=0, y=30, w=20, h=30)
g.setClip(10, 20, 20, 30);           // 在螢幕 (10,20) 開 20x30 窗口
g.drawImage(image, 10, 20, Graphics.LEFT | Graphics.TOP); // 圖集左上角對齊窗口

// 繪製完成後**必須恢復**全螢幕裁切區,否則後續繪製受限
g.setClip(0, 0, getWidth(), getHeight());

核心原理圖解

setClip 定義的矩形區域是螢幕座標系的可繪製區域。呼叫 drawImage(img, x, y, anchor) 時,圖片的 (0,0) 點會對齊到 (x,y)。因此,若要顯示圖集中 (srcX, srcY) 起始的區域,需將圖片繪製座標設為 (screenX - srcX, screenY - srcY),使目標區域落入裁切窗口。

進階技巧:預先分割圖集為獨立 Image

若頻繁繪製同一小圖,預先分割可避免重複 setClip 呼叫,提升效能:

// 分割 10 張 10x15 的數字圖片
Image[] digits = new Image[10];
Image sheet = Image.createImage("/res/digits.png"); // 假設 100x15

for (int i = 0; i < 10; i++) {
    digits[i] = Image.createImage(10, 15); // 建立可變動圖片
    Graphics g = digits[i].getGraphics();
    g.drawImage(sheet, -i * 10, 0, Graphics.LEFT | Graphics.TOP); // 負座標偏移
    // 注意:MIDP 1.0 此法會丟失透明通道,見下方補救
}

MIDP 1.0 透明像素遺失問題與解決方案

方案適用場景代價
直接使用 setClip 繪製大圖簡單場景、幀數低每幀額外 setClip 呼叫
Nokia 裝置:DirectUtils.createImage(w, h, 0)Nokia 系列手機非標準 API,僅 Nokia 支援
MIDP 2.0:Image.createImage(src, x, y, w, h, transform)支援 MIDP 2.0 的裝置標準 API,保留透明度
// MIDP 2.0 標準分割法(保留透明度)
Image[] frames = new Image[8];
Image sheet = Image.createImage("/res/sprite_sheet.png");
for (int i = 0; i < 8; i++) {
    frames[i] = Image.createImage(sheet, i * 32, 0, 32, 32, Sprite.TRANS_NONE);
}

最佳實踐總結

  1. 恢復裁切區:每次 setClip 後務必呼叫 setClip(0,0,getWidth(),getHeight())。
  2. 座標換算:熟記「螢幕窗口座標 = 繪製座標 + 圖集源座標」的關係。
  3. 選擇策略:簡單 UI 用 setClip;高頻精靈用預分割;MIDP 2.0 優先用 createImage(src, x, y, w, h, transform)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved