0

AS3でたくさんの単語をアニメーション化しています。これをモバイルデバイスで使用するので、スプライトではなくビットマップを使用したいと思います。そこで、アクセスできる.bitmapプロパティを持つWordObjectsを作成しました。

次のコードがあります。これは、クリックイベントで起動し、enterframeイベント内の配列をループします。これはおそらく悪い考えですが、どうすればもっとうまくできるかわかりません。(驚くべきことは、Flashbuilderでは問題なく動作しますが、Flash CS5ではクロールが遅くなることです。)

これを行うためのより良い方法はありますか?ビットマップの配列をアニメーション化する効率的な方法が必要です。

    private function clickhandler (e:MouseEvent){

        this.addEventListener(Event.ENTER_FRAME, blowemup);
    }
    private function blowemup(e:Event){
        var newPosition:Number;
        for(var i:int=0; i<arrWordObjects.length; i++)
        {
            newPosition = updatePosition(arrWordObjects[i].bitmap);
            arrWordObjects[i].bitmap.x += newPosition;
            arrWordObjects[i].bitmap.y += getRandomNumber();

        }
    }
4

3 に答える 3

1

一度にいくつのビットマップをステージに置く予定ですか?

Air 2.6を使用して、iPhoneでフルスピードで実行しているステージ上で40個の900x16pxビットマップをアニメーション化しています。

エンターフレームイベントでforeachループを使用しました。これは、マウスクリックで追加し、アニメーションが終了したら削除しました。

GPUレンダリングを有効にしてモバイル用にコンパイルすることを忘れないでください。(air 2.6を使用している場合は、app.xmlのgpu)

これも一読の価値があり、モバイルデバイスのパフォーマンスについて多くのことを説明しています http://help.adobe.com/en_US/as3/mobile/WS901d38e593cd1bac-3d719af412b2b394529-8000.html

これが私が持っていたものの基本的な例です...

package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Rectangle;

    [SWF(frameRate="30", backgroundColor="#FF00FF")]
    public class Test extends Sprite
    {
        private var fields:Vector.<Bitmap> = new Vector.<Bitmap>();

        public function Test()
        {
            this.stage.scaleMode = StageScaleMode.NO_SCALE;
            this.stage.align = StageAlign.TOP_LEFT;

            for(var i:int = 0; i< 37; i++){
                var bd:BitmapData = new BitmapData(960, 16, true, 0x000000);

                bd.fillRect(new Rectangle(0, 0, 900, 16), Math.round( Math.random()*0xFFFFFFFF ));

                var b:Bitmap = new Bitmap(bd);

                b.x = 0;
                b.y = i*16;

                stage.addChild(b);
                fields.push(b);
            }

            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
        }

        private var inertia:Boolean = false;
        private var yCurrent:Number;
        private var ySpeed:Number;
        private var startY:Number;

        private var cy:Number = 0;

        private function onEnterFrame(e:Event):void{
            if(!inertia){
                ySpeed = (startY - yCurrent) ; // / 16;
                startY = yCurrent
            } else {
                ySpeed *= 0.8;

                if(ySpeed < 0.01 && ySpeed > -0.01){
                    inertia = false;
                    stage.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
                }
            }

            cy += ySpeed;
            if(cy > 640)
                cy -= 640;

            var ty:Number = cy;
            for each(var tf:Bitmap in fields){
                tf.y = ty;
                ty += 16;

                if(ty > 640)
                    ty -= 640;
            }
        }

        private function onMouseDown(e:MouseEvent):void{
            inertia = false;
            startY = e.stageY;
            yCurrent = e.stageY;
            stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
        }

        private function onMouseMove(e:MouseEvent):void{
            yCurrent = e.stageY;
        }

        private function onMouseUp(e:Event):void{
            inertia = true;
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
        }

    }
}
于 2011-05-04T21:31:32.563 に答える
1

大きな違いを生むものは、標準のループfor each(Object in Array)ではなく、を使用することです。for

private function blowemup(e:Event):void
{
    var newPosition:Number;

    var i:ArrWordsObjectClass; // <-- don't know what the class for this is, just replace
    for each(i in arrWordObjects)
    {
        newPosition = updatePosition(i.bitmap);
        i.bitmap.x += newPosition;
        i.bitmap.y += getRandomNumber();
    }
}

ループが入力されます。つまり、通常はすべての反復がfor each何であるかを計算しようとする場所で多くの時間が節約されます。arrWordObjects[i]

また、補足:1つのENTER_FRAME駆動関数を使用し、各フレームを処理するアプリケーション内のすべてをループすることは、オブジェクトに数百のリスナーを適用するよりもはるかに効率的です。

私は通常、次のように、ENTER_FRAMEとオブジェクトを格納する配列を含むハンドラークラスを作成します。

package
{
    import flash.events.Event;
    import flash.display.Sprite;

    public class Handler extends Sprite
    {
        // vars
        public var elements:Array = [];

        /**
         * Constructor
         */
        public function Handler()
        {
            addEventListener(Event.ENTER_FRAME, _handle);
        }

        /**
         * Called on each dispatch of Event.ENTER_FRAME
         */
        private function _handle(e:Event):void
        {
            var i:Element;
            for each(i in elements)
            {
                i.step();
            }
        }
    }
}

step()次に、上記で呼び出された関数を含む、処理するすべてのオブジェクトの基本クラスを作成します。

package
{
    import flash.display.DisplayObject;

    public class Element extends Object
    {
        // vars
        public var skin:DisplayObject;

        /**
         * Called on each dispatch of Event.ENTER_FRAME at Handler
         */
        public function step():void
        {
            // override me
        }
    }
}

次に、オブジェクトでElementを拡張します。

package
{
    import flash.display.Sprite;

    public class MyThing extends Element
    {
        /**
         * Constructor
         */
        public function MyThing()
        {
            skin = new Sprite();

            skin.graphics.beginFill(0);
            skin.graphics.drawCircle(0,0,40);
            skin.graphics.endFill();
        }

        /**
         * Override step
         */
        override public function step():void
        {
            skin.x += 4;
        }
    }
}

そして、それをすべて実行してください!:

var handler:Handler = new Handler();

var m:MyThing;
var i:uint = 0;
for(i; i<10; i++)
{
    m = new MyThing();
    m.y = Math.random()*stage.stageHeight;

    handler.elements.push(m);
    addChild(m.skin);
}
于 2011-05-05T00:04:37.653 に答える
0

ENTER_FRAMEイベントに登録するよりも、AdobeのWebサイトにカスタムエフェクトを作成することを検討することをお勧めします。あなたがそこに置いたことは、プログラムが実行されている限り、このコードが永久に実行されることを意味します。エフェクトを停止するか、10フレーム実行して停止する場合は、さらにコードを記述する必要があります。これを複数のインスタンスに適用する場合は、さらに複雑になります。カスタムエフェクトフレームワークが解決する問題を解決する必要があります。

ここでカスタムエフェクトの書き方を読みました:

http://livedocs.adobe.com/flex/3/html/help.html?content=createeffects_1.html

于 2011-05-04T21:14:31.240 に答える