チェイスゲームでプレイヤーに直線で敵の動き


10

私は、敵がマップ上でランダムに出現し、ランダムな速度でフレームごとにプレイヤーに向かって移動するゲームを作成しています。マップには障害物がないため、敵は常に直線的に移動する必要があります。私は数回ムーブメント関数を書きましたが、敵が常に0、45、90、135、180、225、270、315の角度に当たったとしても、決して直線にはなりません。次にコードの例を示します。

    base_speed = random();

    diff_x = abs(enemy_y_pos - player_x_pos);
    diff_y = abs(enemy_x_pos - player_y_pos);
     if (diff_x > diff_y) {
      y_speed = base_speed;
     } else if (diff_y > diff_x) {
      x_speed = base_speed;
     }

     if (enemy_x_pos < player_x_pos) {
      velocity.x = x_speed;
     } else if (enemy_x_pos > player_x_pos) {
      velocity.x = -x_speed;
     } else {
      velocity.x = 0;
     }

     if (enemy_y_pos < player_y_pos) {
      velocity.y = y_speed;
     } else if (enemy_y_pos > player_y_pos) {
      velocity.y = -y_speed;
     } else {
            velocity.y = 0;
    }

    enemy_x_pos = enemy_x_pos + velocity.x;
    enemy_y_pos = enemy_y_pos + velocity.y;

これがゲームプログラミングの私の最初の試みです。Bresenham's Line(http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm)のようなアルゴリズムを使用する必要があると思いますが、実装しようとする試みには同じ問題があります。敵をまっすぐに動かすにはどうすればよいですか?

回答:


17

ブレゼンハムの線アルゴリズムは、浮動小数点演算を使用せずに線を高速で描画するために開発されました(整数演算はより高速です)。これは非常に興味深い歴史的ですが、ゲームにはあまり良い解決策ではありません(特に速度を指定できないため)。

2D移動を行う場合は、常にベクトルを使用します。これはあなたのためにすべてのものを行います。時々代数学は素晴らしいです。

Vec2d playerPos;
Vec2d direction; // always normalized
float velocity;

update()
{
   direction = normalize(playerPos - enemyPos);
   playerPos = playerPos + direction * velocity;
}

確かに、ターゲット言語用のvector2Dクラスがいくつかあります。


それは完璧に機能しました。正規化は私が必要とした機能でした。ありがとう。
user4761 2011年

9

すべてのフレームを計算していますか?コードは、x_speedまたはy_speedのいずれかを乱数に設定し、もう一方をゼロ(またはデフォルト)に設定します。敵が0、0にいて、プレーヤーが20、10にいるとします。これは、x_speedをフレームごとに乱数に設定し、敵が10、0になるまで右に移動するように見えます。その後、敵は移動しますフレームごとにxまたはyのいずれかで、10、10まで45度の角度で移動しているように見えます。

Notabeneのベクトル説明は正しいですが、ここではその仕組みを説明します。Vec2dには、xおよびyコンポーネントがあります。上記の例では、playerPos-enemyPosは(20、10)のベクトルを提供します。normalize()は、長さが1になるようにベクトルを変更します。現在、長さはsqrt(20 * 20 + 10 * 10)です。それは約22.36068です。normalizeはXとYの両方をこの数で除算し、方向に約(0.89443、0.44721)を与えます。これは、敵から長さ1のプレイヤーを指すベクトルです。これにランダムな速度を掛けると、思い通りになります。

ただし、フレームごとに新しいランダム速度を計算しません。おそらく、ランダムな速度を1回だけ設定するか、各フレームに近づくような初速度と目標速度を設定します。敵が最初に100 mph、次に1フレームで50 mph、次のフレームで200 mphになるのは意味がありません。

float targetSpeed = random(); // do this only rarely, or each frame if you don't mind slowing down and speeding up constantly

float acceleration = max(abs(targetSpeed - speed), 0.5) * sgn(targetSpeed - speed); // cap accel/decel at 0.5 per frame
speed = speed + acceleration;

いい説明と追加ジェイソン、ありがとう。私はあなたの加速機能が好き
Notabene

そのスコープ内のrandom()はタイプミスでした。notabeneが書いたものを使用した説明とコードは、ゲームを動作させるのに役立ちます。ありがとう。
user4761 2011年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.