Jak sprawić, by istota poruszała się w określonym kierunku?

11

Mam Entityinstancję, która jest aktualizowana przy każdym zaznaczeniu gry. Załóżmy, że istota stale się rozwija. Chciałbym móc nadać kąt istoty funkcji, która powoduje, że porusza się ona w tym kierunku:

moveForward(90);powinien sprawić, by przesunęli się w prawo. Jeśli zadeklaruję swoją rotację jako globalną int, to zrobię to

moveForward(rotation);
rotation++;

sprawiłoby, że jego ruch śledziłby małe kółko.

W jaki sposób mogę to zrobić? Zakładam, że dotyczy to matematyki wektorowej; Nie znam żadnego, więc miłe byłoby krótkie wyjaśnienie.

Shaun Wild
źródło

Odpowiedzi:

16

W najprostszym sensie masz coś takiego.

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

Szybkość jest jednak szybka, ale wróg jest w stanie określić, o ile powinni poruszać się w kierunku x i o ile poruszają się w kierunku y, biorąc grzech lub cos kąta i mnożąc przez prędkość. Ponieważ...

 sin(a) = x / speed

Więc:

 x = speed * sin(a)

I:

cos(a) = y / speed

Więc:

y = speed * cos(a)

W twoim przykładzie moveForward(90)ustąpiłby speed * sin(90)lub speed * 1w kierunku x i / speed * cos(90)lub 0w kierunku y (powinien przesuwać się w prawo, jak określono). To powinno zacząć od podstaw w sensie podstawowym.

Czyniąc to ogólnie:

moveForward(float angle)
{
    x += speed * sin(angle);
    y += speed * cos(angle);
}
Kevin DiTraglia
źródło
Ahh, to o wiele prostsze, niż sobie wyobrażałem, wielkie dzięki :)
Shaun Wild
Jestem pewien, że musisz zmienić y i x. sin (alfa) = b / c.
jcora,
@ Pasuje do rysunku, który wykonałem SOH-CAH-TOA, sin jest przeciwny do przeciwprostokątnej, która na rysunku jest x / prędkość. Gdyby kąt znajdował się po drugiej stronie trójkąta, byłby odwrócony (a jeśli jest to bardziej praktyczne dla celów projektowania gry, mógłbym go zmienić, ale czuję, że to wszystko arbitralne).
Kevin DiTraglia,
Używam telefonu komórkowego, więc trudno było to zinterpretować. Właśnie
przejrzałem
To naprawdę ładny trójkąt, który tam masz. +1
Bro Kevin D.
3

Inna odpowiedź jest na razie błędna, aby poprawnie poruszać się po płaszczyźnie w oparciu o obrót, wykonaj następujące czynności:

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

Jednak polecam utworzenie zmiennej dla cos / sin, którą aktualizujesz tylko wtedy, gdy zmienia się obrót, więc nie obliczasz jej 4 razy tyknięciem.

StrafeSpeed ​​poruszałby się z boku na bok, a prędkość do przodu do poruszania się do przodu wzdłuż rotacji.

edycja: tesselode robi to samo, tyle że nie ma ruchu z boku na bok.

teh8bits
źródło
2

Powiedziałeś, że aktualizacja zaznacza, więc zakładam, że nie masz zmiennej liczby klatek na sekundę. W takim razie:

x + = prędkość * matematyka. kąt (kąt)

y + = prędkość * matematyka.sin (kąt)

Jeśli używasz zmiennej liczby klatek na sekundę, musisz także pomnożyć przez czas delta.

tesselode
źródło