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

最近研究了一下出來了好久的HTML5,總結了一下,準備來個系列,文中也許有不少問題,歡迎你們指正。javascript

Canvas介紹

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

這裏說些w3school中沒有的。html5

當即模式

canvas元素是當即模式的圖形系統,意味着當你提出要求時,他會當即繪製,而後當即忘記(繪製完成一個對象,就會銷燬這個對象)。其它的圖形系統(例如:SVG),使用了保留模式的圖形系統,就是說繪製時他們會保留一系列將要繪製的對象。正因未Canvas不須要維護這一系列對象,因此Canvas的運行速度要快不少。java

雙緩存機制

在上面,咱們提到了當即模式,但這裏的「當即繪製」並非你們所謂的當即,此處須要進一步說明。編程

在瀏覽器調用咱們定義的繪製方法(假設這個方法是DrawGame)繪製當前動畫幀時,Canvas元素並非當即繪製出你指定的內容。相反,它會建立另外一個Canvas元素(咱們叫它Canvas2),全部的繪製實際上都在Canvas2中進行。當DrawGame方法返回時,瀏覽器會經過一個圖形操做,複製Canvas2內容到屏幕上,咱們將這種技術稱爲雙緩存技術,雙緩存技術讓動畫的實現變得平滑。canvas

座標系統(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大佬,如文中有問題,請你們幫忙指正,謝謝你們~

相關文章
相關標籤/搜索