2

ダブルバッファを使用してアニメーションを描画する単純なフラッシュ ゲームを開発しようとしています。

Event.ENTER_FRAME が発生すると、再描画が行われます。

ダブルバッファリングに使用されるバックバッファのタイプは BitmapData です。

アニメーションは非常に単純です。20x20 ピクセルのビットマップをバックバッファーに描画し、x 座標を増やして、キャンバスの左側から右側にスムーズに移動するようにします。これは基本的には問題なく機能しますが、よく見ると、この動きに大きな混乱が見られます。フレームレートは常に 60 を超えているため、これはフレーム レートとは関係がないようです。スムーズな動きの中断はアニメーションには受け入れられませんが、ダブルバッファリングに問題はないと確信しています。これはフラッシュプレーヤーの問題か何かではないかと心配しています...そうでなければ非常に安心します

簡単なアニメーションを示す swf を見てください。

https://dl.dropbox.com/u/55967135/test.swf

(ちなみに、動きが2つのフレーム間の時間に基づいている場合、アニメーションの中断も消えません。現在では、フレームごとに一定の2ピクセルです。)

上記の swf のソースコード全体を含む非常に軽量なフラッシュ ビルダー プロジェクトをアップロードしました: https://dl.dropbox.com/u/55967135/test.zip

    public function enterFrame():void               
      {

           // Calculate the time since the last frame  (NOT USED IN THE EXAMPL PROGRAM)                   
           var thisFrame : Date = new Date();               
           var dT : Number = (thisFrame.getTime() - lastFrame.getTime())/1000.0;               
           lastFrame = thisFrame;          

           // erase backBuffer
           backBuffer.fillRect(backBuffer.rect, 0xFFFFFFFF);


           // set new postion of the small testimage
           if (this.pos > 600 || this.pos < 0) {
                this.direction = !this.direction;
           }

           // increase / decrease vertical position
           if (this.direction) {
                this.pos += 2;
           } else {
                this.pos -= 2;
           }

           //trace(pos);
           // draw small test image at postion "offset"
           backBuffer.copyPixels(     this.testGraphic.bitmap.bitmapData, 
                                         this.testGraphic.bitmap.bitmapData.rect, 
                                         new Point(pos, 0.0));               
      }

enterFrame() は、ダブルバッファリングを処理するクラス GraphicsController のメソッドです。アプリケーションの enterFrame(event) メソッドによって起動されます。

        public function enterFrame(event:Event):void
           {
                GraphicsController.Instance.enterFrame();     
                myCanvas.graphics.clear();
                myCanvas.graphics.beginBitmapFill(GraphicsController.Instance.backBuffer, null, false, false);                              
                myCanvas.graphics.drawRect(0, 0, this.width, this.height);                              
                myCanvas.graphics.endFill();
                stage.invalidate();
           }  

助けていただければ幸いです

ありがとうございました

4

2 に答える 2

1

クロムで私にとっては完全にスムーズに動作しますが、あなたが説明する効果は知っています. 私は Firefox のアプリケーションでそれを経験しましたが、ビットマップデータの代わりに表示リストを使用していました。私の問題は、表示オブジェクトを 1 ピクセル未満移動したためであり、フラッシュはそれに満足していませんでした。オブジェクトを 0.99 にスケーリングするとすぐに修正されました。

dT をグラフ化して、安定しているかどうかを確認できます。変動している場合は 60 fps で実行しているため、16.6666 (または 0.0166) である必要があります。フレーム入力イベントが押し戻されます。

これも役に立つかもしれません: http://www.craftymind.com/2008/04/18/updated-elastic-racetrack-for-flash-9-and-avm2/

于 2012-09-07T13:31:22.717 に答える
1

まず、backBuffer はそのままで問題ありません。更新する前に lock() し、更新後に unlock() するだけです。次に、代わりに Bitmap オブジェクトを使用できるのに、なぜグラフィックスを再描画するのでしょうか? したがって、GraphicsController.enterFrame() をそのまま保持し、メソッド コードの最初と最後にbackBuffer.lock();and呼び出しを追加し、enterFrame 呼び出し中に自動的に更新される初期化フェーズで単一の Bitmap オブジェクトを使用します。backBuffer.unlock();アプリケーションの enterFrame() の他のすべては役に立たなくなります。

基本的に私が話しているのは、キャンバスを Shape 型から Bitmap 型に変更することです。そのビットマップは GraphicsController の backBuffer にハードリンクされ、自動更新されます。

于 2012-09-07T13:32:11.553 に答える