適時在複雜的向量內容使用點陣圖快取功能。
使用點陣圖快取功能即可達到最佳化。這項功能會快取向量物件,在內部將它顯示為點陣圖,並且使用該點陣圖進行顯示。結果會大幅改善顯示效能,但是它可能需要大量的記憶體。在複雜的向量內容 (例如複雜的漸層或文字) 使用點陣圖快取功能。
在包含複雜向量圖形 (例如文字或漸層) 的動畫物件開啟點陣圖快取功能以改善效能。不過,如果在顯示物件 (例如具有播放時間軸的影片片段) 上啟用點陣圖快取,會得到相反的結果。在每個影格上,執行階段必須升級快取的點陣圖,然後在螢幕上重新繪製它,這可能需要許多 CPU 週期。點陣圖快取功能只對於產生一次、不需更新就能使用的快取點陣圖才有好處。
如果您為 Sprite 物件開啟點陣圖快取,該物件便可在不需要執行階段重新產生快取點陣圖的情況下移動。變更物件的
x
和
y
屬性不會導致重新產生快取的點陣圖。但是,對物件進行旋轉、縮放或變更 Alpha 值則會導致執行階段重新產生快取的點陣圖,進而影響效能。
備註:
但 AIR 與 Packager for iPhone 中的
DisplayObject.cacheAsBitmapMatrix
屬性則無此限制。透過使用
cacheAsBitmapMatrix
屬性,即可旋轉、縮放、傾斜和變更顯示物件的 Alpha 值,而不必觸發點陣圖重新產生。
快取的點陣圖所使用的記憶體,可能比一般影片片段實體還多。例如,如果在「舞台」上的影片片段為 250 x 250 像素,當快取它時,會使用大約 250 KB,而不是未快取的 1 KB。
下列範例涉及包含蘋果影像的 Sprite 物件。下列類別會附加到 apple 元件:
package org.bytearray.bitmap
{
import flash.display.Sprite;
import flash.events.Event;
public class Apple extends Sprite
{
private var destinationX:Number;
private var destinationY:Number;
public function Apple ()
{
addEventListener(Event.ADDED_TO_STAGE,activation);
addEventListener(Event.REMOVED_FROM_STAGE,deactivation);
}
private function activation(e:Event):void
{
initPos();
addEventListener (Event.ENTER_FRAME,handleMovement);
}
private function deactivation(e:Event):void
{
removeEventListener(Event.ENTER_FRAME,handleMovement);
}
private function initPos():void
{
destinationX = Math.random()*(stage.stageWidth - (width>>1));
destinationY = Math.random()*(stage.stageHeight - (height>>1));
}
private function handleMovement(e:Event):void
{
x -= (x - destinationX)*.5;
y -= (y - destinationY)*.5;
if (Math.abs(x - destinationX) < 1 && Math.abs(y - destinationY) < 1)
initPos();
}
}
}
程式碼會使用 Sprite 類別,而非 MovieClip 類別,因為並非每個蘋果都需要時間軸。為了獲得最佳的效能,請盡可能使用輕量型物件。接下來,會使用下列程式碼將類別實體化:
import org.bytearray.bitmap.Apple;
stage.addEventListener(MouseEvent.CLICK,createApples);
stage.addEventListener(KeyboardEvent.KEY_DOWN,cacheApples);
const MAX_NUM:int = 100;
var apple:Apple;
var holder:Sprite = new Sprite();
addChild(holder);
function createApples(e:MouseEvent):void
{
for (var i:int = 0; i< MAX_NUM; i++)
{
apple = new Apple();
holder.addChild(apple);
}
}
function cacheApples(e:KeyboardEvent):void
{
if (e.keyCode == 67)
{
var lng:int = holder.numChildren;
for (var i:int = 0; i < lng; i++)
{
apple = holder.getChildAt (i) as Apple;
apple.cacheAsBitmap = Boolean(!apple.cacheAsBitmap);
}
}
}
當使用者按一下滑鼠時,會建立蘋果而不會進行快取。當使用者按 C 鍵時 (按鍵碼 67),會將蘋果向量快取為點陣圖,並顯示在螢幕上。此技術可在 CPU 變慢時,大幅改善桌上型電腦與行動裝置上的顯示效能。
不過,雖然使用點陣圖快取功能可改善顯示效能,它有可能會快速地耗用大量的記憶體。只要一快取物件,就會將其表面擷取為透明的點陣圖並儲存在記憶體中,如下圖所示:
儲存在記憶體中的物件及其表面點陣圖
Flash Player 10.1 與 AIR 2.5 採用
濾鏡與動態點陣圖取消載入
中所述的相同方法來最佳化記憶體的使用方式。如果快取的顯示物件是隱藏的或在螢幕外,其點陣圖只要一段時間沒有使用就會從記憶體釋出。
備註:
如果顯示物件的
opaqueBackground
屬性設定為特定顏色,則執行階段會將顯示物件視為不透明。當與
cacheAsBitmap
屬性搭配使用時,執行階段會在記憶體中建立不透明的 32 位元點陣圖。Alpha 色版會設定為 0xFF 以改善效能,因為在螢幕上繪製點陣圖不需要透明效果。避免使用 Alpha 混合效果可加快顯示速度。如果目前的螢幕深度限制為 16 位元,則記憶體中的點陣圖將儲存為 16 位元影像。使用
opaqueBackground
屬性不會以隱含方式啟用點陣圖快取。
若要節省記憶體,請使用
cacheAsBitmap
屬性,並在每個顯示物件 (而非容器) 上啟用它。在容器上啟用點陣圖快取會讓記憶體中的最終點陣圖變大,這是為了建立尺寸為 211 x 279 像素的透明點陣圖。此影像使用大約 229 KB 的記憶體:
在容器上啟用點陣圖快取
此外,快取容器時如果有任何蘋果開始在影格上移動,您將面臨可能在記憶體中更新整個點陣圖的風險。在個別實體上啟用點陣圖快取,會在記憶體中快取六個 7 KB 的表面,這樣只會使用 42 KB 的記憶體:
從顯示清單存取每個蘋果實體並呼叫
getChildAt()
方法,會將參考儲存在 Vector 物件中以便快速存取:
import org.bytearray.bitmap.Apple;
stage.addEventListener(KeyboardEvent.KEY_DOWN, cacheApples);
const MAX_NUM:int = 200;
var apple:Apple;
var holder:Sprite = new Sprite();
addChild(holder);
var holderVector:Vector.<Apple> = new Vector.<Apple>(MAX_NUM, true);
for (var i:int = 0; i< MAX_NUM; i++)
{
apple = new Apple();
holder.addChild(apple);
holderVector[i] = apple;
}
function cacheApples(e:KeyboardEvent):void
{
if (e.keyCode == 67)
{
var lng:int = holderVector.length
for (var i:int = 0; i < lng; i++)
{
apple = holderVector[i];
apple.cacheAsBitmap = Boolean(!apple.cacheAsBitmap);
}
}
}
請記住,如果不在每個影格上旋轉、縮放或變更快取的內容,則點陣圖快取可改進顯示效能。不過,對不是在 X 與 Y 軸上轉移的任何變形而言,並不會改善顯示效能。在這些情況下,Flash Player 會更新顯示物件上每個變形的快取點陣圖副本。更新快取副本可能會導致高 CPU 使用率、效能變慢以及高電池用量。但 AIR 或 Packager for iPhone 中的
cacheAsBitmapMatrix
屬性則無此限制。
下列程式碼會變更移動方法中的 Alpha 值,它會變更每個影格上蘋果的不透明度:
private function handleMovement(e:Event):void
{
alpha = Math.random();
x -= (x - destinationX)*.5;
y -= (y - destinationY)*.5;
if (Math.abs(x - destinationX) < 1 && Math.abs(y - destinationY) < 1)
initPos();
}
使用點陣圖快取會造成效能變慢。變更 Alpha 值會讓執行階段在每當修改 Alpha 值時,強制更新記憶體中快取的點陣圖。
使用濾鏡時必須有點陣圖,而這些點陣圖會在每次快取影片片段播放磁頭移動時隨之更新。因此,使用濾鏡會自動將
cacheAsBitmap
屬性設定為
true
。下圖說明動畫影片片段:
動畫影片片段
避免在動畫內容上使用濾鏡,因為它可能會造成效能問題。在下圖中,設計師加入投影濾鏡:
套用投影濾鏡的動畫影片片段
其結果是,如果播放影片片段中的時間軸,就必須重新產生點陣圖。如果內容不是以簡單 x 或 y 變形的方式進行修改,也必須重新產生點陣圖。每個影格都會強制執行階段重新繪製點陣圖,這將需要更多的 CPU 資源、造成效能變差,以及耗用更多的電池壽命。
在下列訓練影片中,Paul Trani 針對使用 Flash Professional 與 ActionScript 提供的範例會使用點陣圖最佳化圖形: