Skocz do zawartości

Gładkie kolizje przy użyciu joysticka


Wojzax

Rekomendowane odpowiedzi

  • Filar Społeczności

Mam problem z kolizjami gracza ze ścianą. Top-down, gracz ma kwadratową maskę, ściany mają kwadratowe maski.

Do sterowania używam wyświetlanego na ekranie joysticka (w zależnosci od kierunku i odległości na jaki zostanie naciągnięty zmienia się direction gracza (360 stopni) i speed gracza (0-2).

Kiedy gracz podchodzi do ściany to owszem, zatrzymuje się, ale kiedy skieruje się joystick w bok, gracz zamiast ślizgać się po prostu się zacina. Dopiero skierowanie go w przeciwnym do ściany kierunku uwalnia go.

Próbowałem to rozwiązać różnymi sposobami, place_meeting na przykład, ale nie potrafi się wtedy ślizgać po ścianach, albo place_free ale wtedy z kolei ekran trzęsie się niemiłosiernie.

Co robić? W przypadku sterowania w czterech kierunkach nie było nigdy problemu, ale w 360 stopniach problem jest olbrzymi. Pomóżcie!

Odnośnik do komentarza
Udostępnij na innych stronach

Musisz rozdzielić kolizję na 2 osie z osobna. Nie sprawdzaj kolizji w obu osiach na raz w jednym warunku bo wtedy zatrzymasz ruch w obu a tego nie chcesz, chcesz zatrzymać 1 oś.

 

prosty przykład:

dla sztywnych kierunków

GML
if ( keyboard_check( vk_left ) ) if ( !place_meeting(x - predkosc, y, Wall) ) x -= predkosc;

if ( keyboard_check( vk_right ) ) if ( !place_meeting(x + predkosc, y, Wall) ) x += predkosc;

if ( keyboard_check( vk_up ) ) if ( !place_meeting(x, y - predkosc, Wall) ) y -= predkosc;

if ( keyboard_check( vk_down ) ) if ( !place_meeting(x, y + predkosc, Wall) ) y += predkosc;

 

lub dla twojego analogu

GML
// wektor ruchu

HS = hspeed;

VS = vspeed;

if ( !place_meeting(x+HS, y, Wall) ) { x += HS; hspeed = 0; }

if ( !place_meeting(x, y+VS, Wall) ) { y += VS; vspeed = 0; }

Odnośnik do komentarza
Udostępnij na innych stronach

Najlepsze rozwiązanie jakie znam jest z oficjalnego tutoriala od Marka Overmarsa.

GM Tutorial - First Person Shooter

 

GML (kolizja)
{

x = xprevious;

y = yprevious;

if (abs(hspeed) >= abs(vspeed) &&

not place_meeting(x+hspeed,y,obj_wall_basic))

{ x += hspeed; exit;}

if (abs(vspeed) >= abs(hspeed) &&

not place_meeting(x,y+vspeed,obj_wall_basic))

{ y += vspeed; exit;}

speed = 0;

}

Odnośnik do komentarza
Udostępnij na innych stronach

  • Filar Społeczności

@Threef:

ale wtedy np. w takiej sytuacji:

kzVxmyt.png

nie działa poprawnie, bo kiedy ustala się kierunek tej czerwonej strzałki to postać się nie ślizga.

 

Próbuję sposobu I am Lorda z rozdzieleniem osi, ale ciągle coś robię źle.

Odnośnik do komentarza
Udostępnij na innych stronach

GML
//Horizontal collision checking

if (place_meeting(x + hor_speed,y,WALLS))

{

while(! place_meeting(x+sign(hor_speed),y,WALLS))

{

x += sign(hor_speed);

}

hor_speed = 0

}

//Vertical collision checking

if (place_meeting(x,y+vert_speed,WALLS))

{

while(!place_meeting(x,y+sign(vert_speed),WALLS))

{

y += sign(vert_speed);

}

vert_speed = 0;

}

//Move!!!

x += hor_speed;

y += vert_speed;

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...