Skocz do zawartości

kolizje "całościowe"


sagi

Rekomendowane odpowiedzi

Witam

aktualnie robię gierkę na studia, od jakichś 2 tygodni przeglądam waszą stronę w poszukiwaniu pomocy gdy czegoś nie wiem, ale teraz mam problem gdyz grę muszę skonczyć do poniedziałku a zostało mi jeszcze kilka misji do ogarnięcia.

 

w tym pytaniu głównie chodzi mi o to jak zrobić kolizję gdy mój pojazd wjedzie na miejsce parkingowe, jako miejsce mam zrobiony obiekt w kształcie prostokąta, samochód to grafika z gta i tak:

jak miejsce jest na solid to nie mogę na nie wjechać, a jaknie jest solid to wszystkie instancje obiektu miejsce uciekają w prawo az zatzymają się o jakiś obiekt solid (wszystkie instancje oprócz tej na którą wjechałem) najlepiej było by się dowiedzieć jak to wyklikać ale jak ktoś może mi poradzić jakiś kod to też będzie fajnie,

nie napisałem że warunkiem ukonczenia misji ma być najechanie samochodu na miejsce parkingowe i zakrycie go przynajmniej w 90% (znaczy ze obiekty bedą na siebie nachodzic - czyli moim zdaniem należy to jakoś liczyć kolizją).

 

proszę o szybką i konkrętną odpowiedz.

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

Co do 90%:

Jeśli robisz to na studia, liczę, że znasz podstawową matematykę. Wtedy obliczenie wspólnej części dwóch prostokątów, znając pozycje dwóch rogów każdego z nich nie powinny być problemem, tak samo jak porównanie, czy owa część jest większa, niż 90% innego pola.

 

Jeśli dobrze zrozumiałem zagadnienie - chodzi o to:

parking.png

 

Oba czerwone punkty masz (samochód i miejsce parkingowe), a obliczenie długości boków tego prostokąta nie powinno zatem stanowić problemów.

Odnośnik do komentarza
Udostępnij na innych stronach

dobra myśl, w podobny sposób robiłem we fleshu w poprzednim semestrze, ale tam chodziło o zwiększenie lub zmniejszenie prędkości na odpowiednim terenie,ale to już historia.

 

odnosnie mojego pytania czy nie to samo dałby mi przycisk z zakładki "control" - "check collision"?

 

nie chciałbym być wybredny, ale mam naprawdę mało czasu a jeszcze kolega z mojej grupy co grafikę miał zrobić to zawalił temat i teraz muszę sam grafiką się zająć(jak będzie taka bedzie, ale czasu trochę zabiera).

 

zaraz zobaczę co uda mi się pokombinować z Twoim pomysłem.

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

Można użyć też collision_rectangle() z odpowiednimi argumentami. Ze sprawdzaniem kolizji jako akcji jest ten problem, że to zalezy od maski obiektu - i np. dotykając się raptem 1 pixelem już możemy mieć kolizję - a chyba nie o to chodzi.

Odnośnik do komentarza
Udostępnij na innych stronach

już nie wiem jak mam to szybko zrobić, ale znalazłem cos w dokumentacjii

collision_rectangle(x1,y1,x2,y2,obj,prec,notme)

czy tym mogę zrobic tak że jak samochód mi wiedzie w prostokąt o wsp.: (500,1000);(550,1100), zaznaczam ze pojazd jest wielkosci 40x80, jak dokładnie ma ten skrypt wyglądać?

 

a co do innego problemu to jak uruchomiłem gierkę w "debug mode" i wyswietliłem lokalne zmienne to zauważyłem że mam ustawiony kierunek grawitacji na 270 czyli w prawo, ale prędkość grawitacji była ustawiona na 0, jak w gm'ie usunąć ten kierunek grawitacji?

 

