6

斑鳩に似た Android 用のアーケード シューティング ゲームに取り組んでいます。私が直面している問題は、敵の移動パターンと射撃パターンを堅牢に作成することが非常に難しいことがわかっていることです。現時点では、2 つの抽象クラス EnemyShip と FlightPath を作成しました。これらのクラスから、それぞれ異なる敵と移動パターンが派生します。World が作成されると、次の形式でレベル情報を格納する LevelManager がインスタンス化されます。

waveInfos.add(new WaveInfo(3, 3f)); // new WaveInfo(NumberOfGroups, spawn interval)
enemyGroups.add(new EnemyGroup(8, EnemyGroup.TYPE_SCOUT_SHIP, EnemyGroup.F_PATH_INVADERS));
enemyGroups.add(new EnemyGroup(1, EnemyGroup.TYPE_QUAD_SPHERE, EnemyGroup.F_PATH_QUAD_SPHERE_L, World.BLACK));
enemyGroups.add(new EnemyGroup(8, EnemyGroup.TYPE_SCOUT_SHIP, EnemyGroup.F_PATH_INVADERS));
// new EnemyGroup(NumberOfEnemies, EnemyType, FlightPathType)
// new EnemyGroup(NumberOfEnemies, EnemyType, FlightPathType, ShipColour)

waveInfos.add(new WaveInfo(2, 0.33f));
enemyGroups.add(new EnemyGroup(1, EnemyGroup.TYPE_QUAD_SPHERE, EnemyGroup.F_PATH_QUAD_SPHERE_L, World.WHITE));
enemyGroups.add(new EnemyGroup(1, EnemyGroup.TYPE_QUAD_SPHERE, EnemyGroup.F_PATH_QUAD_SPHERE_R, World.WHITE));

totalWaves = waveInfos.size();

レベルは敵のグループの波に分割され、現在、EnemyGroup クラスがインスタンス化を処理し、指定された FlightPath を新しく作成された敵に追加し、その敵を LevelManager の ArrayList に渡して、必要なときにワールドにスポーンされるまで保存します。

生成されると、FlightPath コンポーネントが引き継ぎ、独自の stateTime に基づいて指示を出し始めます。各 FlightPath には EnemyShip 所有者への参照フィールドがあるため、制御している船の関数とメンバーにアクセスできます。

EnemyShip クラスには、moveTo(float x, float y, float duration) や shot() などの簡単な指示のための関数がいくつかありますが、これらを使用しても、特に同じグループ内の異なる敵に持たせたい場合は、FlightPath の派生物を作成するのは困難です。わずかに異なる経路とわずかに異なる到着時間。

キーフレームを追跡するために、FlightPath にいくつかのフィールドを作成しました。

public int currentKeyFrame = 0;
public int totalKeyFrames;
public KeyFrame[] keyFrames; // Stores duration of instruction to be done, the spreadTime, totalFrameTime and enemyIntervalTime
public int shipNumber; // Stores which ship out of group this FlightPath is attached to
public int totalShips; // Stores total number of ships in this EnemyShip's group
public float stateTime = 0;

KeyFrame.spreadTime は、グループ内の最初の敵が移動/射撃を開始してから最後の敵までの時間を制御する試みです。

KeyFrame.totalFrameTime = KeyFrame.duration + KeyFrame.spreadTime

KeyFrame.enemyIntervalTime = KeyFrame.spreadTime / このグループ内の敵の数

このセットアップは、非常に単純な直線的な動きにはうまく機能しますが、かなり面倒に感じます。

ここまで読んでくれてありがとう。私の質問は、グループ内の他の敵が何をしているかなどを確認するための if() ステートメントの大群なしで複雑な動きを可能にする、より合理化されたパターン コントロールをどのように実装するかということです。

敵がどのように扱われるかを理解するのに十分な情報を提供できたことを願っています. 興味のある方にはソースコードを提供します。この件についてご意見をお寄せいただきありがとうございます。

マリオス・カロゲロウ

編集:私が望むものに最適なシステムの種類を非常に詳しく説明しているページを見つけましたが、グループ全体のキーフレームに関してそれを正しく実装する方法がわかりません

http://www.yaldex.com/games-programming/0672323699_ch12lev1sec3.html

4

2 に答える 2

1

FlightPath はオブジェクトを制御するべきではありません。マネージャーではなく、パスです。ただし、任意のキーフレームまたは時間を指定して座標を指定できる必要があります。例: flightPath.getX(1200)-> 1200ms で X 座標のどこにいるべきですか?

各 EnemyShip は、FlightPath インスタンスを保持する必要があります。EnemyShip は、フレームごとにパスのどこにいるべきかをチェックします。

次に、EnemyGroup が各 EnemyShip のスポーンを制御します。1 つの EnemyGroup に 8 つの EnemyShip があり、すべてが同じ FlightPath タイプを持っている場合、EnemyGroup が各船を約 500 ミリ秒間隔でスポーンして波を作成すると想像できます。

最後に、すべての EnemyShip 座標を、伝統的にゆっくりと垂直方向に移動するワールド/スクリーン座標に相対的に変換します。

于 2012-04-10T17:41:09.403 に答える
1

さまざまなアプローチがあります。

  1. 撮影前にランダムな間隔を追加したり、到着時間を少しランダムに設定したりできます。のようにcurrentEnemyArrivalTime += (X - rand(2*X))

  2. 敵のグループの動きを制御できます。グループ内の各敵は、グループの中心に対する位置を維持しようとします。

  3. 非常に複雑なパターンの場合は、単純なスクリプト エンジンを開発する方がよい場合があります。非常に単純なもの ( splineの係数の配列など) にすることも、より複雑なものにすることもできます。そのようなゲームでは、動作はスクリプトによって行われると思います。

于 2012-04-10T17:27:52.720 に答える