Huri Opublikowano 23 Września 2013 Udostępnij Opublikowano 23 Września 2013 Cześć to znowu ja. Otóż zaplątałem się w tych wszystkich klockach i postanowiłem, że jednak przerzucę się na GML. Zacząłem od samego początku i napisałem kod odpowiedzialny za rysowanie poziomu (dla przypomnienia top-down fake isometric). Mam sprite spr_wall i spr_w_template. Gdy w edytorze ROOM rysuje poziom gry uzywam obiektu z domyślnie przypisanym spr_w_template (dla ułatwienia rysowania). W kodzie obiektu obj_wall w EVENT CREATE wstawiłem wykonywanie skryptu room_draw(). Skrypt ten jest dosyć uniwersalny dzięki czemu mogę rysować różne sprite'y dla obiektu obj_wall. Moim głównym zamierzeniem było to żeby obj_wall w zależności czy i z której strony jest otoczony przez inne obiekty (solid) zmieniał sprite. Wszystko działa super i tak jak chciałem... Ale zapragnęło mi się dodać cienie pod obiektami sciany. Skorzystałem więc z GMLdraw_sprite_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, image_angle, image_blend, image_alpha); No spoko... Cień rysuje się nawet pod obj_wall... ale tylko tym, z którego został wygenerowany. Chciałbym żeby cienie były rysowane pod wszystkimi obiektami obj_wall a nie tylko pod jednym, z którego został wygenerowany. Jakieś pomysły? Kombinowałem też z surface'ami ale coś pochrzaniłem (nie doszedłem jeszcze do tego etapu obcowania z GM) i zcrashowałem grę. Część kodu odpowiedzialnego za przydzielanie sprite'ów do obj_wall (reszta wygląda tak samo tylko sprawdza czy obiekt jest/nie jest otoczony z innych stron): GML // Rysowanie ściany orientacji NE (Północ-Wschód) if (!place_free(x-grid_s, y+0) && place_free(x+0,y-grid_s) && !place_free(x+0,y+grid_s) && place_free(x+grid_s, y+0)) { image_index=w_ne; //rysuj_cien(); <-- to nieaktualne już } W EVENT DRAW obj_wall wpisałem to: GML GMLdraw_sprite_ext(sprite_index, image_index, x-3, y-3, 1.3, 1.3, image_angle, c_black, 0.4); depth=-x-y; draw_self(); W grze wygląda to mniej więcej tak. Nie zwracajcie uwagi na tą niebieską gębę :P ... wziąłem najtańszego statystę z Avatara do testowania rozwiązań :P . W czerwonej ramce oczywiście nakładające się cienie. Jeszcze jeden obrazek. Może na tym będzie lepiej widać (Tu zaznaczone na zielono). Cień może nachodzić na gracza (ale tylko na niego). Będę wdzięczny za pomoc. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Exigo Opublikowano 23 Września 2013 Udostępnij Opublikowano 23 Września 2013 Przychodzą mi do głowy dwa rozwiązania: Pierwsze: bardziej skomplikowane. Narysuj wszystkie cienie skrzynek do surface, po czym narysuj owy surface. Po narysowaniu rysuj skrzynki bez cienia. Tą technikę będziesz mógł potem rozwinąć (np. blurując shaderem utworzony cień). Drugie: prościej się nie da. Najpierw rysujesz wszystkie cienie skrzynek, potem wszystkie skrzynki. Zrób jakiś pojedynczy obiekt, nazywając go np. "obj_rysowanie_skrzynek", i daj mu do draw event mniej-więcej taki kod: GML with (skrzynka) { rysuj cień skrzynki } with (skrzynka) { rysuj skrzynke } Ze skrzynek natomiast usuń rysowanie (cienie i skrzynki). Wada: cienie skrzynek nakładają się na siebie. Pierwsze rozwiązanie, to trudniejsze, rozwiązuje problem. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Threef Opublikowano 23 Września 2013 Udostępnij Opublikowano 23 Września 2013 drugi raz na tym skrzynki.W ten sposób nie będzi mógł schować się za skrzynkami (depth). Wg mnie powinieneś stworzyć surface i na nim (z alpha=1!) rysować cienie. Depth po kolei: Gracz, Surface (teraz z alpha), skrzynki. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
ereg Opublikowano 23 Września 2013 Udostępnij Opublikowano 23 Września 2013 kiedy cien "wychodzi" mimo prostokot sprite (x-3,y-3) to sproboj dac w depth poziom wall od -do w ktorym bedom tylko wall nastepnie zmien depth kazdej wall w zaleznosci na x,y tak by cienie sie nakladaly prawidlowo. linie mogo miec depth+1000 ( w zaleznosci na resolution screen) colmuny dept+1 dla optimalizacji mozna minimalizovac cykle i obszar zmian depth tak jak gra pozwoli jesli niepozwoli to surface jest lepszy Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Huri Opublikowano 23 Września 2013 Autor Udostępnij Opublikowano 23 Września 2013 Przyznam szczerze, że nie potrafię zrozumieć. Póki co to chyba dla mnie zbyt zaawansowane. Nawet z narysowanym w sprite'cie cieniem jest ten problem (w sumie logiczne). Daruje sobie chyba Cienie dopóki nie nauczę się więcej. kiedy cien "wychodzi" mimo prostokot sprite (x-3,y-3) to sproboj dac w depth poziom wall od -do w ktorym bedom tylko wall nastepnie zmien depth kazdej wall w zaleznosci na x,y tak by cienie sie nakladaly prawidlowo. linie mogo miec depth+1000 ( w zaleznosci na resolution screen) colmuny dept+1 dla optimalizacji mozna minimalizovac cykle i obszar zmian depth tak jak gra pozwoli jesli niepozwoli to surface jest lepszy Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
hopek Opublikowano 23 Września 2013 Udostępnij Opublikowano 23 Września 2013 Możesz podzielić ten cień na kilka części i rysować każdą z nich jeżeli w miejscu którym się znajduje nie stoi jakiś inny bloczek. Wiem że to rozwiązanie na chłopski rozum, ale działało mi w paru grach........ :D Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
I am Lord Opublikowano 23 Września 2013 Udostępnij Opublikowano 23 Września 2013 To wcale nie jest takie trudne. Jak już exigo wspomniał najlepszym sposobem będzie rysowanie tego na surface. 1. Tworzysz 2 obiekty > oShadow i pShadowCaster. Pierwszy to będzie obiekt rysujący cień na ekranie. Drugi będzie parentem dla każdego obiektu który ma rzucać cień. oShadow ustaw depth na tyle mały duży by inne obiekty go mogły przykryć oprócz podłogi. pShadowCaster zostaw jak jest. 2. W obiekcie oShadow GML (create) globalvar gShadowSurface, gVx, gVy; // zmienne globalne // tworzenie surface o rozmiarze viewa gShadowSurface = surface_create( view_wview, view_hview ); // czyszczenie go surface_set_target( gShadowSurface ); draw_clear_alpha( 0, 0 ); surface_reset_target(); // pozycja viewa gVx = view_xview; gVy = view_yview; GML (BeginStep) surface_set_target( gShadowSurface ); draw_clear_alpha( 0, 0 ); surface_reset_target(); gVx = view_xview; gVy = view_yview; GML (draw) // zabezpieczenie na wypadek gdyby coś się stało z surfacem if ( !surface_exists(gShadowSurface) ) gShadowSurface = surface_create( view_wview, view_hview ); // rysowanie surface na ekranie draw_surface_ext( gShadowSurface, gVx, gVy, 1, 1, 0, 0, 0.5 ); 3. W obiekcie pShadowCaster GML (Step) // rysowanie cieni na surface surface_set_target( gShadowSurface ); draw_sprite_ext( sprite_index, image_index, x-gVx-3, y-gVy-3, 1.3, 1.3, image_angle, 0, 1 ); surface_reset_target(); 4. Wszystkim obiektom które mają rzucać cienie daj parenta pShadowCaster i dodaj do step. GML event_inherited(); I postaw w roomie obiekt oShadow Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Huri Opublikowano 23 Września 2013 Autor Udostępnij Opublikowano 23 Września 2013 Dzięki :) .. Spróbuje jutro to ogarnąć (lubię rozumieć to co przepisuje). Teraz walczę z czym innym. Jeszcze się za to nie zabrałem i możliwe, że mój pomysł polega na tym samym albo jest niewykonalny ale... A gdyby tak narysować room tak jak odbywa się to normalnie, narysować jego tło, wypalić cienie na nim i zapisać cały room do pliku i odczytać go i ustawić jako tło? Coś na wzór bake'owania textur w grafice 3D. To wcale nie jest takie trudne. Jak już exigo wspomniał najlepszym sposobem będzie rysowanie tego na surface. 1. Tworzysz 2 obiekty > oShadow i pShadowCaster. Pierwszy to będzie obiekt rysujący cień na ekranie. Drugi będzie parentem dla każdego obiektu który ma rzucać cień. oShadow ustaw depth na tyle mały by inne obiekty go mogły przykryć oprócz podłogi. pShadowCaster zostaw jak jest. 2. W obiekcie oShadow GML (create)globalvar gShadowSurface, gVx, gVy; // zmienne globalne // tworzenie surface o rozmiarze viewa gShadowSurface = surface_create( view_wview, view_hview ); // czyszczenie go surface_set_target( gShadowSurface ); draw_clear_alpha( 0, 0 ); surface_reset_target(); // pozycja viewa gVx = view_xview; gVy = view_yview; GML (BeginStep)surface_set_target( gShadowSurface ); draw_clear_alpha( 0, 0 ); surface_reset_target(); gVx = view_xview; gVy = view_yview; GML (draw)// zabezpieczenie na wypadek gdyby coś się stało z surfacem if ( !surface_exists(gShadowSurface) ) gShadowSurface = surface_create( view_wview, view_hview ); // rysowanie surface na ekranie draw_surface_ext( gShadowSurface, gVx, gVy, 1, 1, 0, 0, 0.5 ); 3. W obiekcie pShadowCaster GML (Step)// rysowanie cieni na surface surface_set_target( gShadowSurface ); draw_sprite_ext( sprite_index, image_index, x-gVx-3, y-gVy-3, 1.3, 1.3, image_angle, 0, 1 ); surface_reset_target(); 4. Ustaw wszystkim obiektom które mają rzucać cienie daj im parenta pShadowCaster i dodaj do step. GMLevent_inherited(); I postaw w roomie obiekt oShadow Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Amaterasu Opublikowano 24 Września 2013 Udostępnij Opublikowano 24 Września 2013 Jeśli room jest duży, to taki bake zajmie sporo miejsca w pamięci. Generalnie sposób HuderLorda polega na tym samym, ale bake obejmuje tylko widzialny obszar rooma. Bake jest update'owany co step (czyli np. 60 razy na sekundę, jeżeli room_speed = 60), więc dobrym pomysłem byłoby zmniejszenie częstości tego update'owania, jeżeli obiekty rzucające cienie są w miarę statyczne. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
I am Lord Opublikowano 24 Września 2013 Udostępnij Opublikowano 24 Września 2013 No moje raczej trudno nazwać Bake skoro się updatuje non stop. Jeśli cienie mają być tylko statyczne to można zrobić bake cieni na tilesy w jakimś edytorze leveli. 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ę