ターンベース、距離ベースの戦略ゲームで可能な動きの範囲を決定する方法は?


11

私はc ++とSFML-2.0を使用して、2次元のターンベースの戦略ゲームを作成しています。移動はグリッドベースではなく距離ベースであり、いくつかの異なる三角形のピースが所定のターンで所定の位置で回転するか、前方に移動します。

動きは、プレイヤーが駒を移動する場所を選択するように機能します。これにより、駒が進む可能性のあるパスが生成されます。プレーヤーが決定を確認すると、ピースはそのパスに沿って目的の場所に移動します。パスは次の2つの要素によって制限されます。距離、曲がり角を考慮して、ピースが移動できる距離です(カーブがある場合、ポイントからポイントに直接ではなく、カーブに沿った長さになります)。ステアリングアングル、ピースが移動中に任意のポイント(およびすべてのポイント)で回転できる距離(たとえば、-30から30度)。

私の質問は、ピースを移動させるためにプレーヤーが選択できる潜在的な場所の範囲をどのように決定すればよいですか?

ここで使用する方程式やアルゴリズムは完全にはわかりません。私の最初の計画は非常に複雑で、実装することはほぼ不可能であり、説明は言うまでもありませんでした。この時点で、プロジェクトが停滞して完全に迷っています。

回転半径を考慮して、ユニットが移動できる範囲をどのように決定できますか?

たとえば、次の画像では。赤、青、緑の線はすべて同じ長さになります。紫色の円は、ユニットが移動できる移動範囲を示します。(形状はおそらく不正確であり、ラインはおそらく実際には同じ長さではありません、あなたはアイデアを得るでしょう)

ここに画像の説明を入力してください


それでも、同じ(合計)距離だけを移動できるようになります。したがって、問題は、「どこまで回転するか」/「どこまで回転する必要があるか」/「どこで回転する必要があるか」を理解することです。おそらく、通常の経路を決定することから始めて、一定の角度を超える角度に向けて、ターンの開始点に戻る必要があります。直線のパスでは、最終的な距離がカーブよりも長くなることに注意してください。
時計じかけのミューズ

はい、移動距離が主な制限要因です。ここでの最大のハードルは、距離が空いている限り、到達できる任意の時点でピースが回転し、回転し続けることを考慮する必要があることです。
sfphilli 2013

ユニットが移動できる範囲とはどういう意味ですか?あなたはそれが移動できるポイントを意味しますか?線形代数(ベクトル)についてどの程度知っていますか?
BlueRaja-Danny Pflughoeft 2013

1
モデル化しようとしている実際のシナリオは何ですか?あなたの問題は要件に対して曖昧すぎるため、提案されるソリューションアプローチが多すぎます。この領域の(実質的に)すべての特定の問題に対するよく知られているアプローチがありますが、皆さんが実際に取り組んでいるこれらの多くの問題のどれかを推測しています。
Pieter Geerkens 2013

1
@PieterGeerkens OPはコードを要求していないため、アルゴリズムを要求していると思います。そして、アルゴリズムが合理的に考えられるシナリオについて十分な詳細を提供しました。これは一般的で許容範囲です。
MichaelHouse

回答:


4

Dijsktraを使用して、流れまたは距離フィールドを生成します。

基本的に、宛先のないダイクストラアルゴリズムを使用してグリッドに入力します(おそらく別の名前です;知らないので)。各オープンノードを取得し、到達可能なネイバーを計算し、それらをオープンリストにプッシュし、クローズリストに設定し、親ノードの「次の」パスを適切に更新するなどします。新しいノードに到達するためのコストを決定するときは、回転制限を考慮してください。

結果として、最初に戻る方法について、すべてのノードのネットワークができます。到達できないノードは、最初のステップで操作されていません。到達可能なノードには、「親への最適なパスに沿った次のノード」要素が計算されるため、すべてのノードを強調表示し、この情報を使用して、ユーザーが強調表示された領域をホバーまたはクリックしたときに移動パスを表示または実行できます。


