Html5游戲開發-圖形與動畫(一)


最近研究了一下出來了很久的HTML5,總結了一下,准備來個系列,文中也許有很多問題,歡迎大家指正。

Canvas介紹

canvas用於在網頁中繪制圖形的一個元素,具體內容請查看 -> HTML5 Canvas

這里說些w3school中沒有的。

立即模式

canvas元素是立即模式的圖形系統,意味着當你提出要求時,他會立即繪制,然后立即忘記(繪制完成一個對象,就會銷毀這個對象)。其它的圖形系統(例如:SVG),使用了保留模式的圖形系統,就是說繪制時他們會保留一系列將要繪制的對象。正因未Canvas不需要維護這一系列對象,所以Canvas的運行速度要快很多。

雙緩存機制

在上面,我們提到了立即模式,但這里的“立即繪制”並不是大家所謂的立即,此處需要進一步說明。

在瀏覽器調用我們定義的繪制方法(假設這個方法是DrawGame)繪制當前動畫幀時,Canvas元素並不是立即繪制出你指定的內容。相反,它會創建另一個Canvas元素(我們叫它Canvas2),所有的繪制實際上都在Canvas2中進行。當DrawGame方法返回時,瀏覽器會通過一個圖形操作,復制Canvas2內容到屏幕上,我們將這種技術稱為雙緩存技術,雙緩存技術讓動畫的實現變得平滑。

坐標系統(translate)

translate(x,y)這是Canvas元素的一個方法,游戲的背景移動,大多通過該方法來實現。游戲中,我們不會通過頻繁對大量元素進行坐標計算來實現對象的滾動,因為這樣的計算不僅消耗計算機性能,還增加了代碼的維護難度。

注意:為了不影響后續的繪制,在使用translate(x,y)修改坐標系統后,需要再次調用translate(-x,-y)來恢復坐標系統。

具體內容請查看 -> HTML5 canvas translate()

創建Canvas鏡像和恢復Canvas

在進行動畫繪制時,我們會經常的對Canvas元素的繪圖環境(context)進行修改,例如strokeStyle,lineWidth等。這些修改操作都是永久的,也就意味着對他們的修改將會影響接下來任何你在Canvas元素的圖形操作。那么如何讓這些操作只是臨時有效呢?這里我們可以使用save()和restore()方法對當前Canvas元素的繪圖環境狀態創建鏡像和恢復。任何寫在這兩個方法間的環境屬性修改,在執行restore后,都會恢復成save時的狀態。

注意:save()和restore()需要成對出現,也就是有save,就要有restore。

 

實現平滑的HTML5動畫

所謂的動畫,說白了就是一張一張的圖片不斷的連續更換。所以,通過編程實現動畫也就是不斷的通過替換圖片,來達到動畫的效果。

但是,這種不斷地替換,當然不能使用死循環while(true)來實現,傳統的方法是使用setTimeout()和setInterval()方法,這兩個方法雖然都提供了毫秒級的精確度,但實際上,卻達不到毫秒級(參考此處:setTimeout精度測試setInterval精度測試)。所以為了保證動畫的平滑度,我們不應該繼續使用setTimeout和setInterval方法來實現對時間有着苛刻要求的動畫,用什么來代替?我們在下一節講到。

requestAnimationFrame()方法

在w3c中的Timing Control for Script-based Animations(參考此處 -> w3c-Script-based Animations)說明中,定義了一個requestAnimationFrame()窗口對象的方法。不同於setTimeout和setInterval方法,requestAnimationFrame是專門用來實現動畫的,它使用瀏覽器的時間間隔進行繪制,不會掉幀。

這里需要注意的是,requestAnimationFrame方法在窗體沒激活或者頁簽不可見的時候,動畫會暫停。

下面是盜的圖,支持requestAnimationFrame方法的瀏覽器及版本(來源:HTML5 requestAnimationFrame( ) 動畫API

javascript實例:

1 function animate(now)
2 {
3     DrawGame(now);
4     requestAnimationFrame(animate);
5 }
6 ...
7 requestAnimationFrame(animate);

 

制作基於時間的運動

游戲幀速率是不穩定的,也許此時能夠60幀/秒,下一刻也許就成了10幀/秒。游戲幀的速率是變化的,我們不能讓游戲幀的速率影像到游戲中物體運動的速率,例如:人物的運動,背景的滾動,子彈的速度等等。所以,游戲中物體的運動必須是基於時間的,並且僅僅依賴於時間(例如:像素/秒),而不是動畫幀速率。

在上一節的實例中,我們可以發現animate有個參數是now,它代表當前繪制的時間,既然有了這個參數,我們就能知道兩次時間間隔,從而計算出運動的距離。

javascript實例:

1 var speed = 50;
2 var lastAnimationTime = new Date();
3 var offsetX = 0;
4 function SetBackgroundOffsetX(now)
5 {
6     offsetX += speed * (now - lastAnimationTime)/1000
7     ...
8     //如果一直加下去,背景會慢慢移出屏幕,下面的代碼自己寫吧
9 }

 

結尾

到這里,關於圖形與動畫的內容就差不多結束了,內容不多,代碼很少,但是我覺得已經夠了,畢竟大部分的基礎知識都能在網上找到哈哈。

本人不是HTML5大佬,如文中有問題,請大家幫忙指正,謝謝大家~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM