1

「ネイティブ」アプリとしてモバイルに展開することを目的としたゲーム、およびデスクトップ Web ブラウザーに取り組んでいます。

いくつかのプラットフォームで作業して以来、Flash とそれに組み込まれた AIR は非常に優れたソリューションであると思われました。しかし、うーん。

今のところ 4 キーフレームのムービークリップのみを使用すると (ステージに追加し、フレームごとに位置を更新し、最終的には削除します)、約 30 がデスクトップ画面に表示されるとゲームが遅くなり、Android に表示されると約 20 になります (サムスン i9000 - 2.3.3)。そして、私はもっと必要かもしれません。

そこで、ビットマップの領域を再描画し、Flash ライブラリに保存されている bitmapDatas スプライトシートに MovieClip を変換して、ブリッタリングを試みました。デスクトップでの結果は素晴らしく、何百ものオブジェクトであっても、完璧で滑らかなアニメーションが表示されます。しかし、モバイルでの結果はひどいもので、画面にオブジェクトが 1 つしか表示されていない場合でも、CPU または GPU でレンダリングされた場合でも、FPS は 15 まで低下します。

私のゲームが「古い」デバイスで動作するのは明らかにいいことですが、50 に近いまたはそれ以上のフレームレートに到達したい場合、現時点で Flash と AIR を使用するのは悪い考えですか?

Flash を使用したモバイル ゲームを開発する際に使用する必要があるヒントや必須のプラクティスはありますか? このような場合に避けるべきよくある間違いはありますか?

4

2 に答える 2

1

Adobe Air では、非常に複雑な Flash ベクター アニメーションを使用して、実際に 30 fps から 50 fps を得ることができます。

してはいけないこと:

  1. アニメーション化されたものには、事前に作成された「ビットマップとしてキャッシュ」チェックボックスを使用しないでください。これは、静的なベクター画像に適用すると、静的なビットマップに変換されるため、優れた機能です。ムービー クリップを x 軸または y 軸に変換する以外の方法でアニメーションをアニメーション化する場合、ビットマップとしてのキャッシュをオンにすると、アニメーションは実際には遅くなります。

  2. ブリッティングをしないでください。ブリッティングにより、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);
            }
        }
    }
}
于 2016-03-15T00:58:22.603 に答える
0

GPU レンダリングと組み合わせて、cacheAsBitmap と cacheAsBitmapMatrix を使用すると、ある程度の改善が得られますが、リモートで複雑なものについては、60 fps に近づくことはできない可能性があります。

モバイル デバイスで実際のパフォーマンスが必要な場合は、おそらく Starling フレームワーク (http://gamua.com/starling/) を確認することをお勧めします。合成とレンダリングを完全に GPU に移行し、オブジェクト モデルと表示リストを標準の Flash とほぼ同等に保ちます。1 世代または 2 世代前のハードウェアでも、パフォーマンスは非常に高速です (60 fps を簡単に達成できます)。

于 2012-09-05T10:49:35.930 に答える