벡터를 사용하여 XNA / C #에서 스프라이트 이동


9

나는 현재 C # 언어로 XNA 게임 개발을 찾고 있습니다.

메인 게임 핸들러와 "스프라이트"클래스라는 두 가지 클래스가 있습니다. 다음은 문제를 적절하게 설명하기위한 기본적인 의사 코드입니다.

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 좌표가 사용되며 게임 개체는 일정 기간 동안 해당 위치를 향해 이동합니다.

글쎄 ... 코드는 작동하지만 추악하고 객체는 객체를 향해 직접 움직이지 않습니다 (대각선 움직임, 단일 축 움직임). 사용할 수있는 몇 가지 수학적 함수가 있다고 생각하지만 솔직히 어디에서 시작할 지에 대한 실마리는 없습니다. 어떤 제안?


3
손님 안녕하세요. 당신이 찾고있는 것은 정규화입니다. 이 질문에 대한 답변을 읽어 보시기 바랍니다 : gamedev.stackexchange.com/questions/7540/...를 . 하나는 필요한 코드를 제공하고 다른 하나는 어떻게 작동하는지 설명합니다.
Notabene

안녕하세요, 나는 링크를 보았고 그것은 내가 필요한 것입니다. 감사합니다!
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

정확히, 나는 나의 포스트를 편집하려고했지만, 나는 그렇지 않을 것이라고 생각한다. 스프라이트가 지속적으로 대상을 찾지 않게하려면 방향이 대상에 충분히 가까이있을 때 Vector2.Zero로 설정하십시오.
Jesse Emond

아주 좋은 대답 ... 그리고 당신은 또한 느린 시간의 컴퓨터에서 적절한 속도로 스프라이트를 이동시키기 위해 gameTime의 사용에 대해 가르쳐주었습니다. 이 답변을 수락 된 것으로 표시하겠습니다.
Matt

:) 개인적으로 클래스 외부에서 지속적으로 정규화하지 않아도되도록 스프라이트 클래스 (업데이트 기능 내부)에 정규화를 넣는 것을 개인적으로 좋아합니다. 또한 벡터의 길이가 0이 아닌지 확인해야합니다. 그렇지 않으면 0으로 나누기 예외가 발생합니다. Safety.LengthSquared ()> 0이 안전한지 표준화하기 전에 확인하십시오 (길이 제곱이므로 고가의 제곱 함수를 계산할 필요가 없습니다;)).
Jesse Emond

정규화 함수가없는 다른 IDE를 사용한다고합시다. 정규화 방정식은 무엇입니까?
Spooks

2

구글 정규화 ... 나는 또한 이것에 약간 잃어 버렸지 만, 이것이 당신의 문제를 해결하는 데 도움이 될 것이라고 확신합니다. 다른 사람이 내 대답을 정교하게하거나 반증 할 수 있습니다.

편집 : 나는 이것에 더 잘 대답 할 수있다, 사과

나는 개인적으로 항상 이러한 유형의 문제를 돕기 위해이 블로그 게시물을 찾습니다 : http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

처음부터 시작하여 게임 개발과 관련이 있습니다.


3
당신 말이 맞아요. 정상입니다. 그러나 이전 질문에서 좋은 답을 찾으려고 노력하는 것이 항상 좋습니다. 그리고 대답하고 있다면 코드를 설명하거나 공유하거나 유용하다고 생각되는 것을 거의 Google에 알려주지 않는 것이 좋습니다.
Notabene

내가 말 했어야했는데 네 말이 맞아
Douglas Rae
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.