Skocz do zawartości

Skalowanie się obiektu, gdy ten zetknie się z tilesem.


Rekomendowane odpowiedzi

Tworzę sobie taki projekcik, gdzie wykorzystuję kolizję opartą o tilesy, a nie obiekty.

 

Mój skrypt, który jest taką alternatywą dla "place_meeting()", tylko działa na tilesach:

 

Cytuj

///@arg xx
///@arg yy
///@arg collision_layer

var xx = argument0;
var yy = argument1;
var tilemap_id = layer_tilemap_get_id(layer_get_id(argument2));
var right_collision = false;
var left_collision = false;
var top_collision = false;
var bottom_collision = false;

//save current position
var xp = x;
var yp = y;

//update position and check for collision

if (xx != xp){
    x = xx;
    if (xx > xp){     // right movment collision
        right_collision =    tilemap_get_at_pixel(tilemap_id, bbox_right, bbox_top) ||
                            tilemap_get_at_pixel(tilemap_id, bbox_right, bbox_top+sprite_height/2) ||
                            tilemap_get_at_pixel(tilemap_id, bbox_right, bbox_bottom);    
        } else {    // left movment collision
        left_collision =    tilemap_get_at_pixel(tilemap_id, bbox_left, bbox_top) ||
                            tilemap_get_at_pixel(tilemap_id, bbox_left, bbox_top+sprite_height/2) ||
                            tilemap_get_at_pixel(tilemap_id, bbox_left, bbox_bottom );
    }
}

if (yy != yp){
    y = yy;
    if (yy > yp){     // down movment collision
        bottom_collision =    
                            tilemap_get_at_pixel(tilemap_id, bbox_left, bbox_bottom )||
                            tilemap_get_at_pixel(tilemap_id, bbox_left+sprite_width/2, bbox_bottom)||
                            tilemap_get_at_pixel(tilemap_id, bbox_right, bbox_bottom);    
        } else {    // up movment collision
        top_collision =        tilemap_get_at_pixel(tilemap_id, bbox_left, bbox_top) ||
                            tilemap_get_at_pixel(tilemap_id, bbox_left+sprite_width/2, bbox_top)||
                            tilemap_get_at_pixel(tilemap_id, bbox_right, bbox_top);                    
    }
}

//move back
x = xp;
y = yp;

//return
return (right_collision || left_collision || top_collision || bottom_collision);

 

Tak wygląda kod odnośnie kolizji:

 

Cytuj

// horizontal collision check
if scr_tile_collision(x+hspd, y, "Collision"){
    while(!scr_tile_collision(x+sign(hspd), y, "Collision")){
        x+=sign(hspd);
    }
    hspd = 0;
}

x += hspd;

// vertical collision check
if scr_tile_collision(x, y+vspd, "Collision"){
    while(!scr_tile_collision(x, y+sign(vspd), "Collision")){
        y+=sign(vspd);
    }
    vspd = 0;
}

y += vspd;

 

Nic odkrywczego, taki standard jeśli chodzi o precyzyjną kolizję, tutaj jednak odnosimy się do tilesów.

 

Chcę w grze mieć wrogów, którzy mają zasięg widzenia i jeśli my jako gracz się w nim znajdziemy, to odpalają się pewne state'y. Problem jest taki, że ściany, platformy, to tilesy bez obiektów kolizyjnych, więc funkcja collision_line() odpada. Moje doświadczenie jest małe i coś tak kombinuję sobie, jak pierwszy lepszy pomysł do głowy trafi. Skoro mam własną funkcję do wykrywania kolizji między obiektami a tilesami, to pomyślałem, że może "wzrok" przeciwników, to będzie obiekt, ze spritem o wielkości 1 pixela, który będzie się skalował w osi x na maksymalny zasięg z zmiennej.

 

Cytuj

//line of sight
with (my_line_of_sight){
    x = other.x;
    y = other.y;
    image_xscale = other.seeing_max * other.dir;
    
    if scr_tile_collision(x+other.hspd, y, "Collision"){
        while(scr_tile_collision(x+(other.hspd*2), y, "Collision")){
        image_xscale=image_xscale - (other.hspd*2);
    }
        image_xscale = image_xscale-other.hspd
        other.seeing_wall = true;
        } else {
        other.seeing_wall = false;
    }
}

 

Problem jest taki, że kolizja z tilesami jest oparta o punkty bounding boxa tilesa. Rózne rozmiary kolidujących spirtów mogę powodować różne błędy i niewykrycie kolizji. W moim przypadku mamy 8 punktów sprawdzania kolizji i większości przypadków daje radę. Jeśli biała linia przejdzie za bardzo przez tilesa, to kolizja nie zachodzi i zmienna seeing_wall = false; Na screenie widać o co mi chodzi. Chciałbym żeby linia wchodząc w tilesa scalowała się w dół. Tak by nadal kolidowała z tilesem a się skracała tak by nie wychodziła poza obszar tilesa.

tsA1ocr.jpg

 

Pewnie nie jest to najlepsze rozwiązanie, ale likwidacja tego jednego problemu dałaby mi to czego potrzebuję. Próbowałem coś na googlach szukać odnośnie collision_line z tilesami i jedyne co znalazłem jakiś niezrozumiały dla mnie skrypt, który był raycastem opartym o ds_grid. Jak na moje potrzeby, to jednak za bardzo skomplikowane.

 

Może zamiast skalowanego obiektu na wzór linii zrobić obiekt "punkt", który jest w odległości od przeciwnika i w razie kolizji jest dopychany w pętli idealnie do punktu bounding boxa? samą linię mógłbym na potrzeby debbuginu rysować w drawie w odległości x przeciwnika do x punktu. Jakieś rady? Jeśli ktoś znałbym jakiś nie za bardzo skomplikowany sposób na zrobienie tego bez dodatkowych obiektów tylko na podstawie jakieś "zaawansowanej" matematyki, to się nie obrażę :)

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

Jak chcesz naprawdę na skróty, to ustawiaj obiekty solid i rozciągaj je na całą wysokość danej ściany. W przypadku powyższego screena, można na 5 obiektach zrobić całe kolizje w grze zmieniając x-scale / y-scale . Jak etapy nie są ogromne, albo dodasz deaktywację poza ekranem, to naprawdę wdajnościowo nie będzie problemem, a cały powyższy problem poleci do kosza.

Odnośnik do komentarza
Udostępnij na innych stronach

Czyli darować sobie tilesy i wrócić do starych sprawdzonych obiektów kolizyjnych? Plansze w grze mają być duże, nie jakaś metroidvania, ale trochę tam ma się scrollować zanim etap się skończy. Pomysł z dezaktywacją obiektów, które są daleko od aktualnej kamery nie jest taki głupi i myślę, że nawet z moją małą wiedzą o GM'ie jestem w stanie ogarnąć temat.

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