Java實現動畫的方式多樣,但基本原理一致:在屏幕上繪製一系列幀(Frame)以產生運動感覺。本文將從構建程序框架入手,逐步擴展功能。
為了每秒多次更新屏幕,必須創建獨立線程實現動畫循環,追蹤當前幀並響應週期性繪圖請求。實現線程有兩種途徑:繼承Thread類或實現Runnable介面。常見錯誤是將動畫循環放入paint()方法,這會佔用主AWT線程,導致繪圖與事件處理阻塞。
public class Animator1 extends java.applet.Applet implements Runnable {
int frame;
int delay;
Thread animator;
public void init() {
String str = getParameter("fps");
int fps = (str != null) ? Integer.parseInt(str) : 10;
delay = (fps > 0) ? (1000 / fps) : 100;
}
public void start() {
animator = new Thread(this);
animator.start();
}
public void run() {
while (Thread.currentThread() == animator) {
repaint();
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
break;
}
frame++;
}
}
public void stop() {
animator = null;
}
}
HTML引用方式:
<applet code=Animator1.class width=200 height=200>
<param name=fps value=200>
</applet>
參數fps表示每秒幀數。
上例中線程在兩幀間固定休眠,但忽略了代碼執行本身耗時,導致實際幀率偏低。改進思路:記錄預期下一幀時間點,動態計算休眠時長。
public void run() {
long tm = System.currentTimeMillis();
while (Thread.currentThread() == animator) {
repaint();
try {
tm += delay;
Thread.sleep(Math.max(0, tm - System.currentTimeMillis()));
} catch (InterruptedException e) {
break;
}
frame++;
}
}
此法能有效抵消執行耗時,使幀率更穩定,是動畫編程的基礎優化技巧。