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(); /* 缺少延遲 */ }
}
}
mp.gameLoop()。while(true) 在事件派發執行緒 (EDT) 跑死迴圈,導致 repaint() 排程的 paint() 永無機會執行,畫面凍結。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 控制幀率,④ (可選) 雙緩衝消除閃爍。缺一不可。