2016-04-27 76 views
0

似乎有一些關於這從博客到博客,視頻到論壇到論壇的不同意見。這是專門針對畫布標籤的2D上下文,而不是WebGL。我知道WebGL會給我更好的表現,但我的目標是瞭解canvas標籤在2D上下文中的工作方式。帆布遊戲開發和表現

我聽說在「虛擬」的屏幕外畫布中預先渲染對象可能是最好的表現,這有助於看到瀏覽器不會真正地繪製它。然後,人們說使用「getImageData」從該畫布中獲取數據,根據我的理解,該數據返回base64代碼,您可以將其應用於使用「putImageData」添加到DOM的畫布。這不會是一個巨大的性能打擊?

我應該在這個虛擬畫布上渲染遊戲的整個視圖,然後在循環內部使用此方法將其顯示爲可見視圖?

回答

1

是的,你可以。我建議在遊戲循環的draw()部分中使用requestAnimationFrame(),將所有單獨的對象繪製到屏幕外Canavs上,然後將圖像放到可見的畫布上。雖然這看起來可能會影響性能,但是當您繪製了很多對象時,get/put圖像的這種開銷實際上可以忽略不計。

+0

所以你說的是,如果我製作類似RPG和一些不同的瓷磚,我應該將它們全部渲染到屏幕外的畫布上,然後從該畫布獲取數據並將它們放到可見區域? –

+1

是的:)畫布上放置的每個圖塊都有一個小的開銷,因此當您在屏幕外緩衝區上繪圖時,它更快,因爲它不需要繪製到內存和屏幕上,它只是將其存儲到內存中。 –

+0

多個畫布會對遊戲開發更有益嗎?一個用於瓷磚,一個用於我的主要角色,例如? –

2

畫布只是一個圖像,從我的經驗來看,使用畫布或圖像在性能方面沒有區別。

離線或在畫布上沒有什麼不同,他們都會盡可能利用GPU。

使用context.getImageData()context.createImageData()context.putImageData()應避免實時渲染,它並不需要GPU和你做它將在主內存的Javascript進行任何處理的優勢。雖然數據存儲在一個類型數組Uint8ClampedArray中,並且可以轉換爲任何類型的類型數組,例如Uint32Array,允許您使用一個變量處理單個像素,而不是4.還有許多用於類型化數組的原生函數,提供比標準Javascript數組更快的數組操作。

圖像的限制因素(包括畫布作爲圖像)是可用GPU RAM的數量,當超過可用RAM的數量時,瀏覽器將根據需要開始將圖像交換到GPU RAM中,阻礙了GPU的渲染能力,與正常的RAM訪問相比,從主RAM到GPU RAM的傳輸速度較慢。發生這種情況時,您將立即看到幀速率的損失。由於瀏覽器可以運行的平臺種類繁多,並且無法瞭解機器功能,所以在發佈實時應用程序時應該小心。

如果您已經爲高端桌面機器編寫了高分辨率圖像的遊戲,它在平板電腦和低端筆記本電腦上表現不佳。爲了緩解這個問題,下載圖像以匹配屏幕分辨率。在1/8分辨率的設備上使用招聘背景圖片會給硬件帶來不適當的壓力。設備是用來處理屏幕的分辨率的,經過這個分辨率會產生很大的不必要的性能影響。這是您可以使用屏幕外畫布以設備原始分辨率呈現圖像,然後轉儲原始人員圖像的位置。質量不會有任何損失,但性能會有很大的提高,從而將無法播放的東西變成可播放的東西。這適用於所有圖形資源。切勿以高於所用設備的分辨率存儲和使用圖像。

由於您可以使用畫布進行多種操作,因此找出最佳運行方式的最佳方法就是進行實驗。監視幀速率並嘗試不同的方法解決問題。如果幀速率提高,你已經找到了一個更好的做事方式,如果幀速率下降,那麼你使用了錯誤的方法。

+0

這幾乎違背了大多數人在網上發表的言論。我認爲這是有益的唯一方法是使用不移動的地圖。一旦角色到達屏幕邊緣,就會進入下一個角色。另外,您在帖子中提出的聲明的參考位置在哪裏? –

+0

@CalebPrenger我不需要保護,任何擁有瀏覽器和一點時間的人都可以測試畫布的性能。只需加載圖像,創建畫布並渲染它們。看看你可以渲染多少幀速率下降,這就是你將如何找到什麼有效,什麼沒有。現實情況是,大多數畫布性能問題與畫布無關,這是糟糕的JavaScript編碼實踐,直到性能問題纔會變得明顯,那麼畫布就會受到指責。 – Blindman67

+0

我不認爲你理解多個畫布的重點。一個是背景,大多數情況下我不需要重畫。上面那個將是我的精靈,我需要重繪。我不會重繪整個畫布,儘管我只會重繪我的角色以前所在的部分。當然,在循環中使用getImageData和putImageData畫布會讓遊戲停滯不前。這不是我所能理解的。 –