快速動畫是指每隔一段很小的時間間隔就快速擦去原有畫面,并重新畫上新的畫面的動畫技術。快速動畫成功的關鍵就在于擦去和重畫的速度必須很快,否則畫面就會有閃爍現象。
在VB中制作快速動畫比較簡單,只要把窗體的AutoRedraw屬性設置為true,再直接調用API函數BitBlt,畫完一幀Refresh一次。但C++Builder的窗體沒有AutoRedraw屬性,只要一使用BitBlt,窗體就會自動刷新,由于一幀畫面往往要幾次用到BitBlt,畫面就閃爍起來了。解決的辦法就是自己定義一個不可見的緩沖區,其大小應與目標窗體相同,先在緩沖區上把一幀的畫面畫完,再用一次BitBlt函數把緩沖區的圖案貼到窗體上。請看例子:
//在TForm1 *Form1;的后面添上這三句
Graphics::Tbitmap *p;
Graphics::Tbitmap *q;
int xx=0;
//---------------------
void __fastcall TForm1::FormCreate(Tobject *Sender)
{
p=new Graphics::Tbitmap;//這存放的就是要貼到窗體上的小圖案
p->Handle=LoadBitmap(Hinstance,″aaa″);//從資源文件中載入小圖案
q=new Graphics::Tbitmap;//定義緩沖區q
q->Width=Width;//使緩沖區的大小與窗體相同
q->Height=Height;
PatBlt(q->Canvas->Handle,0,0,q->Width,q->Height,0);//把緩沖區的背景變為黑色
}
//--------------------
void __fastcall TForm1::FormDestroy(Tobject *Sender)
{
//程序結束時釋放內存
delete p;
delete q;
}
//--------------------
void __fastcall TForm1::Timer1Timer(Tobject *Sender)
{
//窗體上要加上一個Timer控件
xx+=2;
PatBlt(q->Canvas->Handle,0,0,Width,Height,0);//把緩沖區的背景變為黑色,同時擦去了舊的畫面
BitBlt(q->Canvas->Handle,xx,0,p->Width,p->Height,p->Canvas->Handle,0,0,SRCCOPY);
/t//正在緩沖區上制作一幀的畫面,這幾句是不可見的
BitBlt(q->Canvas->Handle,xx,50,p->Width,p->Height,p->Canvas->Handle,0,0,SRCCOPY);
BitBlt(q->Canvas->Handle,xx,100,p->Width,p->Height,p->Canvas->Handle,0,0,SRCCOPY);
BitBlt(q->Canvas->Handle,xx,150,p->Width,p->Height,p->Canvas->Handle,0,0,SRCCOPY);
BitBlt(q->Canvas->Handle,xx,200,p->Width,p->Height,p->Canvas->Handle,0,0,SRCCOPY);
BitBlt(q->Canvas->Handle,xx,250,p->Width,p->Height,p->Canvas->Handle,0,0,SRCCOPY);
BitBlt(q->Canvas->Handle,xx,300,p->Width,p->Height,p->Canvas->Handle,0,0,SRCCOPY);
BitBlt(Canvas->Handle,0,0,Width,Height,q->Canvas->Handle,0,0,SRCCOPY);
/t//把緩沖區的畫面貼到窗體上
}
如果實際應用時,像上面的程序那樣,把畫動畫的語句放在Timer控件的OnTimer事件中,就可能會有一個小問題。如果用戶暫停了動畫,窗體又正
好產生了重畫事件(比如窗體被最小化后又被恢復),那窗體上的畫面就會消失。這是因為窗體被重畫時,只畫了窗體的通用部分,Windows并不知道原
來的窗體上有自定義的畫面。要想讓Windows把畫面恢復原樣,必須把畫動畫的語句放在窗體的OnPaint事件中,Timer控件的OnTimer事件中只寫決定
圖案位置的語句(如本例中的xx+=2;)和一句RePaint。修改后具體的程序我就省略了,請大家自己完成吧,愿大家都做出令自己滿意的精彩動畫。