動畫程式骨架

這個主題的動畫程式骨架主要是使用Java程式為範例,使用多執行緒來進行動畫的狀態改變,其它的程式語言其實類似, 最後也補充了不使用多執行緒的版本。

Java的程式骨架

package cc.openhome; 
 
import java.awt.*;
import javax.swing.JApplet;
 
public class AnimationSkeleton extends JApplet implements Runnable { 
    // 定義多執行緒的方法 
    public void run() { 
        // 動畫迴圈 
        while(true) { 

            // 動畫的狀態改變、緩衝區繪圖 

            this.repaint();  // 重繪畫面 

            // 執行緒暫停 50 毫秒 
            try { 
                Thread.sleep(50); // 避免Busy loop
            } 
            catch(InterruptedException e) { 
                    // 例外處理 
            } 
        }  // while結束 
    }  // run()結束 
 
    // 改寫update(),避免畫面不連續 
    public void update(Graphics g) { 
        this.paint(g);  // 單純呼叫paint() 
    } 
 
    public void paint(Graphics g) { 
        super.paint(g);
        // 繪圖動作 
    } 
} 

在這個骨架中,實作Runnable以使用多執行緒進行動畫狀態的改變,在這邊要養成一個習慣:「將動畫狀態的改變與繪 圖兩個工作分開。」這可以讓程式的邏輯更為清楚,雖然不使用多執行緒也可以繪製部份的動畫(例如畫框動畫),但上面這個骨架,在額外進行像是緩衝區繪圖時 相當方便。 

其中改寫update()的部份是為了避免繪圖的閃爍,這是因為Java在呼叫repaint()之後,repaint()會先呼叫 update()清除畫面,而update()預設會使用白色背景清除畫面,然後再繪上使用者指定的背景,這會造成Java在繪圖時的閃爍,改寫 update()直接呼叫paint(),讓它不重繪畫面,讓重繪的動作由您控制,以避免閃爍的發生。

HTML 5 Canvas

<!DOCTYPE html>
<html>
    <head>
        <meta content="text/html; charset=Big5" http-equiv="content-type">
        <script type="text/javascript">
            window.onload = function() {
                var canvas1 = document.getElementById('canvas1');
                
                
                var context = canvas1.getContext('2d');
                
                setTimeout(function() {
                    context.beginPath();
                    context.clearRect(0, 0, canvas1.width, canvas1.height);
                    
                    // 動畫處理、繪圖緩衝區或清除部份區域
                    
                    context.stroke();
                    
                    // 每 20 毫秒重繪
                    setTimeout(arguments.callee, 20);
                    
                }, 20); // 每 20 毫秒重繪
            };
        </script>
    </head>
    <body>       
        <canvas id="canvas1" width="640" height="480"></canvas>
    </body>
</html>

如果使用HTML 5 Canvas,由於JavaScript沒有像Java的Thread.sleep()方法,所以可以改用setInterval()來定時執行,動畫進 行最簡單的方式,就是每次清除上一次的畫面再重新繪製,比較複雜的話,可以使用繪圖緩衝區或清除部份區域。

Turbo C 繪圖模式

#include <graphics.h> 
#include <stdlib.h> 
 
void modify(); // 改變動畫狀態 
void draw();    // 繪圖 
 
int main(void) { 
    // 啟動繪圖模式 
    initgraph(&driver, &mode, "c:\\"); 
 
    // 動畫迴圈 
    while(1) { 
        cleardevice();  // 清除螢幕,不一定需要這個函式 
        draw(); 
        modify(); 
        // 暫停執行 
        sleep(50); // 避免Busy loop    
    } 
 
    // 關閉繪圖模式 
    closegraph(); 
 
    return 0; 
} 
 
void modify() { 
    // 動畫狀態改變 
} 
 
void draw() { 
    // 繪圖 
}  

在Turbo C中,所有的繪圖與狀態改變都是在while迴圈中進行,函式的設計與使用者的互動必須多花一些心思,程式的邏輯性會變得複雜一些。

這個網誌中的熱門文章

【動漫】今年心目中最神漫畫,在千萬年壽命的妖精眼中,人類究竟算什麼呢