2009-09-21 16 views
9

私は現在、非常に大規模なFlashプラットフォームゲーム(何百ものクラス)に取り組んでおり、ゲームを長時間放置するとゲームが遅くなるという問題に対処しています。私はゲームを書いていないので、私はその内部を漠然と熟知しています。いくつかの不思議な症状には、時間の経過とともにAS3のゲームパフォーマンスが低下する

  • が含まれます。突然の突然のメモリリークが発生すると、所定のレベルでゲームが正常に実行されます。
  • 指数関数的に漏れるポイントにゲームが到達するまでの時間は、画面にスプライトが多くなると短くなります。
  • 画面に何も表示されていなくても、ゲームの速度が遅くなります。
  • スプライトが頻繁に衝突すると、ゲームのスピードが速くなります。
  • コリジョンコードを完全に無効にすると、劣化が緩和されますが、ゲームが最終的にフレームをドロップするのを防ぐことはできません。

ソースを見てみるとFlexプロファイラを使用して、私の総理容疑者は、多くの不明なオブジェクトはメモリを大量に取って、特にWeakMethodClosure

  • があります。
  • このプログラムでは、弱いイベントリスナー(フレームごとに数十回のディスパッチ)が非常に多く使用されています。
  • 新しいスプライトが作成されるたびにBitmapDataがコピーされています。これらは50x50ピクセルのスプライトで、毎秒約8スプライトで生成されます。

ソースを見ることなく問題を教えてもらえないことはわかっているので、これを絞り込むためのヒントを探しています。誰も自分のプロジェクトでこの回避的なパフォーマンス低下を経験しましたか?あなたの場合、何が原因でしたか?

答えて

7

に30から私のFPSを殺しました。 そして、私はあなたを与えることができるいくつかの建築のアドバイス:

  1. 主な原則は - 可能関数としてなどほとんどないのtry /イベントは
  2. はすべてが、 onEnterFrame/onInterval /にOnTimerサイクルをオフに取り除く呼び出します。 が必要なものはすべて一般的なイベントコールが必要です。 処理されたオブジェクト 参照を格納するためには、おそらく多くの静的配列が必要です。
  3. メインループ
  4. にも、あなたのグラフィックス/レンダリングものを行う代わりに、小さなスプライト/ビットマップのビッグ(おそらくレンダリング済み)キャンバスを使用してみてください。 通常はバックグラウンドで使用できます。しかし、また、ソース矩形プロパティを介して、1タイルシートにそれを組み立て、そこから直接自分のもの を描き、(樹木、プラットフォーム、などのような)
  5. が小さいビットマップリソースをオフに取り除く小さなオブジェクト のための良好な作業

私はそれがあなたを助けてくれることを願っています! メモリリーク - 頭文字です。

P.S.あなたのゲームをさまざまなブラウザでテストしてみましょう.IEは、すべてのものが最も漏れています。

+0

これは、大規模なゲームプロジェクトを開始し、その構造を最適にする方法が不思議である人にとって、これは大きなアドバイスだと思います。 – Kai

0

何が起きているかを確認するには、アプリケーションのプロファイルを作成する必要があります。

このスレッドにはいくつかの提案がありましたが、最終的に何が起こっているのかを判断するためのコードを入力する必要があります。

Profiling ActionScript-3 Code

あなたは、あなただけの一定期間のいくつかの小さな部分を実行し、景気減速を見れば見ることができるかどうかを確認することをお勧めします。

アプリケーションをユニットテストして、さまざまなパーツをすばやく実行してメモリリークを探すことができます。 http://asunit.org/、および他のです: つのフレームワークがあるhttp://opensource.adobe.com/wiki/display/flexunit/

ユニットテストは、私がプロファイリングのために多くを使うものですので、あなたが問題を探して、あなたのゲームのトップレベルでテストし、それを何千回も実行することができ、それぞれの部分を実行し、どの部分に問題があるのか​​を見て、あなたの道を切り抜けてください。これは手動のプロセスですが、最初にリストされたSOスレッドの2つのアイデアが役に立たない場合は、これが最善の方法かもしれません。

