2015-06-14 106 views
0

我必須模擬一些對象的運動,所以我創建了一個SurfaceView,並在其上使用專用線程繪製它們。每一個循環我調用canvas.drawColor()來清理所有以前的對象的位置並繪製新的狀態。一切工作正常,幀率是體面的。在SurfaceView上繪製對象的路徑

問題是:如果我想繪製物體軌跡的痕跡?在這種情況下,我必須記住每個對象的位置,並且在每個循環中繪製所有過去的數百個點的位置。這個任務保持幀率更低,在我看來,唯一的辦法就是每次重繪同樣的點時,這似乎是荒謬的!有一種方法可以在畫布上繪製點,而不是使用每個循環的canvas.drawColor()來取消它們(這對於其他任務是必需的)?

回答

1

排序

SurfaceView的Surface使用多個緩衝區。如果它是雙緩衝的,並且每幀沒有清除屏幕,那麼您將在一個緩衝區中顯示所有奇數幀,而在另一個緩衝區中顯示所有奇數幀。每當你畫一個新的框架,它會翻轉到另一個緩衝區,你的一半位置將消失(看起來像一切都在振動)。

您可以在每個框架上繪製每個對象的當前位置和其前一個位置。這樣,兩個框架都可以獲得每個對象的位置。

這個想法的實際問題是你不知道Surface有多少緩衝區正在使用。如果它是三重緩衝的(這是非常可能的),那麼你需要繪製當前,前一個和前一個前一個位置,以確保每個緩衝區都具有每個位置。理論上可能有更多數量的緩衝區,但不太可能。儘管如此,你並不想追求這種方法,原因很簡單:當你鎖定畫布時,你同意修改髒區域中的每個像素。如果你不這樣做,結果是不可預測的,並且你的應用程序可能會在未來的操作系統版本中被打亂。

做你想做的事情的最好方法是繪製一個屏幕外的位圖,然後將整個事物塗抹到Surface上。首先,這是一個巨大的浪費,因爲您只是爲了幾個對象而複製一個屏幕大小的位圖,但很快縮減的繪製調用就會開始取勝。

創建一個與Surface大小相同的位圖,然後使用constructor that takes a Bitmap創建一個Canvas。通過這個畫布做所有的繪畫。當你想更新屏幕時,在SurfaceView的畫布上使用drawBitmap()方法。

由於性能成本的原因,我建議不要使用軟件縮放 - 確保您正在進行1:1的複製。您可以使用SurfaceView表面上的setFixedSize()調用使其成爲特定大小(如果有幫助的話) - 對於像素密度較大的設備,它可以提高幀速率並減少電池使用量(blog post here)。