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

Java AWT 動畫小球不動:缺少遊戲迴圈啟動與繪圖執行緒

     編輯:程式設計疑難解答

問題程式碼

public class New01 {
    public New01() {
        Frame f = new Frame("my app");
        GamePanel mp = new GamePanel();
        f.add(mp); f.setVisible(true);
        // 缺少 mp.gameLoop() 呼叫!
    }
    public static void main(String[] args) { new New01(); }
}

class GamePanel extends Panel {
    int x=50, y=50, diameter=100;
    public void paint(Graphics g) { g.fillOval(x,y,diameter,diameter); }
    public void gameLoop() {
        while(true) { x++; repaint(); /* 缺少延遲 */ }
    }
}

三大缺失

  1. 未啟動 gameLoop:建構子未呼叫 mp.gameLoop()。
  2. 阻塞 EDT:while(true) 在事件派發執行緒 (EDT) 跑死迴圈,導致 repaint() 排程的 paint() 永無機會執行,畫面凍結。
  3. 無幀率控制:需 Thread.sleep(16) 約 60 FPS,否則 CPU 100%。

修正版:獨立執行緒 + 正確繪圖

public class New01 {
    public New01() {
        Frame f = new Frame("my app");
        GamePanel mp = new GamePanel();
        f.add(mp); f.setSize(300,300); f.setVisible(true);
        new Thread(mp::gameLoop).start(); // 獨立執行緒
    }
    public static void main(String[] args) { new New01(); }
}

class GamePanel extends Panel implements Runnable {
    int x=50, y=50, diameter=100;
    volatile boolean running = true;

    public void paint(Graphics g) {
        g.setColor(Color.BLUE);
        g.fillOval(x, y, diameter, diameter);
    }

    public void gameLoop() {
        while (running) {
            x++;
            if (x > 300) x = 0; // 邊界回彈
            repaint();
            try { Thread.sleep(16); } catch (InterruptedException e) { break; }
        }
    }
    public void run() { gameLoop(); }
}

進階建議:雙緩衝防閃爍

// GamePanel 成員
private Image offscreen;
private Graphics offgc;

public void update(Graphics g) { // 覆寫 update 避免預設 clearRect
    if (offscreen == null) {
        offscreen = createImage(getWidth(), getHeight());
        offgc = offscreen.getGraphics();
    }
    offgc.setColor(getBackground());
    offgc.fillRect(0, 0, getWidth(), getHeight());
    paint(offgc);
    g.drawImage(offscreen, 0, 0, null);
}

總結

AWT/Swing 動畫必須:① 獨立執行緒跑迴圈,② 呼叫 repaint() 排程重繪,③ Thread.sleep 控制幀率,④ (可選) 雙緩衝消除閃爍。缺一不可。

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