タワーディフェンスゲームのA *実装でのパフォーマンスが遅い


9

定義済みのパスを使用せずに、タワーディフェンスゲームをFlashで作成しています。

私のグリッドは40x40(小さい?)ですが、A *は毎回再計算するときに苦労しています。そのため、再計算を簡単にするために独自の変更を加えたため、タッチされたセルの数は約900に減少しました(ルートの近くで変更した場合)。新しいタワーが設置されると、非常に短時間ですが検出可能な時間はフリーズします。

これは実装の問題ですか、それとも40x40が多すぎますか?

編集:

私のコードの構造:

  • すべてのデータは、セルの2D配列に保存されます。
  • 各セルには、パス方向の親(時計回りに1〜8)と、パス内の子のビットごとにエンコードされた配列(すべてのビットが子を表す)が含まれます。
  • 検索は、ユークリッド距離の推定値を使用してA *によって実行されます。

ここでは、もっと具体的にする必要があります。私たちはあなたのコードがどのように見えるのか、どのように構造化されているのかなどわからないので、何が遅くなっているのかについて結論を出すことはできません。
ショーンジェームズ

1
私が最後にA *を実装したとき、64x64グリッドを最大 1ms で実行したことを覚えています。ええ、それはあなたの実装に問題があるようです。私たちはあなたのコードまたはその要旨を投稿することをお勧めします。
マルク・ミュラー

追加した編集を見る
ダニ

1
40x40が遅すぎる場合は、非常に間違っている可能性があります。コードを投稿するか、プロファイルを作成してください。または、拡大して何が起こるかを確認します。80x80グリッドに4倍以上かかる場合は、非常に壊れているものがあります。
ZorbaTHut

タイトルはもう少し参考になりますか?
tenpn

回答:


4

コメントはできませんが、Flexの最初のプロファイルです。それ以外はすべて推測です。


フレックスでフラッシュプロジェクトをプロファイリングするにはどうすればよいですか?
ダニ

はいといいえ。Flashプロジェクトを直接ロードするとは思わない。ソースなしでswfをプロファイリングしても、関数レベルの情報を取得できると思います。「フレックスでのフラッシュプロジェクトのプロファイリング」などのGoogle検索を行います。これを実行して取得しました:flexblog.edchipman.ca/…有望に見えます。
ジョナサンフィショフ2010

ありがとう、問題のある部分を見つけるのを本当に助けてくれた(アルゴリズムにはなかった、質問のコメントを参照)
Dani

13

TDは「タワーディフェンス」だと思います

このため、A *は少し行き過ぎていると思います。

ゲームの開始時に、ゲームポイントを出口ポイントから塗りつぶして、移動マップを作成します。

 |---------|
 |5|4|3|3|3|
 |5|4|3|2|2|
->5|4|3|2|1->
 |5|4|3|2|2|
 |5|4|3|3|3|
 |---------|

動きは常に低い値の正方形に向かっています。

プレーヤーがタワーを配置したら、8つの隣接する正方形のそれぞれを更新します。各正方形について、その移動値を最も低い隣接値よりも1だけ大きく設定します。値が変更された場合は、更新された正方形を中心にプロセスを繰り返します。次に、出口へのルートがブロックされていないことを確認するには、すべての正方形が値の小さい正方形に隣接していることを確認します。

プレイヤーがタワーを削除するとき、移動値を最も低い隣接する正方形よりも1だけ大きく設定し、上記のプロセスを繰り返します。

より簡単なアプローチは、洪水を再び行うことです。


6
フラッドフィルを再実行することは、A *を実行するよりも、少数のユニット(おおよそ、ボードの長さ)のアルゴリズムよりもコストがかかります(これはフラッシュであるため、メモリレイアウトなどの非アルゴリズム定数はおそらく可能です)非常に効果的に使用されます)。ただし、これは多くの通信ユニットにとって非常に優れたモデルであり、協調的拡散と呼ばれます-scalablegamedesign.cs.colorado.edu/wiki/Collaborative_Diffusion

@ジョーWreschnig:すごい素敵なリンク。私は以前にそのテクニックを使用したことがありますが、それが何と呼ばれるのか知りませんでした。ありがとう。
tenpn

@Joe、マップに少なくともいくつかの障壁がある限り、これはA *を呼び出すよりも非効率だとは思いません。つまり、ユニットがほとんどなく、バリアフリーでほぼバリアフリーのマップの場合にのみ、状況が悪化する可能性があると考えています。
edA-qa mort-ora-y

@edA:定義により、フラッドフィルは最終的にマップ上のすべてのアクセス可能なポイントに接触する必要があります。A *は、接触する必要があるポイントの数に実績のある上限を提供します。これは、多くてもマップ上のアクセス可能なすべてのポイントであり、通常ははるかに少なくなります。フラッドフィルは、メモリレイアウトなどを最適化するためのより単純なアルゴリズムですが、先ほど述べたように、おそらく問題ではありません。

@Joe、それは私が主張していることです。たとえタワーがほんの少しでも、A *はほとんどすべてのスペースに触れる可能性が高いということです。ただし、Nモンスターの場合、フラッドフィルよりも効率を下げるには、total_squares / Nを超える必要があります。
edA-qa mort-ora-y 2011

2

奇妙なことに、私はこれに返信したと思いましたが、返信がなくなったようです。複数のステップで更新できるように検索アルゴリズムを作成します。これにより、タワーを配置してアニメーションを再生するときに、フレームごとに少しずつ実行でき、0.5秒から1秒の間で更新を行うことができます。 A *目立った一時停止はありません。それは待ち時間です-あなたはそれをスピードアップできないiF、それを隠す方法を見つけます。タワーを配置しながらアニメーションを再生するのはゲームにとって自然なことであり、imoを非表示にするのに適しています。


これは一般的には良い考えですが、この特定の質問には良くありません。そのような小さなグリッドでのA *は、ほとんど時間をかけずに、ほぼ瞬時である必要があります。
davr

けっこうだ。スローダウンの原因となる実装の詳細を知らなくても問題を解決できるのは、これが唯一の答えです。
Kaj

0

まず、配列をベクトルに変更できます。速度が向上するはずです。コードを投稿すると、さらに最適化を提案できる場合があります。


0

あなたのスローダウンは、すべてのキャラクターのパスを同時に計算しているためだと思います。1つのキャラクターのパスの計算は高速ですが、シーンに20ダースのキャラクターがいる場合、それは失敗する可能性があります。

代わりに、負荷を数フレームに分散する必要があります。AIの更新をずらして、異なるキャラクターが異なるフレームでパスを更新するようにします。キャラクターが1秒後まで反応しなかったとしても、1フレームだけが悪い反応を引き起こすことはないでしょう。


これはほぼ1年前に回答され、Graceの編集作業のためにぶつかっただけです。(あまりにも多くの文字とは関係がありませんでした。)

知らせてくれてありがとうございます。日付に気づかなかった。
ジョッキング
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.