Adobe Air では、非常に複雑な Flash ベクター アニメーションを使用して、実際に 30 fps から 50 fps を得ることができます。
してはいけないこと:
アニメーション化されたものには、事前に作成された「ビットマップとしてキャッシュ」チェックボックスを使用しないでください。これは、静的なベクター画像に適用すると、静的なビットマップに変換されるため、優れた機能です。ムービー クリップを x 軸または y 軸に変換する以外の方法でアニメーションをアニメーション化する場合、ビットマップとしてのキャッシュをオンにすると、アニメーションは実際には遅くなります。
ブリッティングをしないでください。ブリッティングにより、Flash ではゲームが非常に高速になりますが、Adobe Air ではゲームが遅くなります。必要なのは、ステージに配置されたビットマップ オブジェクトであり、ステージに blit される bitmapData オブジェクトではありません。
したがって、できることは、swf またはムービークリップを取得し、オブジェクトのすべてのフレームを実行して、各フレームをビットマップに変換することです。次に、各ビットマップを配列に保存します。次に、アニメーションを再生するために、配列からビットマップを取得し、ステージ上に順番に配置します。私のテストでは、Android タブレットで 40 fps 以上で 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);
}
}
}
}