あまりにも多くのメモリを使用していますか?またはあなたのCPU使用率が高すぎますか?

+0

質問にはメモリリークがあるので、CPU使用率が問題ではないと思います。 –

+0

私は、彼が推測していること以外に他の問題があるかどうかを調べようとしています。残念ながら、私のプログラムに問題がある場所を推測したとき、私は間違っている傾向があります。そのため、プロファイリングに大きく依存しています。 –

+0

あまりにも多くのオブジェクトが非常に高速に生成されているため、過剰なガベージコレクションがプログラムの劣化を招くかどうかは疑問です。 –

0

まず、メモリまたはプロセッサの制限が当てられているかどうかを判断します。それは後のように聞こえる、多くのオブジェクトが周りのものをしているようだ...それらの余分なスプライトは自由に解放されていない可能性が高い。それらのイベント内のオブジェクト/変数/何かの間の依存関係を探し、スプライトが削除されていることを確認し、EnterFrameのハンドラまたは定期的なイベントに注意を払う。

3
  • 匿名メソッドを避ける - クラスレベルのメソッドに変更します。
  • addEventListenerで弱い参照を使用するか、削除する前にオブジェクトのすべてのリスナーを削除することを確認してください。removeChild
  • すべてのスプライトを削除するようにしてください。また、可能であれば、新しいものを作成する代わりにスプライトを再利用してください。
1

特にビットマップデータのような重いオブジェクトの場合、多くの作成/破壊が行われている場合は、オブジェクトのプールを考慮する必要があります。

は、それはあなたがメモリよりもプロセッサの速度に出てキャッピングされていることをはるかにありそうに聞こえるObject Pool class

+0

ボトルネックの原因となっているリソースを特定したら、これは良いアイデアです。 – Kai

0

を参照してください。あなたは、フラッシュアプ​​リケーションをメモリに余分にしようとする必要があります。

幸いあなたはCPUを抑えるために行うことができます簡単なものがたくさんある...

1)厳密すべて、特にマウスリスナーのイベントリスナーを管理します。すべてのスプライトオブジェクトに$ texasイベントリスナーがありますか?それは問題になる可能性があります。

2)Numberの代わりにintまたはuintを使用して配列にアクセスします。これは巨大で、これは背後にあるAdobeのトリックの1つです。 intとuintを使って配列オブジェクトにアクセスするのはNumberよりも高速ですが、繰り返し実行すると、フレーム実行から数百万分の1秒も節約できます。 #2と同じ静脈で

3)、あなたの数学の操作を監視し、どのような種類のあなたが特定の操作のために使用されています。 AS3の算術演算で最も遅いのは、繰返しキャスト(整数を返す関数にintを渡す)、またはintの代わりにNumberに加算や減算などの基本的な演算を実行することです。

Flashでこのようなwtfhugeプログラムを持っていることについての素晴らしい事は些細な最適化の変更がパフォーマンスに大きな影響を与える可能性があることです。私はかつて私は1つの余分な変数を宣言しAS3での光線追跡エンジンをおもちゃにし、それは私が最近、大規模なプロジェクトの最適化を完了した23

+0

私のゲームは、少なくともいくつかの場所でこれらのルールを破っていると確信しています。私はそれがそれほど簡単であることを願っています! – Kai

0
Flashは、タイマーのイベントリスナーを引き起こし、弱く参照されたとしても、ENTER_FRAMEイベントがガベージコレクションされないというかなり悪名高い問題です(多くはバグだと思います)。したがって、弱く参照されたイベントを使用することをお勧めしますが、不要になった時点ですべてのイベントリスナーを削除する必要があります。
+0

Event.ENTER_FRAMEをすばやく検索した後、私は18回の試合を行ったので、ここでも問題が発生する可能性があります。 – Kai

関連する問題