W celu zwiększenia wydajności renderowania tekstu należy użyć buforowania bitmapy i właściwości
opaqueBackground
.
Mechanizm Flash Text Engine oferuje pewnie znaczące optymalizacje. Jednak do wyświetlenia pojedynczego wiersza tekstu użyć trzeba wielu różnych klas. Dlatego do utworzenia edytowalnego pola tekstowego za pomocą klasy TextLine wymagana jest duża ilość pamięci i wiele wierszy kodu ActionScript. Klasa TextLine najlepiej nadaje się do obsługi statycznego tekstu niedostępnego do edycji — zapewnia wówczas szybsze renderowanie i wymaga mniejszej ilości pamięci.
Funkcja buforowania bitmapy umożliwia buforowanie treści wektorowych jako bitmap w celu zwiększenia wydajności renderowania. Ta funkcja jest użyteczna w przypadku złożonych treści wektorowych, a także gdy jest używana z tekstem, którego renderowanie wymaga przetwarzania.
Poniższy przykład przedstawia, w jaki sposób można wykorzystać funkcję buforowania bitmapy i właściwość
opaqueBackground
do przyspieszenia renderingu. Poniższy rysunek przedstawia typowy ekran powitalny, który może zostać wyświetlony, gdy użytkownik oczekuje na załadowanie treści:
Poniższy rysunek ilustruje programową zmianę dynamiki zastosowaną do obiektu TextField. Tekst jest powoli, niejednostajnie przemieszczany od góry do środka sceny:
Poniższy kod generuje efekt dynamicznego niejednostajnego ruchu tekstu. Zmienna
preloader
zawiera bieżący obiekt docelowy, co ogranicza wyszukiwanie właściwości, które może znacznie zmniejszać wydajność:
wait_mc.addEventListener( Event.ENTER_FRAME, movePosition );
var destX:Number=stage.stageWidth/2;
var destY:Number=stage.stageHeight/2;
var preloader:DisplayObject;
function movePosition( e:Event ):void
{
preloader = e.currentTarget as DisplayObject;
preloader.x -= ( preloader.x - destX ) * .1;
preloader.y -= ( preloader.y - destY ) * .1;
if (Math.abs(preloader.y-destY)<1)
preloader.removeEventListener( Event.ENTER_FRAME, movePosition );
}
Funkcja
Math.abs()
może zostać umieszczona w tym miejscu kodu w celu zmniejszenia liczby wywołań funkcji i dodatkowego zwiększenia wydajności. Dobrą praktyką jest zastosowanie typu int dla właściwości
destX
i
destY
, dzięki czemu dostępne będą wartości stałopozycyjne. Stosowanie typu int umożliwia uzyskanie idealnego przyciągania do pikseli bez konieczności ręcznego zaokrąglania wartości za pomocą powolnych metod, takich jak
Math.ceil()
i
Math.round()
. Ten kod nie zaokrągla współrzędnych do int, ponieważ ciągłe zaokrąglanie wartości powoduje, że obiekt nie porusza się płynnie. Ruchy obiektu mogą być drżące, ponieważ współrzędne są przyciągane do najbliższych zaokrąglonych liczb całkowitych w każdej klatce. Jednak ta technika może być użyteczna w przypadku ustawiania końcowego położenia obiektu wyświetlanego. Nie należy stosować poniższego kodu:
// Do not use this code
var destX:Number = Math.round ( stage.stageWidth / 2 );
var destY:Number = Math.round ( stage.stageHeight / 2);
Poniższy kod działa znacznie szybciej:
var destX:int = stage.stageWidth / 2;
var destY:int = stage.stageHeight / 2;
Poprzedni kod można dodatkowo zoptymalizować poprzez użycie operatorów bitowych do dzielenia wartości:
var destX:int = stage.stageWidth >> 1;
var destY:int = stage.stageHeight >> 1;
Funkcja buforowania bitmapy ułatwia środowisku wykonawczemu renderowanie obiektów przez stosowanie dynamicznych bitmap. W bieżącym przykładzie zilustrowano buforowanie klipu filmowego zawierającego obiekt TextField:
wait_mc.cacheAsBitmap = true;
Dodatkowym sposobem na zwiększenie wydajności jest usunięcie przezroczystości (alfa). Przezroczystość alfa wymaga dodatkowych obliczeń w środowisku wykonawczym podczas rysowania obrazów przezroczystych bitmap, co zademonstrowano w poprzednim przykładowym kodzie. Korzystając z właściwości
opaqueBackground
, można pominąć rysowanie poprzez określenie koloru jako tła.
W przypadku korzystania z właściwości
opaqueBackground
powierzchnia bitmapy utworzona w pamięci nadal wykorzystuje 32 bity. Jednak przesunięcie wartości alfa jest ustawione na 255 i nie jest wykorzystywana przezroczystość. W rezultacie właściwość
opaqueBackground
nie zmniejsza obciążenia pamięci, ale zwiększa wydajność renderowania w przypadku korzystania z buforowania bitmapy. W poniższym kodzie zastosowano wszystkie techniki optymalizacji:
wait_mc.addEventListener( Event.ENTER_FRAME, movePosition );
wait_mc.cacheAsBitmap = true;
// Set the background to the color of the scene background
wait_mc.opaqueBackground = 0x8AD6FD;
var destX:int = stage.stageWidth >> 1;
var destY:int = stage.stageHeight >> 1;
var preloader:DisplayObject;
function movePosition ( e:Event ):void
{
preloader = e.currentTarget as DisplayObject;
preloader.x -= ( preloader.x - destX ) * .1;
preloader.y -= ( preloader.y - destY ) * .1;
if ( Math.abs ( preloader.y - destY ) < 1 )
e.currentTarget.removeEventListener ( Event.ENTER_FRAME, movePosition );
}
Zoptymalizowano animację i buforowanie bitmapy poprzez usunięcie przezroczystości. Rozważmy zmianę jakości stołu montażowego na
LOW
i
HIGH
na urządzeniach przenośnych, w różnych stanach animacji i podczas korzystania z funkcji buforowania bitmapy:
wait_mc.addEventListener( Event.ENTER_FRAME, movePosition );
wait_mc.cacheAsBitmap = true;
wait_mc.opaqueBackground = 0x8AD6FD;
// Switch to low quality
stage.quality = StageQuality.LOW;
var destX:int = stage.stageWidth>>1;
var destY:int = stage.stageHeight>>1;
var preloader:DisplayObject;
function movePosition( e:Event ):void
{
preloader = e.currentTarget as DisplayObject;
preloader.x -= ( preloader.x - destX ) * .1;
preloader.y -= ( preloader.y - destY ) * .1;
if (Math.abs(e.currentTarget.y-destY)<1)
{
// Switch back to high quality
stage.quality = StageQuality.HIGH;
preloader.removeEventListener( Event.ENTER_FRAME, movePosition );
}
}
W tym przypadku zmiana jakości stołu montażowego zmusza środowisko wykonawcze do ponownego wygenerowania bitmapy powierzchni obiektu TextField w celu zapewnienia jej zgodności z aktualną jakością obiektu Stage (stołu montażowego). Z tego powodu zmiana jakości stołu montażowego nie jest zalecana, gdy używana jest funkcja buforowania bitmapy.
W tym przypadku możliwe jest także zastosowanie ręcznego buforowania bitmapy. W celu zasymulowania działania właściwości
opaqueBackground
klip filmowy można rysować w nieprzezroczystym obiekcie BitmapData, przez co środowisko wykonawcze nie będzie musiało ponownie generować bitmapy powierzchni.
Ta technika przynosi dobre rezultaty, pod warunkiem że treść nie ulega zmianie w miarę upływu czasu. Jeśli jednak treść pola tekstowego może ulec zmianie, należy rozważyć zastosowanie innej strategii. Wyobraźmy sobie na przykład pole tekstowe, w którym ciągle zmieniana jest wartość procentowa obrazująca postęp ładowania aplikacji. Jeśli to pole tekstowe (lub zawierający je obiekt wyświetlany) zostało zbuforowane jako bitmapa, jego powierzchnia musi zostać wygenerowana przy każdej zmianie zawartości pola. Nie można zastosować ręcznego buforowania bitmapy, ponieważ zawartość obiektu wyświetlanego nieustannie się zmienia. Zmiana tej stałej mogłaby wymusić ręczne wywołanie metody
BitmapData.draw()
w celu zaktualizowania buforowanej bitmapy.
Należy pamiętać o tym, że począwszy od programu Flash Player 8 (i środowiska AIR 1.0) — bez względu na jakość stołu montażowego — pole tekstowe z opcją renderowania Wygładź dla czytelności pozostaje idealnie wygładzone. Takie rozwiązanie zmniejsza zużycie pamięci, ale powoduje większe obciążenie procesora, a rendering przebiega nieznacznie wolniej niż w przypadku funkcji buforowania bitmapy.
W poniższym kodzie zastosowano takie rozwiązanie:
wait_mc.addEventListener( Event.ENTER_FRAME, movePosition );
// Switch to low quality
stage.quality = StageQuality.LOW;
var destX:int = stage.stageWidth >> 1;
var destY:int = stage.stageHeight >> 1;
var preloader:DisplayObject;
function movePosition ( e:Event ):void
{
preloader = e.currentTarget as DisplayObject;
preloader.x -= ( preloader.x - destX ) * .1;
preloader.y -= ( preloader.y - destY ) * .1;
if ( Math.abs ( preloader.y - destY ) < 1 )
{
// Switch back to high quality
stage.quality = StageQuality.HIGH;
preloader.removeEventListener ( Event.ENTER_FRAME, movePosition );
}
}
Stosowanie tej opcji (Wygładź dla czytelności) w odniesieniu do tekstu w ruchu nie jest zalecane. W przypadku skalowania tekstu ta opcja powoduje podejmowanie prób zachowania wyrównania tekstu, co wywołuje efekt przesuwania. Jeśli zawartość obiektu wyświetlanego jest stale zmieniana, a wymagany jest tekst skalowany, można zwiększyć wydajność aplikacji dla urządzeń przenośnych przez ustawienie jakości
LOW
. Po zakończeniu ruchu można z powrotem przywrócić jakość
HIGH
.