Como faço para que uma entidade se mova em uma direção?

11

Eu tenho uma Entityinstância que é atualizada a cada tick do jogo. Vamos apenas assumir que a entidade avança constantemente. Eu gostaria de poder atribuir o ângulo da entidade a uma função que a faz se mover nessa direção:

moveForward(90);deve fazê-los mover para a direita. Se eu declarasse minha rotação como global int, então fazer

moveForward(rotation);
rotation++;

o faria traçar um pequeno círculo com seu movimento.

Como posso fazer isso? Suponho que isso envolva matemática vetorial; Eu não conheço, então uma breve explicação seria legal.

Shaun Wild
fonte

Respostas:

16

Bem, no sentido mais simples, você tem algo parecido com isto.

   y  |\
      | \
   m  |  \         s
   o  |   \        p
   v  |(a) \       e
(y)e  |angle\      e
   m  |      \     d
   e  |       \
   n  |        \
   t  |         \
      |__________\
      x movement
        (x)

A velocidade é, contudo, a velocidade do inimigo, e você pode determinar quanto eles devem se mover na direção x e quanto eles se movem na direção y, pegando o pecado ou cos do ângulo e multiplicando pela velocidade. Porque...

 sin(a) = x / speed

Assim:

 x = speed * sin(a)

E:

cos(a) = y / speed

Assim:

y = speed * cos(a)

No seu exemplo moveForward(90)renderia speed * sin(90)ou speed * 1na direção x e speed * cos(90)ou0 na direção y (ele deve se mover para a direita, como você especificou). Isso deve começar no sentido básico.

Tornando geral:

moveForward(float angle)
{
    x += speed * sin(angle);
    y += speed * cos(angle);
}
Kevin DiTraglia
fonte
Ahh, isso é muito mais simples do que eu imaginava, muito obrigado :)
Shaun selvagem
Eu tenho certeza que você precisa mudar y e x. sin (alfa) = b / c.
Jcora # 14/12
@Bane corresponde ao desenho que fiz SOH-CAH-TOA, o pecado é oposto à hipotenusa, que no desenho é x / velocidade. Se o ângulo estivesse do outro lado do triângulo, ele seria revertido (e se isso for mais prático para o objetivo do design de jogos, eu poderia alterá-lo, mas acho que tudo é arbitrário).
Kevin DiTraglia
Estou no meu celular, então foi muito difícil interpretar isso. Eu apenas desnatado sobre as fórmulas ...
jcora
Esse é um triângulo muito legal que você chegou lá. 1
Bro Kevin D.
3

A outra resposta está errada a partir de agora. Para mover-se corretamente ao longo de um plano com base em uma rotação, faça o seguinte:

posX += Math.cos(rotation) *  forwardSpeed + Math.sin(rotation) * strafeSpeed;
posY -= -Math.cos(rotation) * strafeSpeed + Math.sin(rotation) * forwardSpeed;

No entanto, eu recomendo criar uma variável para cos / sin que você atualize apenas quando a rotação mudar, para que você não a calcule 4 vezes por carrapato.

O strafeSpeed ​​se moveria de um lado para o outro, o forwardSpeed ​​para avançar ao longo de sua rotação.

edit: tesselode faz a mesma coisa, exceto que ele não tem movimento de um lado para o outro.

teh8bits
fonte
2

Você disse que os ticks de atualização são, portanto, suponho que você não tenha uma taxa de quadros variável. Se então:

x + = velocidade * math.cos (ângulo)

y + = velocidade * math.sin (ângulo)

Se você estiver usando taxa de quadros variável, também precisará multiplicar por tempo delta.

tesselode
fonte