Adobe の Scout の多くのユーザーが気付いているように、画像の解凍は、ゲームなどのフレーム レートに敏感なアプリケーションでおそらく最大のパフォーマンス ヒットです。
ゲーム (2D サイド スクローラー) でこれを使用すると問題が発生します。scout が画像圧縮解除イベントを表示する場合を除いて、フレームレートは非常にスムーズ (50+) で、その後 2 ~ 15 fps に低下します。それはひどいです。追加する画像 (画面上のタイル) が多いほど、これが発生します。
これに慣れていない場合は、Flash Player が「不要」で画面に表示されていない画像をメモリから削除し、再度画面に移動すると再圧縮されることに注意してください。これは、約 10 秒ごとに発生すると報告されています。
現時点での状況は満足とはほど遠いと思うので、私の解決策を共有し、あなた自身の解決策をいくつか尋ねたいと思います.
明白で私のコメントから始めましょう:
- Flash Pro では、インポートされた (埋め込まれた) 画像はすべて、プロパティ パネルで、圧縮解除なし / 無損失 PNG/GIF に設定する必要があります。
コメント: これは役に立ちますが、それでも減圧が発生し、通常の遅延の問題が発生します。
- 複数のタイルや画像を使用する代わりに、それらをより大きなタイルに統合するか、ゲームまたはアプリの「レベル」ごとに 1 つの画像に統合します。
コメント: 明らかな理由から、これも非常に役立ちます。画像が大きいため、画面全体に表示されるか、常により多くの画像が表示されるため、Flash はそれを取り除くことができません。明らかな理由から、これは本当に醜い解決策です。大きな画像をインポートすると Flash がクラッシュし、サイズの制限があり、タイルではなくレベルやグラフィック アプリを設計するときに大きな画像を扱うのは一般的に非常に困難です。ただし、これが機能する場合もあります。
- 複数の画像またはタイルがありますが、Flash がそれらを強制的にメモリに保持する場所にそれらを画面に追加します (.visible = true が必要です)。
コメント: これも機能しますが、上記のソリューションよりもさらに醜いです (それを呼び出すことができる場合)。これは、大きな画像をインポートしたり、最大サイズに達した場合に Flash がクラッシュしないようにするための単なる回避策です。しかし、それはトリックを行います。下のビットマップを形状オブジェクトのフィラーとしてのみ使用する場合、これらのイメージを他のフラッシュ レイヤーまたはイメージの下に非表示にすることができます。
- ImageDecodingPolicy.ON_LOAD を使用します。
コメント: 私のゲームでは、これだけではほとんど違いがありませんでしたが、ソリューション 1 と混ぜてみると、わずかに効果があるように見えました。コードは次のとおりです。
var loaderContext:LoaderContext = new LoaderContext();
loaderContext.imageDecodingPolicy = ImageDecodingPolicy.ON_LOAD
var loader:Loader = new Loader();
loader.load(new URLRequest("gameLevel.swf"), loaderContext);
これは通常、ビットマップのロードに使用されることは知っていますが、swf ではわずかにしか機能しませんでした。
- オブジェクトをメモリ上に保持するには、bitmapData オブジェクトで getPixel() を使用します。
コメント: これは何人かの人には効果があると読みましたが、私にはまったく効果がありませんでした. 非埋め込みアセットのコードの最も重要な部分 ( Keeping Bitmaps Decompressed ) は次のとおりです。
var bmd:BitmapData;
var timer:Timer = new Timer(1000);
timer.start();
timer.addEventListener(TimerEvent.TIMER, onTimer);
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
loader.load(new URLRequest("Adobe_Flash_Professional_CS5_icon.png"))
function onLoaded(ev:Event): void
{
bmd = ((ev.target as LoaderInfo).content as Bitmap).bitmapData;
}
function onTimer(ev:TimerEvent): void
{
bmd.getPixel(0, 0);
}
あなたが私のようで、埋め込み画像を使用している場合は、次のようなコードでコードを適応させることができます:
//be sure to set the library item on Flash Pro to be exported to ActionScript 3,
//and give it a class name, in this case Artwork.
var Artwork:Class;
Artwork = getDefinitionByName(Artwork) as Class;
bmd = new Artwork();
次に、10 秒ごとに getPixel() 関数を呼び出して、画像をメモリに再利用します。
残念ながら、私には関係ありません!!
- ビットマップが既にビットマップであっても、ビットマップをビットマップとしてキャッシュして、Flash Player アルゴリズムがそれをメモリに保持するように強制します。
コメント: これは非常にうまく機能し、「疑似ソリューション」2-3 とほとんど同じです。フレームレートはそれほど良くありませんが、解凍によるしゃっくりが非常にスムーズに解消されます。これはもちろん、instance.cacheAsBitmap = true; のようなコードで実行できます。または、単純に Flash Pro から直接レンダリング オプションを選択します。
- bitmapData を新しい BitmapData インスタンスにコピーし、元のアセットをガベージ コレクターに残します。データのコピーによる 1 回限りの CPU ヒットは比較的小さく、圧縮解除されたビットマップの 2 つのコピーを保持するために一時的に余分なメモリを使用することになります。ただし、完了したら、圧縮されたデータを解放することもできます。
コメント: 私も何もしませんでした。また、なぜそれが必要なのかわかりません:
var loadedBitmapData = event.target.content.bitmapData;
var newBitmapData:BitmapData = new BitmapData(loadedBitmapData.width,loadedBitmapData.height);
newBitmapData.copyPixels(loadedBitmapData,new Rectangle(0,0,loadedBitmapData.width, loadedBitmapData.height),new Point(0,0));
私が試したのはこれだけですが、ご想像のとおり、私はこれらのダクトテープのハックに満足しているとは言えません。おそらく解決策 4 と 5 を除いて、これらはすべて平凡なパッチのように思えますが、実際には何もしません。
だから、ここに私の質問があります:
解決策 5 と 7 がうまくいかない理由について、答えを探すのを手伝ってくれませんか? コードで埋め込み画像オプションを使用しており、タイマーを使用する代わりに、enterFrame 呼び出しで counter++ 変数の 50 ティック後に呼び出しています。
別の回避策を提供できますか?