呈现文本对象

使用位图缓存功能和 opaqueBackground 属性可提高文本呈现性能。

Flash 文本引擎提供一些很出色的优化。但是,需要使用许多类才能显示单个文本行。为此,使用 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 属性的整数类型,以便拥有固定点值。通过使用整数类型,您可以获得完美的像素贴紧,而无需使用较慢的方法(如 Math.ceil() Math.round() )手动对值进行四舍五入。此代码不会将坐标四舍五入为整数,因为不断对值进行四舍五入会使对象不能平滑移动。此对象可能不会平滑移动,因为坐标已采用各个帧上最接近的四舍五入的整数。然而,此技术在设置显示对象的最终位置时可能非常有用。不要使用以下代码:

// 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;

提高性能的另一种方式是删除 alpha 透明度。在绘制透明位图图像时,Alpha 透明度增加了运行时的负担,如前面的代码所示。您可以使用 opaqueBackground 属性指定背景颜色来避免此情况。

当使用 opaqueBackground 属性时,在内存中创建的位图表面仍使用 32 位。然而,alpha 偏移量已设置为 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 ); 
}

现在动画已经过优化,还通过删除透明度优化了位图缓存。在移动设备上,请考虑以下情况:当使用位图缓存功能时,在不同动画状态期间将舞台品质切换为 LOW HIGH

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)及更高版本中,无论 Stage 品质值如何,呈现设置为“可读性消除锯齿”的文本字段会始终保持完全消除锯齿状态。此方法占用的内存较少,但是需要更多的 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