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

J2ME 遊戲開發實戰技巧 (一):雙緩衝與自訂斷點除錯

     編輯:J2ME

技巧一:雙緩衝消除螢幕閃爍

原理

閃爍成因:畫面顯示的同時程式又在修改像素。雙緩衝在記憶體開闢後台緩衝區,所有繪圖操作在後台完成,一次性複製到前台顯示。

實作範例

public class GameCanvas extends Canvas implements Runnable {
    Graphics bg;      // 後台繪圖上下文
    Image buffer;     // 後台緩衝圖片
    int width, height;

    public GameCanvas() {
        width = getWidth();
        height = getHeight();
        buffer = Image.createImage(width, height); // 建立緩衝區
        bg = buffer.getGraphics();                 // 取得後台 Graphics
    }

    private void drawBlock(int bx, int by) {
        int x = getLeft(bx);
        int y = getTop(by);
        int color = board[bx][by];
        bg.drawImage(blockImages[color], x, y, Graphics.TOP | Graphics.LEFT);
    }

    public void run() {
        while (running) {
            // 1. 所有繪圖在 bg 上進行
            for (int i=0; i

關鍵步驟總結

  1. 定義 Image buffer + Graphics bg,依螢幕尺寸建立緩衝區。
  2. 所有繪圖 (drawImage, fillRect, drawString...) 操作 bg。
  3. 呼叫 repaint() 觸發系統呼叫 paint(g)。
  4. paint(g) 中單純 g.drawImage(buffer, 0, 0, ...) 刷新螢幕。

MIDP 2.0 GameCanvas 內建此機制,直接用 getGraphics() 取得後台 Graphics,繪製完呼叫 flushGraphics() 即可。


技巧二:自訂斷點函數 — 解決模擬器死機與無法除錯

痛點

  • IDE 斷點易導致模擬器凍結、死機。
  • 即使不死機,斷點干擾執行時序,難以重現 Bug。
  • 仍需即時查看變數值定位問題。

解決方案:軟體斷點

public class GameCanvas extends Canvas implements Runnable {
    private boolean stopFlag = false; // 除錯旗標

    public void run() {
        // 斷點位置 1
        debugBreak("x:" + x + " y:" + y);

        // ... 遊戲邏輯 ...

        // 斷點位置 2
        debugBreak("score:" + score);
    }

    private void debugBreak(String msg) {
        stopFlag = true;
        // 畫白底黑字訊息到後台緩衝區
        bg.setGrayScale(255); // 白
        bg.fillRect(0, 0, fontW, fontH);
        bg.setGrayScale(0);   // 黑
        bg.drawString(msg, 0, 0, Graphics.TOP | Graphics.LEFT);
        repaint(); // 刷新顯示

        // 死循環等待按鍵
        while (stopFlag) {
            // 不佔用 CPU?實測 J2ME 中空 while 會佔滿 CPU
            // 可加 Thread.yield() 或 sleep(10) 緩解
            try { Thread.sleep(10); } catch (Exception e) {}
        }
    }

    public void keyPressed(int keyCode) {
        stopFlag = false; // 任意鍵繼續執行
    }
}

優點

  • 零 IDE 依賴,真機/模擬器均可用。
  • 可在迴圈中、任何函數放置多個斷點。
  • 按任意鍵單步繼續,不干擾遊戲邏輯時序。
  • 螢幕直接顯示變數值,直觀高效。

延伸應用:遊戲暫停功能

private boolean paused = false;

public void run() {
    while (running) {
        if (!paused) {
            // 遊戲邏輯
        }
        // 暫停時只處理重繪與輸入
        repaint();
        // sleep...
    }
}

public void keyPressed(int keyCode) {
    int action = getGameAction(keyCode);
    if (action == FIRE) paused = !paused; // Fire 鍵切換暫停
}

優於 Thread.sleep(Long.MAX_VALUE):理論上 sleep 無法無限期暫停,且無法即時響應繪圖更新。旗標法完美解決。


圖示說明

斷點除錯畫面截圖

圖 1:自訂斷點運行時畫面,白底顯示變數值,按鍵繼續。

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