コンセプトをどのように説明するか、どのように実装するかではなく、確かに正しいアプローチです。
Pieter Geerkens 2013

アルゴリズムについての現状の理解は、ノードトラバーサルはパスに依存しない必要があるということです。そのため、これを実現するには、対面専用の別の自由度(ノードを作成するための別の軸)を追加する必要があります。つまり、異なるX、Y、場合によってはZ、および向きの組み合わせごとにノードがあります。それ以外の場合、ノードに入る最短経路を見つけても、ノードを離れるときに異なる方向を区別できません。あれは正しいですか?それが事実である場合、この方法は多すぎるかもしれませんか?
TASagent 2013

@TASagent:良い点、私はそれを完全に考えていませんでした。アルゴリズムはおそらく少しずれていますが、アプローチはうまくいくはずです。
Sean Middleditch 2013

@PieterGeerkens:それは悪い説明だと思う。あなたはそれをすべてよりよく説明するあなた自身の答えを作るべきです。
Sean Middleditch 2013

これは私が必要としているものにかなり近いようですが、そのアルゴリズムについて聞いたことがないことを認めざるを得ないので、必要なものに一般化する方法がわかりません。良い情報やチュートリアルへのリンクがありますか?
sfphilli 2013

4

ブルートフォースソリューションは次のようになります。

  1. ユニットを中心にして、ユニットの周りに頂点の円を作成します。円の半径が最大移動距離です。頂点の密度は、最終結果をどの程度詳細にしたいかに応じて変化します。
  2. 各頂点の位置について、その位置に向かうユニットステアリングの動きをシミュレートします。これは、レンダリングせずにタイトなループで行われます。
  3. ステアリングシミュレーションで最大距離に達したら、頂点をシミュレーションされたユニットのポイントに移動します。このポイントは、現在のターンが終了する前にユニットがその頂点に到達できる最も近いポイントです。これは、円を実際の動きのサイズに縮小する効果があります。
  4. これらの頂点とユニットの中心にある頂点を使用して、レンダリング可能な円を作成し、可能な移動距離を描画します。

ここに画像の説明を入力してください

したがって、青い円から始めて、パスを処理し、最後に紫色の円で終わります。次に、これらの点をユニットの中心点と一緒に使用して、形状の表示に必要な赤い三角形を作成できます。(その画像を作成するだけで、その形状が正しくないことに気づきますが、実際に何が正しいかを見るのは興味深いでしょう)


3

ショーンのソリューションは、最初に提案していたものとは異なるアプローチを表すため、別の回答で詳しく説明します。

このソリューションは、おそらく最もアクセスしやすい方法です。環境をノードに分割する必要があります。はい、これはグリッドベースのアプローチを再導入したものですが、比較的細かくすることも、ノード内で処理されるより細かい位置付けで広範なパスファインディングに使用することもできます。ノード構造が粗いほど、パスファインディングが速くなります。

ここでの大きな問題は、実際に船を向いていることです。そのため、多くの従来のパスファインディングソリューションは、変更なしでは使用できません。これらは通常、パスに依存しないため、現在のノードに到達する方法は関係ありません。加速、減速、および回転が瞬時に自由である場合、これは正常に機能します。残念ながらあなたのために回すことは無料ではありません。ただし、この簡略化では実際にドロップされる情報が1つ余分にあるため、別の変数としてエンコードできます。物理学では、これはフェーズスペースとして知られています。

ここでは2次元と仮定すると、3を推定できます。

通常、許容される離散座標位置ごとに1つのノードが必要です。例えば:

(0,0) - (1,0) - (2,0)
  | \  /  |  \  / |
(0,1) - (1,1) - (2,1)

等々隣接するポイントのノードグラフを作成し、それらを空間隣接で接続します。次に、ダイクストラのアルゴリズムを使用して、探索されたノードに接続されたままの探索されていない生きているノードがなくなるまで、ターンに許可された移動値を超えるノードを削除します。各ノードは、ノードに到達するために必要な最小距離を追跡します。

