ベクトルを使用してXNA / C#でスプライトを移動する


9

現在、C#言語を使用したXNAゲーム開発を検討しています。

メインのゲームハンドラーと「スプライト」クラスの2つのクラスがあります。以下は、いくつかの基本的な疑似コードで、問題を適切に説明していると思います。

Game.cs

class game {
  sprite the_sprite;
  void update(time) {
    var mouse = mouse.state
    if(mouse.clicked) { this.the_sprite.moveTo(mouse.x, mouse.y) }
    this.the_sprite.update(time)
    base.update(time)
  }
}

Sprite.cs

class sprite {
  vector2 location;
  vector2 move_to;
  void moveTo(x, y) { this.move_to = new vector2(x, y) }
  void update(time) {
    if(this.location.x > this.move_to.x /* (or less than) */) {
      // adjust location.x
    }
    if(this.location.y > this.move_to.y /* (or greater than) */) {
      // adjust location.y
    }
  }
}

基本的に:ユーザーがゲームウィンドウのどこかをクリックすると、マウスのx座標とy座標が取得され、ゲームオブジェクトは一定期間その位置に向かって移動します。

ええと...コードは機能しますが、見苦しく、オブジェクトはオブジェクトに向かって直接移動しません(代わりに、対角線上の動きとそれに続く1軸の動きです)。使用できる数学関数はいくつかあると思いますが、正直なところ、どこから始めればよいかわかりません。助言がありますか?


3
こんにちはゲスト。あなたが探しているのは正規化です。この質問への回答を読んでください:gamedev.stackexchange.com/questions/7540/…。1つは必要なコードを提供し、2つ目はそれが非常にうまく機能する方法を説明します。
Notabene、2011年

こんにちは、私はリンクを見ました、そしてそれはまさに私が必要としたものでした。ありがとうございました!
Matt

回答:


12

私が問題を正しく理解している場合は、スプライトクラス内で移動したい方向を表すVector2が必要です。このような:

public Vector2 Direction { get; set; }

これは、行きたい場所を示す正規化されたベクトルです(つまり、長さが1であることを意味します)。

次に、スプ​​ライトの速度を示すSpeed floatプロパティを追加します。

public float Speed { get; set; }

また、UpdateSprite関数を追加する必要があるので、Spriteクラス内に配置しませんか?

public Update(GameTime gameTime)
{
   Position += Direction * Speed * gameTime.ElapsedGameTime.TotalSeconds;
}

これにより、スプライトの位置が更新されて移動します(低速のコンピューターでもスプライトが正しく移動するように、デルタ秒を掛けます)。

最後に、方向プロパティを次のように設定します。

sprite.Direction = location - sprite.Position;
sprite.Direction.Normalize();

また、(正規化前の)sprite.Directionの長さがしきい値よりも短い場合は、スプライトが到着したことにも注意してください。
TreDubZedd、2011年

正確に、投稿を編集しようとしていましたが、編集しないと思います。スプライトが常にターゲットをシークしたくない場合は、ターゲットに十分近いときにDirectionをVector2.Zeroに設定します。
Jesse Emond、2011年

非常に良い答えです。また、gameTime(遅いコンピューターでスプライトを適切な速度で移動するため)の使用についても教えてくれました。この回答には承認済みのフラグを付けます。
Matt

:)ちなみに、私は自分のスプライトクラス内(更新関数内)で正規化を行い、クラス外で常に正規化する必要がないようにしています。また、ベクトルの長さが0に等しくないことを確認する必要があります。そうしないと、0除算例外が発生します。安全になるように正規化する前に、Direction.LengthSquared()> 0かどうかを確認するだけです(長さが2乗されるため、高価な2乗関数を計算する必要はありません;))。
Jesse Emond、2011年

正規化関数を持たない別のIDEを使用しているとしましょう。正規化方程式は何でしょうか?
Spooks

1

Googleの正規化...私もこれで少し迷っていますが、これが問題の解決に役立つと確信しています。他の誰かが私の答えを詳しく説明したり反証したりできる

編集:私はこれをよりよく答えることができました、お詫び

私は個人的に常にこのブログ投稿を参照して、これらのタイプの問題を解決します:http : //blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

ゼロから始まり、ゲーム開発に関連しています。


3
あなたは正しい、それは正規化です。しかし、前の質問で良い答えを見つけるように試みることは常により良いです。そして、もし答えるなら、グーグルを指すだけでなく、コードについて少し説明したり共有したりするのに役立つと思うものは何でも常に良いです。
Notabene

私はコメントすべきだった、あなたは正しい。
Douglas Rae、2011年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.