jeszcze jeden kłopot co może być powodem że jak zderzę sie z obiektem (z którym mam ustawioną kolizję), wjadę w niego z prawej strony to odrzuca mnie zawsze w kierunku 270 stopni nie ważne pod jakim kątem podjadę do obiektu.

Odnośnik do komentarza
Udostępnij na innych stronach

jak uruchomiłem gierkę w "debug mode" i wyswietliłem lokalne zmienne to zauważyłem że mam ustawiony kierunek grawitacji na 270 czyli w prawo, ale prędkość grawitacji była ustawiona na 0, jak w gm'ie usunąć ten kierunek grawitacji?

 

Kierunek grawitacji może być dowolny, skoro długość wektora to 0, to kierunek jest obojętny :) 270 to najczęściej spotykany (dół).

 

co może być powodem że jak zderzę sie z obiektem (z którym mam ustawioną kolizję), wjadę w niego z prawej strony to odrzuca mnie zawsze w kierunku 270 stopni nie ważne pod jakim kątem podjadę do obiektu.

Powodem może być (i pewnie będzie) twój kod ;) . Pooglądaj go, poszukaj, gdzie faktycznie zachodzi akcja odrzutu po kolizji. Pamiętaj: 0: prawo, 90: góra, 180: lewo, 270: dół.

 

btw: ten samochód może skręcać (obracać się) ?

Odnośnik do komentarza
Udostępnij na innych stronach

@Rudy: tak masz rację o kątach pomyliło mi się, ale to komplikuje sprawę jeszcze bardziej, generalnie jakikolwiek kod to mam tylko do samochodu(samochód skręca ale tylko gdy speed<>0 nie obraca się w miejscu, wiadomo jest to pojędyńczy obrazek więc żadna animacja nie wchodzi w grę, sterowanie znalazłem gdzieś na forum, bo to co ja używałem we flashu nie dało się sensownie przełożyć na GML), czyli na chwilę obecną nie mam pojęcia czemu tak się dzieje z tym miejscem parkingowym a obiekt stojącego samochodu tak nie reaguje, nawet gdy mają tak samo parametry poustawiane.

 

przed chwilą wymyśliłem że zrobie tak że będzie tylko jedno miejsce na które gracz będzie musiał zaparkować wskazę go strzałkami, moim zdaniem na potrzeby uczelni starczy (lepiej żeby misja się kończyła niż miała jakieś bajery nie istotne dla nauczyciela).

 

pozdrawiam i dziękuję wszystkim za pomoc.

Odnośnik do komentarza
Udostępnij na innych stronach

kod występujący w step samochodu:

GML
if ( keyboard_check( vk_up )) speed = 4

else

if ( keyboard_check( vk_down )) speed = -2

if ( speed <> 0 )

{

if ( keyboard_check( vk_right )) direction -= 5

else

if ( keyboard_check( vk_left )) direction += 5

}

 

if ( keyboard_check( vk_space )) speed = 0

 

friction = 0.1

 

image_angle = direction

if collision_rectangle(1390,530,1440,620,obj_gracz,1,0) {

 

transition_kind=1;

room_goto(menu);

 

}

 

reszta w obiekcie samochodu to tylko kolizjie z różnymi obiektami ale z akcjami "move to contact in direction 0" wszystkie te kolizje mają te same standardowe parametry.

 

w innych obiektach nie mam nawet żadnego eventu i wszystkie obiekty ustawione są na solid oprócz oczywiście samochodu.

 

edit:

zapomniałem dodać że teraz kolizja z tym "urojonym" prostokątem zatrzymuje mi samochód nawet gdy samochód dotknie prostokąta tylko jednym pikselem, a mi chodzi żeby można było spokojnie wjechać w ten prostokąt.

Odnośnik do komentarza
Udostępnij na innych stronach

Ostatecznie możesz zrobić cos takiego, że nie sprawdza procentowe zakrycie, tylko odległość od środków i ustawienie względem parkingu.

 

