TheVVaS Opublikowano 20 Marca 2014 Udostępnij Opublikowano 20 Marca 2014 Witam, Od niedawna zacząłem bawić się w robienie w GMie małej gierki z czołgami w roli głównej :) Aktualnie zatrzymałem się na fragmencie gdzie sprawdza się czy czołg nie jest przez coś blokowany. A oto moje wypociny: 1. Sprawdzanie czy może obrócić się w lewo - skrypt Check_left: GML sprheight = sprite_get_height(spr_tank1) sprwidth = sprite_get_width(spr_tank1) py1 = obj_tank.y - lengthdir_y(sprheight/2,obj_tank.direction) px1 = obj_tank.x - lengthdir_x(sprwidth/2,obj_tank.direction) py2 = obj_tank.y + lengthdir_y(sprheight/2,obj_tank.direction) px2 = obj_tank.x + lengthdir_x(sprwidth/2,obj_tank.direction) if place_free(px1, py1) && place_free(px2,py2) return (1) else return (0) 2. Sprawdzanie czy może obrócić się w prawo - Skrypt Check_right: GML sprheight = sprite_get_height(spr_tank1) sprwidth = sprite_get_width(spr_tank1) py1 = obj_tank.y - lengthdir_y(sprheight/2,obj_tank.direction) px1 = obj_tank.x + lengthdir_x(sprwidth/2,obj_tank.direction) py2 = obj_tank.y + lengthdir_y(sprheight/2,obj_tank.direction) px2 = obj_tank.x - lengthdir_x(sprwidth/2,obj_tank.direction) if place_free(px1, py1) && place_free(px2,py2) return (1) else return (0) 3. Sprawdzanie czy może poruszać się do przodu - Skrypt Check_forward: GML sprheight = sprite_get_height(spr_tank1) sprwidth = sprite_get_width(spr_tank1) py1 = obj_tank.y - lengthdir_y(sprheight/2,obj_tank.direction) px1 = obj_tank.x - lengthdir_x(sprwidth/2,obj_tank.direction) py2 = obj_tank.y - lengthdir_y(sprheight/2,obj_tank.direction) px2 = obj_tank.x + lengthdir_x(sprwidth/2,obj_tank.direction) py3 = obj_tank.y - lengthdir_y(sprheight/2,obj_tank.direction) px3 = obj_tank.x if place_free(px1, py1) && place_free(px2,py2) && place_free(px3,py3) return (1) else return (0) 4. Sprawdzanie czy może poruszyć się do tyłu - Skrypt Check_backward: GML sprheight = sprite_get_height(spr_tank1) sprwidth = sprite_get_width(spr_tank1) py1 = obj_tank.y + lengthdir_y(sprheight/2,obj_tank.direction) px1 = obj_tank.x - lengthdir_x(sprwidth/2,obj_tank.direction) py2 = obj_tank.y + lengthdir_y(sprheight/2,obj_tank.direction) px2 = obj_tank.x + lengthdir_x(sprwidth/2,obj_tank.direction) py3 = obj_tank.y + lengthdir_y(sprheight/2,obj_tank.direction) px3 = obj_tank.x if place_free(px1, py1) && place_free(px2,py2) && place_free(px3,py3) return (1) else return (0) return(1) - Nic go nie blokuje return(0) - Jakiś blok solidny stoi i blokuje Znajdzie się jakiś miszczu co pomoże biednemu w potrzebie? :D Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
I am Lord Opublikowano 20 Marca 2014 Udostępnij Opublikowano 20 Marca 2014 argumenty LEN muszą być takie same bo inaczej punkty które sprawdzasz będą poruszać się po elipsie a nie okręgu. Sprawdź sobie w draw: GML draw_circle( px1, py1, 3, 0 ); draw_circle( px2, py2, 3, 0 ); To zobaczysz o co mi chodzi. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TheVVaS Opublikowano 20 Marca 2014 Autor Udostępnij Opublikowano 20 Marca 2014 Przedstawię na obrazku, gdyż nie potrafię tego dokładnie opisać oraz chciałbym ominąć nieporozumienia: Brązowe - czołg Czerwone - punkty sprawdzające podczas obrotu w lewo czy coś nie blokuje Zielone - tak samo jak czerwone, ale w prawo Edit: Pobawię się draw'em tak jak napisałeś. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
I am Lord Opublikowano 20 Marca 2014 Udostępnij Opublikowano 20 Marca 2014 Ależ ja wiem o co ci chodzi :P Wyświetl sobie te punkty w draw, podczas obracania czołgu nie będą się ruszać tak jak chciałeś. No chyba że sprit czołgu jest kwadratowy to wtedy będzie ok. https://forum.gmclan.org/index.php?showtopic=28090 Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TheVVaS Opublikowano 20 Marca 2014 Autor Udostępnij Opublikowano 20 Marca 2014 To teraz sprostowanie, użyłem skryptu Check_left, by sprawdzić gdzie są te punkty. Pierwszy pojawia się u góry między dwoma zaznaczonymi, a drugi an dole także między zaznaczonymi na powyższym rysunku. Czołg jest prostokątny o wymiarach 34x48. Punkty ruszają się podczas obrotu czołgu. Edit: Przy użyciu drawa na skrypt Check_right kropki pokazują się w tym samym miejscu co przy Check_left, ale jak obracam czołg to kręcą się w drugą stronę. Edit2: Przy skrycie na Check_forward zostałem rozwalony, nie wiem jak opisać obrót tych punktów :D Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
I am Lord Opublikowano 20 Marca 2014 Udostępnij Opublikowano 20 Marca 2014 Jeżeli origin jest na środku to: GML czerwony = obj_tank.y + lengthdir_y(28,obj_tank.direction+123) czerwony = obj_tank.x + lengthdir_x(28,obj_tank.direction+123) niebieski = obj_tank.y + lengthdir_y(28,obj_tank.direction+53) niebieski = obj_tank.x + lengthdir_x(28,obj_tank.direction+53) fioletowy = obj_tank.y + lengthdir_y(28,obj_tank.direction-123) fioletowy = obj_tank.x + lengthdir_x(28,obj_tank.direction-123) rozowy = obj_tank.y + lengthdir_y(28,obj_tank.direction-53) rozowy = obj_tank.x + lengthdir_x(28,obj_tank.direction-53) Może zajść potrzeba odwrócenia direction czyli -obj_tank.direction ale tego nie jestem pewien. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TheVVaS Opublikowano 20 Marca 2014 Autor Udostępnij Opublikowano 20 Marca 2014 Rozumiem, że te punktu są przystosowane już do rozmiarów mojego zacnego prostokątnego czołgu? :D A co do punktu równo na górze albo równo na dole muszę dać tak? GML gora = obj_tank.y + lengthdir_y(24,obj_tank.direction) gora = obj_tank.x + lengthdir_x(24,obj_tank.direction) dol = obj_tank.y + lengthdir_y(24,obj_tank.direction-180) dol = obj_tank.x + lengthdir_x(24,obj_tank.direction-180) Chciałbym też dowiedzieć się jak dorwałeś LEN 28? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Threef Opublikowano 20 Marca 2014 Udostępnij Opublikowano 20 Marca 2014 Chciałbym też dowiedzieć się jak dorwałeś LEN 28? Wyliczył z funkcji trygonometrycznych. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TheVVaS Opublikowano 20 Marca 2014 Autor Udostępnij Opublikowano 20 Marca 2014 To teraz ostatnie pytanko - Czy sposób jakim to zrobiłem jest dobry czy przekombinowałem? Może jest jakiś efektywniejszy sposób na to? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Threef Opublikowano 20 Marca 2014 Udostępnij Opublikowano 20 Marca 2014 Lewo: GML direction-=1 if(!place_free(x,y)) { direction+=1 } Może tak? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
I am Lord Opublikowano 20 Marca 2014 Udostępnij Opublikowano 20 Marca 2014 Też prawdopodobnie bym coś takiego zrobił (tzn to TheVVaSa nie to co Threef dał :D). góra to 24 i dir+90 a dół 24 i dir-90 Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TheVVaS Opublikowano 20 Marca 2014 Autor Udostępnij Opublikowano 20 Marca 2014 Lekko pozmieniałem i wszystko ładnie śmiga. Wielkie dzięki za pomoc :) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TheVVaS Opublikowano 20 Marca 2014 Autor Udostępnij Opublikowano 20 Marca 2014 No niestety napotkałem kolejny problem, mianowicie: Niby punkty do sprawdzania kolizji działają, ale małe skurczybyki działają na większą skale niż chciałem. Czerwone kropki to punkty kolizji, czarny blok to obiekt solidny. Otóż jak na obrazku widać, jest jeszcze sporo miejsca między punktami kolizji i solidną ścianką, lecz pokazane punkty już wykrywają solidna ścianę :( Jakiś pomysł? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
I am Lord Opublikowano 21 Marca 2014 Udostępnij Opublikowano 21 Marca 2014 Bo place_free działa w taki sposób że przenosi maskę obiektu w podane miejsce i tak sprawdza kolizję. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TheVVaS Opublikowano 21 Marca 2014 Autor Udostępnij Opublikowano 21 Marca 2014 Da się to jakoś poprawić? Edit: Użycie collision_point coś by tu zmieniło? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
I am Lord Opublikowano 21 Marca 2014 Udostępnij Opublikowano 21 Marca 2014 Spróbuj może position_meeting Lub lepiej instance_position bo to zamiast true/false zwraca id obiektu kolidującego. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TheVVaS Opublikowano 21 Marca 2014 Autor Udostępnij Opublikowano 21 Marca 2014 Czyli jeśli chciałbym użyć instance_position, by wykrywał bloki solidne to jakoś tak: GML instance_position(obj_tank.x,obj_tank.y+24, obj_solid_block) ? Jeśli dobrze rozumiem to będzie reagować tylko na obiekty, które mu podam? Da się to jakoś wykorzystać, by reagował na każdy obiekt, który jest solidny? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
I am Lord Opublikowano 21 Marca 2014 Udostępnij Opublikowano 21 Marca 2014 Musisz sobie stworzyć hierarchię obiektów. Stwórz pusty obiekt o np nazwie parent_sciany. I każdemu obiektowi który jest ścianą ustaw parent>parent_sciany Teraz przy kolizji (zakładam że kolizje sprawdzasz w obj_tank) GML colid = instance_position(px1,py1, parent_sciany) if ( colid ) { // nastąpiła kolizja // dalej można coś zrobić ze ścianą np zniszczyć with ( colid ) instance_destroy(); } Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TheVVaS Opublikowano 21 Marca 2014 Autor Udostępnij Opublikowano 21 Marca 2014 Zmieniłem sprawdzanie kolizji na instance_position, ale teraz efekt jest nadal daleki. Dodałem też ścianie parenta. Wyśle ci na PW skompilowaną wersje i zobaczysz jak to wygląda. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
I am Lord Opublikowano 21 Marca 2014 Udostępnij Opublikowano 21 Marca 2014 Nie wrzuciłeś DLLela czy coś? Bo mi się nie uruchamia. ERROR in action number 1 of Create Event for object Server: Error defining an external function. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TheVVaS Opublikowano 21 Marca 2014 Autor Udostępnij Opublikowano 21 Marca 2014 A sorki, zawsze o nim zapominam :/ Już wrzucam. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
I am Lord Opublikowano 21 Marca 2014 Udostępnij Opublikowano 21 Marca 2014 To jak masz teraz całą kolizję zakodzoną? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TheVVaS Opublikowano 21 Marca 2014 Autor Udostępnij Opublikowano 21 Marca 2014 Check_backward GML py1 = obj_tank.y + lengthdir_y(18,obj_tank.direction+143) + obj_tank.vspeed px1 = obj_tank.x + lengthdir_x(18,obj_tank.direction+143) + obj_tank.hspeed py2 = obj_tank.y + lengthdir_y(18,obj_tank.direction+213) + obj_tank.vspeed px2 = obj_tank.x + lengthdir_x(18,obj_tank.direction+213) + obj_tank.hspeed py3 = obj_tank.y + lengthdir_y(14,obj_tank.direction-180) + obj_tank.vspeed px3 = obj_tank.x + lengthdir_x(14,obj_tank.direction-180) + obj_tank.hspeed if instance_position(px1, py1, solid) || instance_position(px2,py2, solid) || instance_position(px3,py3, solid) return (0) else return (1) Check_forward GML py1 = obj_tank.y + lengthdir_y(19,obj_tank.direction+37) + obj_tank.vspeed px1 = obj_tank.x + lengthdir_x(19,obj_tank.direction+37) + obj_tank.hspeed py2 = obj_tank.y + lengthdir_y(19,obj_tank.direction-33) + obj_tank.vspeed px2 = obj_tank.x + lengthdir_x(19,obj_tank.direction-33) + obj_tank.hspeed py3 = obj_tank.y + lengthdir_y(15,obj_tank.direction) + obj_tank.vspeed px3 = obj_tank.x + lengthdir_x(15,obj_tank.direction) + obj_tank.hspeed if instance_position(px1, py1, solid) || instance_position(px2,py2, solid) || instance_position(px3,py3, solid) return (0) else return (1) Check_left GML py1 = obj_tank.y + lengthdir_y(19,obj_tank.direction+37) + obj_tank.vspeed px1 = obj_tank.x + lengthdir_x(19,obj_tank.direction+37) + obj_tank.hspeed py2 = obj_tank.y + lengthdir_y(18,obj_tank.direction+213) + obj_tank.vspeed px2 = obj_tank.x + lengthdir_x(18,obj_tank.direction+213) + obj_tank.hspeed if instance_position(px1, py1, solid) || instance_position(px2,py2, solid) return (0) else return (1) Check_right GML py1 = obj_tank.y + lengthdir_y(19,obj_tank.direction-33) + obj_tank.vspeed px1 = obj_tank.x + lengthdir_x(19,obj_tank.direction-33) + obj_tank.hspeed py2 = obj_tank.y + lengthdir_y(18,obj_tank.direction+143) + obj_tank.vspeed px2 = obj_tank.x + lengthdir_x(18,obj_tank.direction+143) + obj_tank.hspeed if instance_position(px1, py1, solid) || instance_position(px2,py2, solid) return (0) else return (1) Edit: Teraz znowu sprawdzam i już blokuje dobrze, ale teraz mam problem z "wbijaniem" się w ścianę, jak czołg osiągnie dużą prędkość to może wbić się lekko w ścianę. Jak temu zapobiec? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Threef Opublikowano 21 Marca 2014 Udostępnij Opublikowano 21 Marca 2014 Są 2 sposoby obliczania kolizji Sprawdzanie czy po skończonym ruchu będzie kolizja. Jeśli nie to przemieszczenie. Przemieszczenie i dopiero potem sprawdzenie czy zaszła kolizja. Jeżeli zaszła to cofnięcie przemieszczenia. Ty wybrałeś pierwszy, bo wydaje się bardziej sensowny. W drugim jest obawa że będzie widoczne to cofnięcie, ale jeżeli wszystko odbędzie się w obrębie jednego step (przed narysowaniem) to będzie dobrze. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TheVVaS Opublikowano 21 Marca 2014 Autor Udostępnij Opublikowano 21 Marca 2014 Tak, wolałbym pierwszy sposób, lecz nawet jak dodam do sprawdzania kolizji vspeed albo hspeed to nadal przy większej prędkości widać jak się wbija. Taki jest efekt aktualnego kodu. (Rozpędziłem się czołgiem do maksimum i wbiłem się w ściankę) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Threef Opublikowano 21 Marca 2014 Udostępnij Opublikowano 21 Marca 2014 Jeżeli chcesz to zrobić dobrze i szybko (w GM) to wystarczy Ci prostokątna maska kolizji ustawiona na sprite i odznaczone precise collision checking. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TheVVaS Opublikowano 21 Marca 2014 Autor Udostępnij Opublikowano 21 Marca 2014 Opcję odznaczyłem, sprite ma prostokątną maskę kolizji - czołg nadal tak samo wbija się w ściankę. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Threef Opublikowano 21 Marca 2014 Udostępnij Opublikowano 21 Marca 2014 Korzystając z instance_position brana jest pod uwagę tylko maska obiektu z trzeciego argumentu. Maska obiektu który wykonuje ten kod nie jest brana pod uwagę. place_free, position_free albo event kolizji powinny być użyte. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
I am Lord Opublikowano 21 Marca 2014 Udostępnij Opublikowano 21 Marca 2014 Najlepiej daj source bo tak się nie dowiem nigdy o co chodzi :P Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TheVVaS Opublikowano 21 Marca 2014 Autor Udostępnij Opublikowano 21 Marca 2014 Już wysyłam wam na PW source, tylko się nie popłaczcie jak zobaczycie moje wypociny :D Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi
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ę