From Gossip@caterpillar

Computer Graphics: 動畫程式骨架

 

 


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

Java的程式骨架

package onlyfun.caterpillar.graphics.animation; 

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);
}
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(),讓它不重繪畫面,讓重繪的動作由您控制,以避免閃爍的發生。

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);
}

// 關閉繪圖模式
closegraph();

return 0;
}

void modify() {
// 動畫狀態改變
}

void draw() {
// 繪圖
}

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