实际上,您可以在 Adobe Air 中通过非常复杂的 Flash 矢量动画获得 30fps 到 50fps。
不该做什么:
不要将预制的“缓存为位图”复选框用于任何动画。当应用于静态矢量图像时,这是一个很棒的功能,因为它将其转换为静态位图。如果动画以除了在 x 或 y 轴上平移影片剪辑之外的任何方式进行动画处理,则您的动画实际上会更慢,并且缓存为打开的位图。
不要做blitting。Blitting 可以使游戏在 Flash 中快速运行,但在 Adobe air 中它会使它们变慢。您想要的是放置在舞台上的位图对象,而不是被传送到舞台上的 bitmapData 对象。
因此,您可以做的是抓取一个 swf 或 Movieclip,运行对象的每一帧并将每一帧转换为位图。然后,将每个位图保存到一个数组中。然后,要播放动画,从数组中检索位图并将它们按顺序放置在舞台上。在我的测试中,我能够在 Android 平板电脑上以超过 40fps 的速度运行全屏、24 帧动画。
代码示例如下。它会慢慢缓存位图,完成,然后立即开始以更高的速率播放。如果需要,您可以在动画缓存时隐藏动画。当您不再需要动画时,清除数组以释放内存。
package scripts.animation{
import flash.display.MovieClip;
import flash.events.*;
import flash.display.Stage;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.*;
import flash.events.Event;
public class spriteSheetMaker extends MovieClip {
private var pWidth:int=0;
private var pHeight:int=0;
private var regX:int=0;
private var regY:int=0;
private var swfObj:MovieClip = null;
private var pFrame:int=0;
private var pFrames:int=0;
private var pSheetArray:Array=[];
private var pSheetInfo:Array=[];
private var pAnimating:Boolean = false;
private var pAnimationCycle:int = 0;
//-------------------------------------------------------
//-------------------------------------------------------
//init
//-------------------------------------------------------
//-------------------------------------------------------
public function spriteSheetMaker ():void {
startGrab();
}
//-------------------------------------------------------
//-------------------------------------------------------
//swf is loaded, find out how many frames are in, dimentions etc, and start animation
//-------------------------------------------------------
//-------------------------------------------------------
public function startGrab ():void {
swfObj=this.animation;
swfObj.x = 0;
//swfObj.y = 0;
pFrames=swfObj.totalFrames;
pFrame=0;
pSheetInfo=[this.name,pWidth,pHeight];
pSheetArray.push (pSheetInfo);
pAnimating = false;
this.addEventListener (Event.ENTER_FRAME,cycleSwfAnim);
}
//-------------------------------------------------------
//-------------------------------------------------------
//load the next frame of the animation and convert it
//-------------------------------------------------------
//-------------------------------------------------------
private function cycleSwfAnim (event:Event):void {
pFrame++;
if (pFrame < pFrames + 2) {
swfObj.gotoAndStop (pFrame);
grabBitmap ();
} else {
stopGrab ();
}
}
//
private function stopGrab():void{
this.removeEventListener (Event.ENTER_FRAME,cycleSwfAnim);
trace("Sheet = " + pSheetArray);
swfObj.parent.removeChild(swfObj);
swfObj=null;
startAnimationPlayback();
}
//-------------------------------------------------------
//-------------------------------------------------------
//Convert fram (vector, bitmap, whatever is on the frame) into a bitmadata object
//-------------------------------------------------------
//-------------------------------------------------------
private function grabBitmap ():void {
pWidth=this.width;
pHeight=this.height;
var bmd:BitmapData=new BitmapData(pWidth,pHeight,true,0x00FFFFFF);
bmd.draw (swfObj);
var bm:Bitmap = new Bitmap();
bm.bitmapData = bmd;
pSheetArray.push (bm);
}
//-------------------------------------------------------
//-------------------------------------------------------
//Play animation
//-------------------------------------------------------
//-------------------------------------------------------
private function startAnimationPlayback():void{
this.addEventListener (Event.ENTER_FRAME,animate);
pFrame =0;
}
//
private function animate(event:Event):void{
pFrame++;
if (pFrame>pSheetArray.length){
pFrame = 1;
}
var bm:Bitmap = pSheetArray[pFrame];
if (bm != null){
if (this.numChildren>0){
this.removeChildAt(0);
}
this.addChild(bm);
}
}
}
}