EDIT: Zależy ci na dobrym efekcie? Check this:

GML
speed -= min(0.02+abs(speed)*0.04, abs(speed))*sign(speed);

if (keyboard_check(vk_up))

speed += 1.2-abs(speed)/20;

if (keyboard_check(vk_down))

speed -= 0.5-abs(speed)/20;

if (keyboard_check(vk_left))

direction += power(abs(speed*2), 0.6)/2;

if (keyboard_check(vk_right))

direction -= power(abs(speed*2), 0.6)/2;

image_angle = direction;

 

Co do parkowania to to, co napisałem wyżej będzie mniej więcej coś takiego:

zał: originy samochodu na środku

GML
if (point_distance(x, y, parking_x, parking_y)*5

+min(abs(direction-parking_dir), abs(direction-parking_dir-360), abs(direction-parking_dir+360))

< 100) // granica błędu gracza > 0. ustal sobie *5 tak, jak bardzo chcesz, aby pozycja była ważniejsza od obrotu

{

show_message("Zaparkowałeś");

game_end();

}

 

Ekhm... parking_XXX to pozycja parkingu (x, y i kierunek, jeśli obiekt, jeśli nie masz takiego obiektu wpisz wartości)

Odnośnik do komentarza
Udostępnij na innych stronach

Information about object: obj_gracz

Sprite: gracz
Solid: false
Visible: true
Depth: 100
Persistent: false
Parent: <no parent>
Mask: <same as sprite>

Create Event:
execute code:




Step Event:
execute code:

speed -= min(0.02+abs(speed)*0.04, abs(speed))*sign(speed);
if (keyboard_check(vk_up))
speed += 0.9-abs(speed)/20;
if (keyboard_check(vk_down))
speed -= 0.5-abs(speed)/20;
if (keyboard_check(vk_left))
direction += power(abs(speed*2), 0.6)/2;
if (keyboard_check(vk_right))
direction -= power(abs(speed*2), 0.6)/2;
image_angle = direction;


/*if ( keyboard_check( vk_up )) speed = 4
    else
    if ( keyboard_check( vk_down )) speed = -2
    if ( speed <> 0 )
    {
        if ( keyboard_check( vk_right )) direction -= 5
        else
        if ( keyboard_check( vk_left )) direction += 5
    }
    
    if ( keyboard_check( vk_space )) speed = 0
    
    friction = 0.1
    
    image_angle = direction
if collision_rectangle(1390,530,1440,620,obj_gracz,1,0) {

transition_kind=1;
room_goto(menu);

} */


Collision Event with object obj_kraw_hor:
move in direction 0 at most -1 till a contact with all objects

Collision Event with object obj_miejsce:
move in direction 0 at most -1 till a contact with all objects

Collision Event with object obj_zajete:
move in direction 0 at most -1 till a contact with all objects

Collision Event with object obj_kraw_ver:
move in direction 0 at most -1 till a contact with all objects

Collision Event with object obj_kraw_skos:
move in direction 0 at most -1 till a contact with all objects

Collision Event with object obj_kraw_skos2:
move in direction 0 at most -1 till a contact with all objects

 

zobaczyłem że można wyswietlać całe info o obiekcie, dalej nie wiem co jest że jak wjade w jakiś obiekt od prawej to przerzuca mnie właśnie w prawo o ileś pikseli lub do obiektu z prawej strony, jest to co najmniej irytujące. Jeśli ma ktoś jakiś pomysł w czym może być problem, to chętnie posłucham, albo jakby ktoś powiedział jak najlepiej napisać kolizje skryptowo w stepie to też by było fajnie i może by problem sam się rozwiązał, z góry dziękuje za pomoc bo ja muszę teraz kolejnymi roomami się zająć bo zostało mi jakieś 10 misji do wykonania a przecież nikt i za mnie w całości nie zrobi.

Odnośnik do komentarza
Udostępnij na innych stronach

