テキストオブジェクトのレンダリング

ビットマップキャッシュ機能と opaqueBackground プロパティを使用してテキストレンダリングのパフォーマンスを向上させます。

Flash Text Engine によって、重要な最適化が実現されます。ただし、1 行のテキストを表示するのに多数のクラスが必要です。したがって、TextLine クラスを使用して編集可能テキストフィールドを作成する場合は、大量のメモリを消費し、ActionScript コードを何行も記述する必要があります。TextLine クラスは、静的な編集不可のテキストで使用する場合に適しています。このようなテキストでは、高速なレンダリングが可能で、メモリをそれほど必要としません。

ビットマップキャッシュ機能を使用すると、ベクターコンテンツをビットマップとしてキャッシュできるので、レンダリングパフォーマンスが向上します。この機能は、複雑なベクターコンテンツで役に立ちます。また、高負荷のレンダリングが必要なテキストコンテンツにも使用できます。

次の例は、ビットマップキャッシュ機能と opaqueBackground プロパティを使用して、レンダリングパフォーマンスを向上させる方法を示しています。次の図は、一般的なスタートアップスクリーンを示しています。このスクリーンは、ユーザーがロードの待機中に表示されます。

フルサイズのグラフィックを表示
スタートアップスクリーン

次の図は、プログラムによって TextField オブジェクトに適用されるイージング効果を示しています。テキストは、シーンの先頭から中央に向かってゆっくりと移動します。

フルサイズのグラフィックを表示
テキストのイージング

次のコードでは、イージングを作成します。preloader 変数は現在のターゲットオブジェクトを保存し、パフォーマンスに影響する可能性のあるプロパティ参照を最小化します。

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 ); 
}

Math.abs() 関数をインラインでここに移動して、関数呼び出しの回数を減らし、さらにパフォーマンスを向上させることができます。ベストプラクティスでは、destX プロパティおよび destY プロパティに int 型を使用して、固定小数点値を格納します。int 型を使用すると、Math.ceil() または Math.round() のような時間のかかるメソッドを使用して手動で値の丸め込みを行うことなく、完全にピクセルへ吸着させることができます。このコードでは、座標を int に丸め込みません。これは、値を常に丸め込むことで、オブジェクトがスムーズに移動しなくなるためです。オブジェクトの動きがぎこちなくなることがあります。これは、座標が各フレームで丸め込まれた最も近い整数に吸着されるためです。ただし、このテクニックは、表示オブジェクトの最終位置を設定するときに有効な場合があります。次のコードは使用しないでください。

// Do not use this code 
var destX:Number = Math.round ( stage.stageWidth / 2 );  
var destY:Number = Math.round ( stage.stageHeight / 2); 

次のコードでは、処理が大幅に高速化されます。

var destX:int = stage.stageWidth / 2;  
var destY:int = stage.stageHeight / 2; 

上述のコードは、値の除算にビット単位のシフト演算子を使用すれば、さらに最適化できます。

var destX:int = stage.stageWidth >> 1;  
var destY:int = stage.stageHeight >> 1;

ビットマップキャッシュ機能によって、ランタイムは動的ビットマップを使用して、オブジェクトをより簡単にレンダリングできます。現在の例では、TextField オブジェクトを含んでいるムービークリップがキャッシュされています。

wait_mc.cacheAsBitmap = true;

パフォーマンスを向上させる別の方法に、アルファ透明度を削除する方法があります。アルファ透明度を使用すると、透明なビットマップイメージの描画時に、ランタイムの負荷が増加します。上述のコードを参照してください。opaqueBackground プロパティを使用して、色を背景色として指定することにより、この問題を回避できます。

opaqueBackground プロパティを使用する場合、メモリ内に作成されているビットマップサーフェスは 32 ビットを使用し続けます。ただし、アルファのオフセットは 255 に設定され、透明度は使用されません。結果として、opaqueBackground プロパティを使用しても、メモリ使用量は低減しませんが、ビットマップキャッシュ機能を使用している場合は、レンダリングパフォーマンスが向上します。次のコードには、すべての最適化が含まれています。

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 ); 
}

ここでは、アニメーションが最適化されています。また、透明度を削除することにより、ビットマップキャッシュが最適化されています。モバイルデバイスで、ビットマップキャッシュ機能を使用し、様々なアニメーションの状態でステージの品質の LOWHIGH を切り替える場合について考えてみましょう。

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 ); 
    } 
}

ただし、この場合にステージの品質を変更すると、ランタイムは現在のステージの品質に合わせて TextField オブジェクトのビットマップサーフェスを再生成します。したがって、ビットマップキャッシュ機能を使用するときは、ステージの品質を変更しないことをお勧めします。

ここでは、手動によるビットマップキャッシュ手法を使用してもよいでしょう。opaqueBackground プロパティをシミュレートするには、ムービークリップを不透明な BitmapData オブジェクトに描画します。これにより、ランタイムがビットマップサーフェスを再生成することはありません。

この手法は、長時間変更しないコンテンツに効果があります。ただし、テキストフィールドのコンテンツが変更可能な場合は、別の方法を検討してください。例えば、アプリケーションのロードの進捗率が継続的に更新されるテキストフィールドについて考えてみましょう。テキストフィールドまたは内部の表示オブジェクトがビットマップとしてキャッシュされている場合、コンテンツが変更されるたびにそのサーフェスを生成する必要があります。表示オブジェクトのコンテンツは継続的に変更されるので、手動によるビットマップキャッシュはここでは使用できません。このコンテンツ変更により、BitmapData.draw() メソッドを手動で呼び出して、キャッシュされたビットマップを更新する必要があります。

Flash Player 8(および AIR 1.0)以降では、ステージの品質の値に関わらず、レンダリング設定が「アンチエイリアス(読みやすさ優先)」に設定されているテキストフィールドは、完全にアンチエイリアス処理されます。この手法により、メモリ消費量は低減しますが、CPU 処理は増大します。また、ビットマップキャッシュ機能と比較して、レンダリングに多少時間がかかります。

次のコードでは、この手法を使用しています。

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 ); 
    } 
}

動いているテキストに「アンチエイリアス(読みやすさ優先)」オプションを使用することは推奨されません。テキストを拡大 / 縮小する際にこのオプションを使用すると、テキストは行揃えされた状態を維持しようとして、シフト効果が発生します。ただし、表示オブジェクトのコンテンツが常に変更されていて、テキストを拡大 / 縮小する必要がある場合は、品質を LOW に設定することにより、モバイルアプリケーションでのパフォーマンスが向上します。モーションが完了したら、品質をHIGH に戻します。