Zdobywaj punkty na linii między dwoma punktami

9

Tworzę prostą grę kosmiczną w JavaScript, ale teraz uderzyłem o ścianę dotyczącą wektorów.

Widok gry jest z góry na dół na siatce 2D. Gdy użytkownik kliknie siatkę, statek kosmiczny poleci w to miejsce.

Więc jeśli mam dwa zestawy punktów:

{ x : 100.2, y : 100.6 }; // the ship
{ x : 20.5,  y : 55.95 }; // the clicked coordinates

Jeśli pętla gry tyka przy 60 iteracjach na sekundę, a pożądana prędkość statku wynosi 0,05 punktu na tik (3 punkty na sekundę), jak obliczyć nowy zestaw współrzędnych dla statku dla każdego tiku w pętli gry?

ps Nie chcę uwzględniać bezwładności lub wielu wektorów wpływających na statek, chcę tylko, aby statek zatrzymał cokolwiek robi (tj. leciał w jedną stronę) i poruszał się do klikniętych współrzędnych ze statyczną prędkością.

Stephen
źródło

Odpowiedzi:

8

W pseudokodzie:

speed_per_tick = 0.05
delta_x = x_goal - x_current
delta_y = y_goal - y_current
goal_dist = sqrt( (delta_x * delta_x) + (delta_y * delta_y) )
if (dist > speed_per_tick)
{
    ratio = speed_per_tick / goal_dist
    x_move = ratio * delta_x  
    y_move = ratio * delta_y
    new_x_pos = x_move + x_current  
    new_y_pos = y_move + y_current
}
else
{
    new_x_pos = x_goal 
    new_y_pos = y_goal
}
Tristan
źródło
@Tristan: Czy masz na myśli goal_distswój ifstan?
Nate W.,
21

LERP - interpolacja liniowa

Dałem tę odpowiedź na podobny problem kilka dni temu, ale proszę bardzo:

Interpolacja liniowa to funkcja, która daje liczbę między dwiema liczbami w zależności od postępu. Możesz faktycznie uzyskać punkt między dwoma punktami.


Wielka formuła - jak ją obliczyć

Ogólna formuła LERP została podana przez pu = p0 + (p1 - p0) * u. Gdzie:

  • pu: numer wyniku
  • p0: numer początkowy
  • p1: ostatnia liczba
  • u: Postęp. Podawany jest w procentach, od 0 do 1.

Jak uzyskać procent

Być może zastanawiasz się: „Jak mogę uzyskać ten odsetek !?”. Nie martw się To jest tak: ile czasu zajmie podróż do ukończenia wektora startowego? Ok, podziel to przez czas, który już minął. To da ci procent.

Zobacz coś takiego: percentage = currentTime / finalTime;


Obliczanie wektorów

Aby uzyskać wynikowy wektor, wystarczy zastosować formułę dwa razy, jeden dla komponentu X i jeden dla komponentu Y. Coś takiego:

point.x = start.x + (final.x - start.x) * progress;
point.y = start.y + (final.y - start.y) * progress;

Obliczanie zmiennego czasu

Możesz chcieć, aby twoje punkty podróżowały z prędkością 0,5 punktu, tak? Powiedzmy, że dłuższy dystans zostanie pokonany w dłuższym czasie.

Możesz to zrobić w następujący sposób:

  • Uzyskaj długość odległości Do tego potrzebne będą dwie rzeczy. Uzyskaj wektor odległości, a następnie przekształć go w wartość długości.

    distancevec = final - start;
    distance = distancevec.length();

Mam nadzieję, że znasz matematykę wektorów. Jeśli nie, możesz obliczyć długość wektora za pomocą tego wzoru d = sqrt(pow(v.x, 2) + pow(v.y, 2));.

  • Poświęć czas i zaktualizuj czas finałowy. Ten jest łatwy. Jeśli chcesz, aby każdy tyk dostał 0,5 długości, musimy tylko podzielić i ustalić, ile mamy tyknięć.

    finalTime = distance / 0.5f;

Gotowy.

UWAGA: Być może nie jest to zamierzona prędkość, ale jest to właściwe. więc masz ruch liniowy, nawet przy ruchach ukośnych. Jeśli chcesz zrobić x + = 0,5f, y + = 0,5f, to przeczytaj książkę wektorową i ponownie sprawdź swoje plany.

Gustavo Maciel
źródło
Co jeśli chcesz, aby% pozostał do miejsca docelowego ze swojej pozycji? JEŻELI nie możesz użyć czasu delta, ale współrzędne x: y.
Dave
Jeśli obliczono progresszgodnie z tą odpowiedzią, powinno ono mieścić się w 0..1zakresie. Po prostu zrób:progressLeft = 1.0 - progress;
Gustavo Maciel
3

Można tego dokonać, obliczając normalną kierunek, a następnie obliczając bieżącą pozycję za pomocą równania parametrycznego

newPoint = startPoint + directionVector * velocity * t

Gdzie t to czas, jaki upłynął od rozpoczęcia podróży statku w pożądanym kierunku. Możesz to również wykonać dla każdej aktualizacji za pośrednictwem

newPoint = currentPoint + directionVector * velocity * timeDelta

I po prostu obliczasz to dla każdej klatki / fizyki / etc. aktualizuj, aż statek dotrze do celu.

hatboyzero
źródło