基于Java的動畫編程基礎第二部分
|
畫出每一幀:
剩下的就是將每一幀圖象繪出。在上例中調用了applet的repaint()來繪出每一幀圖象。
| 看圖之王ACDSee 6.0應用大全 | 數碼人像照片矢量化及藝術處理 | |
| 六天學會Visual Basic數據庫編程 | 解析“震蕩波”惡性蠕蟲病毒 | |
| public void paint(Graphics g) { g.setColor(Color.black); g.drawString("Frame " + frame, 0, 30); } |
生成圖形:
現在我們來畫一些稍微困難的東西。下例畫了一個正弦曲線的組合, 對于每一個x,畫一條短的垂直線,所有這些線組成了一個圖形,并且每幀變化。
但不幸有些閃動,在以后我們將解釋為什么閃以及怎樣避免。
| public void paint(Graphics g) { Dimension d = size(); int h = d.height / 2; for (int x = 0 ; x < d.width; x++) { int y1 = (int)((1.0 + Math.sin((x - frame)*0.05))*h); int y2 = (int)((1.0 + math.sin((x + frame)*0.05))*h); g.DrawLine(x, y1, x, y2); } } |
避免閃爍:
上例中的閃爍有兩個原因:繪制每一幀花費的時間太長(因為重繪時要求的計算量大),二是在每次調用pait()前整個背景被清除,當在進行下一幀的計算時,用戶看到的是背景。
清除背景和繪制圖形間的短暫時間被用戶看見,就是閃爍。在有些平臺如PC機上閃爍比在X Window上明顯,這是因為X Window的圖象被緩存過,使得閃爍的時間比較短。
有兩種辦法可以明顯地減弱閃爍:重載update()或使用雙緩沖。
重載update()?
當AWT接收到一個applet的重繪請求時,它就調用applet的update()。
缺省地,update()清除applet的背景,然后調用paint()。重載update(),將以前在paint()中的繪圖代碼包含在update()中,從而避免每次重繪時將整個區域清除。
既然背景不在自動清除,我們需要自己在update()中完成。我們在繪制新的線之前獨自將豎線擦除,完全消除了閃爍。
| public void paint(Graphics g) { update(g); } public void update(Graphics g) { Color bg = getBackground(); Dimension d = size(); int h = d.height / 2; for (int x = 0; x < d.width; x++) { int y1 = (int)((1.0 + Math.sin((x - frame)*0.05))*h); int y2 = (int)((1.0 + Math.sin((x + frame)*0.05))*h); if (y1 > y2) { int t = y1; y1 = y2; y2 = t; } g.setColor(bg); g.drawLine(x, 0, x, y1); g.drawLine(x, y2, x, d.height); g.setColor(Color.black); g.drawLine(x, y1, x, y2); } |