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

Java 動畫編程基礎(一):線程驅動動畫循環與恆定幀率控制

     編輯:Java 相關知識

動畫核心原理:幀序列產生運動感知

Java 實現動畫的基本原理統一:在屏幕上高頻繁繪製一系列幀,利用視覺暫留效應產生運動感覺。關鍵在於如何控制幀的產生節奏。

基礎框架:獨立動畫線程

錯誤示範: 將動畫循環寫在 paint() 中 → 佔用 AWT 事件分發線程(EDT),導致界面卡死、無法響應用戶交互。
正確做法: 創建獨立線程運行動畫循環,定期調用 repaint() 請求重繪。

實現 Runnable 接口的標準 Applet 骨架

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; // 默認 100ms = 10fps
    }

    public void start() {
        animator = new Thread(this);
        animator.start();
    }

    public void run() {
        // 關鍵:只有當前線程仍是 animator 時才繼續循環
        while (Thread.currentThread() == animator) {
            repaint(); // 請求 AWT 重繪
            try {
                Thread.sleep(delay); // 固定間隔休眠
            } catch (InterruptedException e) {
                break; // 被中斷則退出循環
            }
            frame++;
        }
    }

    public void stop() {
        animator = null; // 釋放線程引用,run() 循環條件失效,線程自然結束
    }
}

HTML 引用:

<applet code=Animator1.class width=200 height=200>
    <param name=fps value=20> <!-- 目標 20 FPS -->
</applet>

痛點:固定 sleep 無法保證恆定幀率

Thread.sleep(delay) 只保證「至少睡 delay 毫秒」,但不包含繪圖邏輯本身的耗時。若繪圖耗時 20ms,sleep 100ms,實際幀間隔 120ms → 實際幀率約 8.3 FPS,遠低於目標 10 FPS。隨著繪圖複雜度波動,幀率極不穩定。

改進:基於時間基準的自適應睡眠

記錄「下一幀理論開始時間」,每幀動態計算剩餘睡眠時間:

public void run() {
    long tm = System.currentTimeMillis(); // 基準時間
    while (Thread.currentThread() == animator) {
        repaint();
        try {
            tm += delay; // 下一幀理論時間點
            long sleepTime = tm - System.currentTimeMillis();
            if (sleepTime > 0) Thread.sleep(sleepTime); // 僅補足差值
            // 若 sleepTime <= 0,說明繪圖超時,立即進入下一幀(不睡眠)
        } catch (InterruptedException e) {
            break;
        }
        frame++;
    }
}

優勢:

  • 自動吸收繪圖耗時波動,幀率極其穩定。
  • 若繪圖長期超時(sleepTime ≤ 0),說明性能不足,需優化繪圖邏輯或降低目標 FPS。

關鍵設計模式總結

  1. 分離關注點:動畫循環線程只負責節奏控制,繪圖邏輯在 paint() / update() 中。
  2. 線程生命周期綁定 Applet:start() 啟動,stop() 通過置空引用優雅停止,避免 Thread.stop() 等棄用方法。
  3. 時間基準校正:使用絕對時間點而非相對睡眠,實現恆定幀率。

這套「線程驅動 + 時間基準校正」模式,不僅適用於 Applet,也是 Swing/JavaFX 遊戲循環、實時渲染引擎的基石思想。

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