なぜオブジェクトが90度よりも45度で速く動くのですか?


32

ゲームには、90度ではなく45度でより速く動くオブジェクトがあります。

各オブジェクトには

  • ポイント(x、y)位置
  • Vector2D(x、y)方向
  • Int速度

そして、更新中に私がすることは、新しい位置が次のように計算されるということです。

position.x += direction.x * speed
position.y += direction.y * speed

これを修正するにはどうすればよいですか?どんな角度でも同じ速度で動くようにしたい。


8
使用前に方向ベクトルを正規化します。問題が解決しました。
減速

1
グーグルでノーマライズする必要がありました:)この便利
Jason94

また、ユーザー入力を使用してこのオブジェクトを制御している場合は、XNA devsのxona.com/2010/05/03.htmlで説明されているように、12,3,6,9方向へのロックに注意してください。それはあなたが望むもの(RPGゲームなど)でもそうでないもの(Geometry Warsスタイルのゲームなど)でもかまいません。
Xonatron

古いゲームDescentでは、これは機能でした。
J.ホームズ

@ 32bitkidはい、Doom straferunning
bobobobo

回答:


55

これは、次の式であるピタゴラスの定理で説明できます。

a² + b² = c²

あなたの場合、右に移動するときは、(x:1、y:0)を使用しています。

c² = 1 + 0 = 1
c = sqrt(1) = 1.00

上下に移動するときは、(x:1、y:1)を使用しています。

c² = 1 + 1 = 2
c = sqrt(2) = 1.41

ご覧のとおり、対角線上の長さは基軸上の長さよりも長くなっています。

他の人が述べたように、単に方向ベクトルを正規化する必要があります。XNAを使用する場合、次のように実行されます。

var normalizedDirection = direction;
normalizedDirection.Normalize();
position += normalizedDirection * speed

私の質問であなたの助けのために+1を与えています:)
マーティン。

12

使用前に方向ベクトルを正規化します。

MindWorXで説明されているように、これは簡単に理解できます。方向ベクトルに不安を感じている可能性がある場合は、単位ベクトル(大きさ/長さ1)であることを確認してください。

Length(Vector2(1, 1)) == 1.4142135623730951 // first hint of grief
Length(Vector2(1, 0)) == 1

Vector2(1, 1) * 2 == Vector2(2, 2)
Vector2(1, 0) * 2 == Vector2(2, 0)

Length(Vector2(2, 2)) = 2.8284271247461903 // second hint
Length(Vector2(2, 0)) = 2

正規化されている場合:

normal(Vector2(1, 1)) == Vector2(0.707107, 0.707107)
Length(Vector2(0.707107, 0.707107)) == 1 // perfect

14
役に立つ答えではありません。質問者が「方向ベクトルの正規化」の意味を知っていれば、質問はしなかったでしょう。
クリストファージョンソン

@KristopherJohnson質問者がベクトルを正規化する方法を知らなかったのは明らかではありませんでした。質問者は十分に機知に富んでいるとはいえ、とにかく重要ではありませんでした。
減速

2
@KristopherJohnson:質問者が「方向ベクトルの正規化」の意味を知らなかった場合、彼はそれをグーグルに入力し、自分の言語の名前を追加し、説明付きのコードを取得するだけです。
ライライアン

6

方向をどのように計算していますか?45度がの場合(1,1)、90度よりも確実に速くなり(1,0)ます。

次のようなものを使用することをお勧めします。

direction.x = Math.Cos(angleInRadians);
direction.y = Math.Sin(angleInRadians);

ラジアン単位の角度を取得するにはPI / 180、を使用して度数を乗算する必要がありますMathHelper。例えば。

angleInRadians = 45.0 * Math.PI / 180.0; // first method
angleInRadians = MathHelper.ToRadians(45f); //second method

6

ジェイソン、

3つのオブジェクト属性を持つのではなく、

  • ポイント(x、y)位置
  • Vector2D(x、y)方向
  • Int速度

多くの場合、方向と速度を組み合わせて速度ベクトルにする方がはるかに簡単です。次に、2つの属性のみがあります。

  • ポイント(x、y)位置
  • Vector2D(x、y)速度

位置の更新

オブジェクトの位置を更新する必要があるときは、次のように簡単です。

position.x += velocity.x * Δt;
position.y += velocity.y * Δt;

Δtタイムデルタ、つまり時差、またはタイムステップはどこにありますか。

位置と速度を更新する

また、この方法で加速度を処理することも非常に簡単です(重力などから)。加速度ベクトルがある場合、次のように速度と位置を一緒に更新できます。

position.x += (velocity.x * Δt) + (0.5 * acceleration.x * Δt * Δt);
position.y += (velocity.y * Δt) + (0.5 * acceleration.y * Δt * Δt);

velocity.x += acceleration.x * Δt;
velocity.y += acceleration.y * Δt;

(これは基本的にPhysics 101のs = vt +½at²の式です。)

速度を適用する

特定の速度を正規化された方向に適用する場合、次のように速度を設定できます。

velocity.x = normalizedDirection.x * speed;
velocity.y = normalizedDirection.y * speed;

速度の導出

そして、逆を行う必要がある場合(特定の速度ベクトルから速度と方向を導出する場合)、ピタゴラスの定理または.Length()メソッドを使用できます。

speed = velocity.Length();

そして、速度がわかれば、速度を速度で除算することで正規化された方向を計算できます(ゼロで除算しないように注意してください)。

if (speed != 0) {
    normalizedDirection.x = velocity.x / speed;
    normalizedDirection.y = velocity.y / speed;
} else {
    normalizedDirection.x = 0;
    normalizedDirection.y = 0;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.