Skip to content
第05回 プレイヤーを狙う敵弾

2 / 4 発射時の方向を求める

このステップの目的

発射位置から目標位置へ向かう方向を求め、弾速を一定にする

2点の差から方向を作る

目標位置から発射位置を引くと、発射位置から目標位置へ向かうベクトルになります。

考え方を示す擬似コードcpp
Vector2 direction = targetPosition - startPosition;

この1行は考え方を示す擬似コードです。開始プロジェクトのVector2には引き算の演算子がないため、そのまま貼り付けません。

この教材のVector2には演算子を用意していないため、実際にはX成分とY成分を個別に計算します。

方向を正規化する

差分ベクトルの長さは、発射位置と目標位置の距離によって変わります。 そのまま速度へ使うと、遠い目標ほど速く、近い目標ほど遅くなります。 長さで割って方向だけを取り出し、一定の弾速を掛けます。 std::sqrt()を使うための標準ライブラリのincludeは、開始用コードへ用意しておきます。

EnemyShot.cppcpp
// 05-1で一度{}にしたvelocityを、次の計算結果へ置き換える
Vector2 direction
{
    targetPosition.x - startPosition.x,
    targetPosition.y - startPosition.y
};

float length = std::sqrt(direction.x * direction.x + direction.y * direction.y);
if (length > 0.0f)
{
    direction.x /= length;
    direction.y /= length;
}

velocity =
{
    direction.x * tuning::enemyShot::Speed,
    direction.y * tuning::enemyShot::Speed
};

発射位置と目標位置が同じ場合は長さが0になるため、0で割らない条件を入れます。

数値で確認する

例えば発射位置が{100, 200}、目標位置が{130, 240}なら、差分は{30, 40}です。 長さは50なので、正規化した方向は{0.6, 0.8}になります。 ここへ弾速180を掛けると、1秒あたりの速度は{108, 144}です。 距離が変わっても、正規化後の方向の長さは1なので、弾の速さは変わりません。

チェックリスト
  • 差分ベクトルの向きが発射位置から目標位置へ向いている
  • 長さで割って方向の大きさをそろえている
  • 弾速を掛けてvelocityを設定している
  • 長さ0のときに0で割っていない