Movendo um sprite em XNA / C #, usando vetores

9

Atualmente, estou olhando para o desenvolvimento de jogos XNA com a linguagem C #.

Eu tenho duas classes: o principal manipulador de jogos e uma classe "sprite". A seguir, apresentamos alguns pseudocódigos básicos que, espero, descrevam adequadamente o problema.

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
    }
  }
}

Basicamente: quando o usuário clica em algum lugar da janela do jogo, as coordenadas xey do mouse são tomadas, e o objeto do jogo se move em direção a esse local por um período de tempo.

Bem ... o código funciona, mas é feio e os objetos não se movem diretamente em direção ao objeto (em vez disso, é um movimento diagonal, seguido pelo movimento de eixo único). Acho que existem algumas funções matemáticas que posso usar, mas sinceramente não tenho idéia de por onde começar. Alguma sugestão?

Matt
fonte
3
Olá convidado. O que você está procurando é normalização. Leia as respostas para esta pergunta: gamedev.stackexchange.com/questions/7540/… . Um oferece o código que você precisa, o segundo explica como funciona muito bem.
Notabene
Olá, olhei o link e era exatamente o que eu precisava. Obrigado!
Matt

Respostas:

12

Se eu entendo seu problema corretamente, você deve ter uma direção Vector2 representando a direção que deseja mover dentro da sua classe de sprite. Como isso:

public Vector2 Direction { get; set; }

Este é o vetor normalizado (o que significa que ele tem um comprimento de 1) mostrando para onde você deseja ir.

Em seguida, adicione uma propriedade Speed ​​float, que indica a rapidez com que o sprite deve ir.

public float Speed { get; set; }

Você também precisa adicionar uma função UpdateSprite. Por que não colocá-la na sua classe Sprite?

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

Isso atualizará a posição do sprite para fazê-lo se mover (você multiplica pelos segundos delta para que o sprite se mova corretamente também em computadores lentos).

Por fim, você acabou de definir sua propriedade direction como esta:

sprite.Direction = location - sprite.Position;
sprite.Direction.Normalize();
Jesse Emond
fonte
Observe também que, se o comprimento do sprite.Direction (antes da normalização) for menor que algum limite, seu sprite chegou.
precisa saber é o seguinte
Exatamente, eu estava prestes a editar minha postagem, mas acho que não vou. Se você não quiser que seu sprite procure constantemente o alvo, defina a Direção como Vector2.Zero quando estiver próximo o suficiente do alvo.
Jesse Emond
Resposta muito boa ... e você também me ensinou sobre o uso do gameTime (mover sprites a uma velocidade apropriada em computadores mais lentos), então dois coelhos com uma cajadada só. Vou sinalizar esta resposta como aceita.
Matt
:) A propósito, eu pessoalmente gosto de colocar a normalização dentro da minha classe sprite (dentro da minha função de atualização), para evitar ter que normalizá-la constantemente fora da classe. Você também deve garantir que o comprimento do vetor não seja igual a 0, caso contrário, você receberá uma exceção de divisão por 0. Basta verificar se Direction.LengthSquared ()> 0 antes de normalizá-lo para ser seguro (comprimento ao quadrado para que você não precise calcular essa função quadrada cara;)).
Jesse Emond
Digamos que estamos usando um IDE diferente que não tivesse uma função normalizar, qual seria a equação Normalizar?
Assustadores
1

Normalização do Google ... também estou um pouco perdido com isso, mas tenho certeza de que isso ajudará a resolver seu problema. Alguém pode elaborar ou refutar minha resposta, tenho certeza

Edit: Eu poderia responder melhor, desculpas

Pessoalmente, sempre procuro este post do blog para ajudar com esses tipos de problemas: http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

Começa do zero e é relevante para o desenvolvimento de jogos.

Douglas Rae
fonte
3
Você está certo, é normalização. Mas é sempre melhor tentar encontrar uma boa resposta nas perguntas anteriores. E se você estiver respondendo, é sempre melhor explicar pouco ou compartilhar código ou o que você achar que pode ser útil, não apenas apontar para o google.
Notabene
Eu deveria ter comentado, você está certo.
Douglas Rae