5

現在、私は非常に単純なGUI描画を実験しています...「エンジン」(あなたはそれをそれと呼ぶことができると思います)。その要点:

  1. ユーザーの要求に見舞われるFrontControllerがあります。各リクエストにはuidがあります
  2. uid(「ページ」を読む)には、その上に存在するコンポーネント(「モジュール」)の宣言があります
  3. コンポーネントはSpriteサブクラスであり、本質的には一意です

当然、これらのスプライトを非表示/表示する方法が必要です。現在、私はFlexがデフォルトで持っているのとほとんど同じように持っています。つまり、「コンプが表示される場所にいる場合は、作成してキャッシュし、再び表示されるたびに再利用する」という方法です。

addChild問題は、 /removeChildまたはトグルを介して-隠したり表示したりするためのより適切で効率的な方法です-visibleです。

私の見方はそれです:

  • visible速くて汚い(最初のテストで)
  • visibleEvent.ADDEDまたはのようなバブリングイベントのチェーンを作成しませんEvent.REMOVED
  • 非表示のコンポーネントはマウスイベントを取得しません

したがってremoveChild、コンポーネントが画面上で不要になる(またはキャッシュが大きすぎるなど)と確信しているときに呼び出すものになります。

stackoverflow'ers / AS3に夢中になっている人々はどう思いますか?

更新:ここに良い読み物があります(グーグルを忘れました)。

私は固執しvisibleます; それは私の仕事により適しているようです。アドビによるマニュアル「フラッシュプラットフォームのパフォーマンスの最適化」(p。69は私にさらに自信を与えました。

これが私が興味のある人のために物事をテストするために立てたコードスニペットです:

package 
{
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.utils.getTimer;

/**
 * Simple benchmark to test alternatives for hiding and showing
 * DisplayObject.
 * 
 * Use:
 * <code>
 * new DisplayBM(stage);
 * </code>
 * 
 * Hit:
 * - "1" to addChild (note that hitting it 2 times is expensive; i think
 * this is because the player has to check whether or not the comp is
 * used elsewhere)
 * - "q" to removeChild (2 times in a row will throw an exception) 
 * - "2" to set visible to true
 * - "w" to set visible to false
 * 
 * @author Vasi Grigorash
 */    
public class DisplayBM{
    public function DisplayBM(stage:Stage){
        super();

        var insts:uint = 5000;
        var v:Vector.<Sprite> = new Vector.<Sprite>(insts);
        var i:Number = v.length, s:Sprite
        while (i--){
            s = new Sprite;
            s.graphics.beginFill(Math.random() * 0xFFFFFF);
            s.graphics.drawRect(
                Math.random() * stage.stageWidth, 
                Math.random() * stage.stageHeight,
                10, 
                10
            );
            s.graphics.endFill();
            v[i] = s;
        }

        var store:Object = {};
        store[Event.ADDED] = null;
        store[Event.REMOVED] = null;
        var count:Function = function(e:Event):void{
            store[e.type]++;
        }
        var keydown:Function = function (e:KeyboardEvent):void{
            var key:String
            //clear event counts from last run
            for (key in store){
                store[key] = 0;
            }

            stage.addEventListener(Event.ADDED, count);
            stage.addEventListener(Event.REMOVED, count);

            var s0:uint = getTimer(), op:String;
            var i:Number = v.length;
            if (e.keyCode === Keyboard.NUMBER_1){
                op = 'addChild';
                while (i--){
                    stage.addChild(v[i]);
                }
            }
            if (e.keyCode === Keyboard.Q){
                op = 'removeChild';
                while (i--){
                    stage.removeChild(v[i]);
                }
            }
            if (e.keyCode === Keyboard.NUMBER_2){
                op = 'visibile';
                while (i--){
                    v[i].visible = true;
                }
            }
            if (e.keyCode === Keyboard.W){
                op = 'invisibile';
                while (i--){
                    v[i].visible = false;
                }
            }
            if (op){
                //format events
                var events:Array = [];
                for (key in store){
                    events.push(key + ' : ' + store[key])
                }

                trace(op + ' took ' + (getTimer() - s0) + ' ' + events.join(','));
            }

            stage.removeEventListener(Event.ADDED, count);
            stage.removeEventListener(Event.REMOVED, count);
        }

        //autodispatch
        stage.addEventListener(KeyboardEvent.KEY_DOWN, keydown);
    }
}
}
4

3 に答える 3

2

Visible は私にとってより理にかなっており (子を削除するとファイナリティを示すため)、自分のプロジェクトで表示/非表示をするときによく使用します。

また、 addChild のパフォーマンスはわずかに低いと思いますが、テストは行っていません。

編集: この Adob​​e の記事http://help.adobe.com/en_US/as3/mobile/WS5d37564e2b3bb78e5247b9e212ea639b4d7-8000.htmlに出くわしました。これは、GPU レンダリング モードを使用する場合、visible = false を設定するだけでパフォーマンスに影響を与える可能性があることを示しています。重なっているオブジェクトを描画するためのコストです (たとえそれらが表示されていなくても)。代わりに、子を完全に削除することをお勧めします。

可能な限りオーバードローを避けてください。オーバードローとは、複数のグラフィック要素を重ね合わせて互いに覆い隠すことです。ソフトウェア レンダラーを使用すると、各ピクセルは 1 回だけ描画されます。したがって、ソフトウェア レンダリングの場合、そのピクセル位置で互いに重なり合うグラフィック要素の数に関係なく、アプリケーションのパフォーマンスが低下することはありません。対照的に、ハードウェア レンダラーは、他の要素がその領域を覆い隠すかどうかに関係なく、各要素の各ピクセルを描画します。2 つの長方形が重なっている場合、ハードウェア レンダラーは重なっている領域を 2 回描画しますが、ソフトウェア レンダラーはその領域を 1 回だけ描画します。

したがって、ソフトウェア レンダラーを使用するデスクトップでは、通常、オーバードローによるパフォーマンスへの影響はありません。ただし、多くの重なり合う形状は、GPU レンダリングを使用するデバイスのパフォーマンスに悪影響を与える可能性があります。ベスト プラクティスは、オブジェクトを非表示にするのではなく、表示リストから削除することです。

于 2012-04-05T23:28:58.873 に答える
1

インスタンス、イベントを減らし、フラッシュ ムービーからメモリを解放するには、子を削除することをお勧めします。後で、スプライトが互いに影響を与える可能性があることに気付くかもしれません。スプライトの描画方法やリスニング方法から、ガベージ コレクションの一般的な機能がこのメソッドの場合に適用されます。実装されたものは、最終的にアプリケーションを台無しにする可能性があります

Visible にはまだスプライトがメモリにあり、現在は描画されていません。スプライトを保存してから削除し、必要に応じて再ロードすることも、すべてのソリューションの理想です。配列を使用してデータを保存することも、アプリケーションの実装方法に依存する別のソリューションです。

子のパフォーマンスを追加することは、非表示の倍数に対して追加する唯一のアイテムであるため、ストレスが少ないと言えます。また、これらの非表示の子には、プロパティがリスナーとともにメモリに保存されます。

于 2012-04-06T03:14:34.503 に答える
0

Moock によるこの件に関するいくつかの確かなデータを次に示します

                  Children on the                     Single-frame 
                  Display List    .visible   .alpha   Elapsed Time (ms)
No Children       0               --         --       4
Non-visible       1000            false      1        4
Zero Alpha        1000            true       0        85
Fully Visible     1000            true       1        1498
90% Transparent   1000            true       .1       1997
于 2013-07-24T00:07:07.547 に答える