tak sobie pomyślałem że to może być tego wina, ale nie mam pojęcia jak to zrobić inaczej, mogłaby być w GM'ie taka opcja żeby przy tworzeniu tej konkretnej kolizji wstawić w direction wartość NULL czy coś w tym stylu, bo jak wstawi nawet 90 to podejrzewam że przy podjechaniu do obiektu od góry wyrzuci mnie w górę właśnie.

Odnośnik do komentarza
Udostępnij na innych stronach

generalnie podczas kolizji:

- z innym pojazdem(obj_zajete):

*dzwiek stłuczki i generalnie lewel powinien zacząć się od nowa.

 

-z miejscem parkingowym(obj_miejsce)

*powinien na miejsce wjechać i jesli zaparkował dobrze to powinno wrócić do menu ewentualnie zacząć kolejną misje,(menu mam w oddzielnym roomie i poki co wszystko co jest zrobione to działa), ale w tym miejscu skorzystam z tego co napisał Rudy i mam nadzieję że będzie działać.

 

-z krawężnikiem(obj_kraw_*)w sumie 4 objekty

*generalnie powinien się z nimi zderzyć i zatrzymać, od której kolwiek strony, ale żeby była możliwość odsunięcia sie od tego krawężnika (np. cofając), ogólnie założenie jest takie że krawężniki sie omija, ale kolizję tżeba zrobić.

 

jeśli coś ominąłem to mam nadzieje że nie jest to tak bardzo istotne.

Odnośnik do komentarza
Udostępnij na innych stronach

Ja bym to zrobił tak:

obj_zajete:

oczywiście event kolizji, dźwięk -> odsyłam do dokumentacji, na pewno dasz sobie radę, co do restartu chyba room_restart(). Proponuję jeszcze lekką zwiechę, żeby po prostu ekran nie mignął i użytkownik nie wiedziałby nawet czemu przegrał.

 

obj_kraw_XXX

zakładamy, że samochód to nie piłka i wtedy sytuacja jest prostsza, bo odwracamy zwrot wektora prędkości, a nie odbijamy :) . Więc...:

GML
speed *= -0.4; // 0.4 to współczynnik sprężystości. 0 to brak odbicia, 1 to całkowity odwrót

x = xprevious; // poprawka - trzeba przerwać kolizję

y = yprevious;
Odnośnik do komentarza
Udostępnij na innych stronach

objekt gracz:

Information about object: obj_gracz

 

Sprite: gracz

Solid: false

Visible: true

Depth: 100

Persistent: false

Parent: <no parent>

Mask: <same as sprite>

 

Create Event:

execute code:

 

 

 

 

Step Event:

execute code:

 

speed -= min(0.02+abs(speed)*0.04, abs(speed))*sign(speed);

if (keyboard_check(vk_up))

speed += 0.9-abs(speed)/20;

if (keyboard_check(vk_down))

speed -= 0.5-abs(speed)/20;

if (keyboard_check(vk_left))

direction += power(abs(speed*2), 0.6)/2;

if (keyboard_check(vk_right))

direction -= power(abs(speed*2), 0.6)/2;

image_angle = direction;

 

 

/*

if (point_distance(x, y, parking_x, parking_y)*5

+min(abs(direction-parking_dir), abs(direction-parking_dir-360), abs(direction-parking_dir+360))

< 100) // granica błędu gracza > 0. ustal sobie *5 tak, jak bardzo chcesz, aby pozycja była ważniejsza od obrotu

{

show_message("Zaparkowałeś");

game_end();

}

 

 

 

if ( keyboard_check( vk_up )) speed = 4

else

if ( keyboard_check( vk_down )) speed = -2

if ( speed <> 0 )

{

if ( keyboard_check( vk_right )) direction -= 5

else

if ( keyboard_check( vk_left )) direction += 5

}

 

if ( keyboard_check( vk_space )) speed = 0

 

friction = 0.1

 

image_angle = direction

if collision_rectangle(1390,530,1440,620,obj_gracz,1,0) {

 

transition_kind=1;

room_goto(menu);

 

} */

 

 