このメソッドを拡張して回転で使用できるようにするには、この同じノードグラフを3次元で想像してください。Z方向は回転/対面に対応し、周期的です。つまり、+ Z方向に移動し続けると、開始した場所に戻ります。これで、隣接する位置に対応するノードは、その方向に対応するフェーシング間でのみ接続されます。通常どおり、既に探索されたノードに接続されているノードを反復処理します。このスキームでは、N、NE、E、SE、S、SW、W、NWに制限することをお勧めします。

このソリューションは、すべてのアクセス可能な領域の領域、およびそこに到達するための最適なパス、そこに到着したときの回転量、およびそこに到着したときのすべての方向を教えてくれます。

次に、実際にパスを実行するときに、より信頼できるように見せるために、自由に補間/三次スプラインをかけます。


1
これは素晴らしいです。アルゴリズムについて少し調べて、ゲームオーバーで実験する必要がありますが、特にゲームの他のいくつかの重要な部分に一般化できるため、これは本当にぴったりだと思います。
sfphilli 2013

1

外出先での作業をどの程度正確に行うかを最初に決定する必要があるようです。次のようなオプション:

  • 円錐内で移動する場合は、最初に回転してから移動を開始します。これは、実装およびパスが容易なソリューションです。面白くないので使いたくないです。

  • 移動中の連続回転、合計45度まで。これはかなりトリッキーで、うまくいけばあなたが求めているものです。固定タイムステップを使用してパス上で数値的に統合することは、おそらくこれにアプローチする最も簡単な方法です。コーンは、最大(ステップごとに+ X度)および最小(ステップごとに-X度)の回転によって制限されます。

これらの2番目の要件でスペースをどのように移動するのが最善かは、それらが移動する環境に大きく依存します。トラバースしなければならない障害がたくさんある場合、物事は非常にトリッキーで非常に高価になる可能性があります。ただし、ない場合は、ローテーションをフロントローディング(さらにはテーパーオフ)して、目的の場所に配置することができます。

あなたが質問したトピックを部分的にしかカバーしていないと感じているので、コメントに追加してください。ディスカッションを拡大できます。


私は、パスに沿って任意のポイントで、たとえばすべてのポイントで45度まで回転するという2番目のオプションを使用したいと思います。障害物もあり、それぞれが破片よりも大きくなります(巨大な岩を考えてください)。私がこれについて最初に考えていた方法は、可能なエンドポイントのコーンを生成し、それらのエンドポイントごとに新しいコーンを生成することでした。そうは言っても、狂ったように複雑化することなくこれを実装する方法を完全に確信しているわけではありません。
sfphilli 2013

うーん、詳細の一部が少し不明だったようです。質問を振り返ると、「ターンベース」を指定していて、ユニットはターンで「回転または移動」できることがわかりました。それでは、プレイヤーが何ターンも前に自分の行動をプロットし、彼らが動いている間にパスファインディングを行いたいということですか?動きがどのように機能することになっているのかについてのさらなる説明が役立つでしょう。
TASagent 2013

いいえ、私が意味したのは、特定のターンで、プレイヤーは自分の駒をその場で好きなだけ回転させたり、すでに見ている方向に動かしたりできるということです。移動する場合、パスに沿って特定の距離を移動でき、移動中に特定の角度(-45〜45度など)まで回転または操縦できます。したがって、選択されたパスが左または右に移動するために曲線を含むと想像してください。パスは、プレイヤーが移動したいポイントを選択することにより、私が判断できない可能性のあるポイントの範囲内で決定されます。
sfphilli 2013

わかりましたので、残念ながら、残念ながら、希望する特性は、上記で取り上げたダイクストラアルゴリズムに対して制限が多すぎる可能性があります:-\。たぶん。後で家に帰ったときに、このためにいくつかのことをスケッチします。
TASagent 2013

収集したこの情報の一部を編集して、問題を元の質問に明確にして、後で来た人がより多くの情報から開始できるようにすることができます。
TASagent 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.