Collision Event with object obj_kraw_hor:

execute code:

 

speed *= -0.4; // 0.4 to współczynnik sprężystości. 0 to brak odbicia, 1 to całkowity odwrót

x = xprevious; // poprawka - trzeba przerwać kolizję

y = yprevious;

 

 

Collision Event with object obj_miejsce:

execute code:

 

if (point_distance(x, y,obj_miejsce.x, obj_miejsce.y)*5

+min(abs(direction-obj_miejsce.direction), abs(direction-obj_miejsce.direction-360), abs(direction-obj_miejsce.direction+360))

< 100) // granica błędu gracza > 0. ustal sobie *5 tak, jak bardzo chcesz, aby pozycja była ważniejsza od obrotu

{

show_message("Zaparkowałeś");

game_end();

}

 

 

Collision Event with object obj_zajete:

execute code:

 

speed *= 0; // 0.4 to współczynnik sprężystości. 0 to brak odbicia, 1 to całkowity odwrót

x = xprevious; // poprawka - trzeba przerwać kolizję

y = yprevious;

 

play sound stluczka; looping: false

display message: stłuczka zacznij od nowa

execute code:

 

x=xstart;

y=ystart;

direction =0;

 

stop sound stluczka

 

Collision Event with object obj_kraw_ver:

execute code:

 

speed *= -0.4; // 0.4 to współczynnik sprężystości. 0 to brak odbicia, 1 to całkowity odwrót

x = xprevious; // poprawka - trzeba przerwać kolizję

y = yprevious;

 

 

Collision Event with object obj_kraw_skos:

execute code:

 

speed *= -0.4; // 0.4 to współczynnik sprężystości. 0 to brak odbicia, 1 to całkowity odwrót

x = xprevious; // poprawka - trzeba przerwać kolizję

y = yprevious;

 

 

Collision Event with object obj_kraw_skos2:

execute code:

 

speed *= -0.4; // 0.4 to współczynnik sprężystości. 0 to brak odbicia, 1 to całkowity odwrót

x = xprevious; // poprawka - trzeba przerwać kolizję

y = yprevious;

 

generalnie to wszystko dział jakbym chciał, ale nie wiem jak zrobić z tym miejscem, żeby chociaż mi się wiadomość wyświetliła.

Odnośnik do komentarza
Udostępnij na innych stronach

właśnie nie wychodzi, tylko zapomniałem wspomnieć że na mapce mam kilka instancji obj_miejsce i origin jest na 0,0 chociaż jak zmieniłem na center to poza tym że instancje zmieniły lekko położenie to też nie wychodzi z gry

Odnośnik do komentarza
Udostępnij na innych stronach

A spróbuj z jednym miejscem?

W obiekcie gracza masz klockiem zrobioną kolizję z miejscem parkingowym i w kodzie kolizji

GML
if (point_distance(x, y,obj_miejsce.x, obj_miejsce.y)*5

+min(abs(direction-obj_miejsce.direction), abs(direction-obj_miejsce.direction-360), abs(direction-obj_miejsce.direction+360))

< 100) // granica błędu gracza > 0. ustal sobie *5 tak, jak bardzo chcesz, aby pozycja była ważniejsza od obrotu

{

show_message("Zaparkowałeś");

game_end();

}

tak?

 

EDIT:

Sagi- Kiedy robisz klockiem kolizję np- auto <collision> parking; To w kodzie parking określa się jako 'other' tzn- zmień w tym kodzie co zacytowałem

GML
obj_miejsce.x na other.x

I tak w każdym miejscu kolizji. Mi pięknie działa - jak chcesz podeślę Ci przykładzik.

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ę...