Skocz do zawartości

Jak zrobić realistyczne cienie w grze top down ?


Rekomendowane odpowiedzi

1. Tworzymy obiekt surface i wpisujemy w podanych eventach co trzeba.

 

CREATE:

 

GML
global.blend=0;

 

global.surf=surface_create(room_width,room_height);

 

surface_set_target(global.surf);

draw_clear_alpha(c_black,0);

surface_reset_target();

 

depth=5+round(random(5)) //opcjonalnie</span>

 

ROOM END:

 

GML
surface_free(global.surf);

 

DRAW:

 

GML
draw_surface_ext(global.surf,0,0,1,1,0,c_white,0.5);

 

 

2. W dowolnym obiekcie, który posiada bądź nie posiada sprite'a, wpisujemy co trzeba. Obiekt nie musi mieć eventu draw z linijką na rysowanie samego siebie. Jeśli mamy ustawionego sprite'a w okienku obiektu lub ustawiliśmy go kodem (np. sprite_index=spr_ludek) to wpisujemy w poniższym kodzie w należytym miejscu sprite_index. Jeśli nie to wpisujemy nazwę (istniejącego) sprite'a jaki nam się podoba.

 

END STEP:

 

GML
//ja dla przykładu mam takie cienie postaci ale

//lepiej ich nie używaj bo się zgubisz i już nie znajdziesz drogi powrotnej,

//przewiń w dół i tam znajdziesz odpowiedni kod.

if surface_exists(global.surf)

{

surface_set_target(global.surf);

draw_clear_alpha(0,0);

draw_sprite_ext(spr_noga,noga_p_index,

x+20*wielkosc+lengthdir_x(noga_p_odl*wielkosc,image_angle+noga_p_odl_kat),

y+20*wielkosc+lengthdir_y(noga_p_odl*wielkosc,image_angle+noga_p_odl_kat),

wielkosc*noga_p_skala,wielkosc,image_angle,c_black,1);

 

draw_sprite_ext(spr_noga,noga_l_index,

x+20*wielkosc+lengthdir_x(noga_l_odl*wielkosc,image_angle+noga_l_odl_kat),

y+20*wielkosc+lengthdir_y(noga_l_odl*wielkosc,image_angle+noga_l_odl_kat),

wielkosc*noga_l_skala,wielkosc,image_angle,c_black,1);

 

draw_sprite_ext(spr_na_graczu,bron_p_index,

x+35*wielkosc+lengthdir_x(ramie_p_odl*wielkosc,image_angle+ramie_p_odl_kat)

+lengthdir_x(przed_ramie_p_odl*wielkosc*ramie_p_skala,image_angle+ramie_p_kat+przed_ramie_p_odl_kat)

+lengthdir_x(bron_p_odl*wielkosc*przed_ramie_p_skala,image_angle+ramie_p_kat+przed_ramie_p_odl_kat+bron_p_odl_kat),

y+35*wielkosc+lengthdir_y(ramie_p_odl*wielkosc,image_angle+ramie_p_odl_kat)

+lengthdir_y(przed_ramie_p_odl*wielkosc*ramie_p_skala,image_angle+ramie_p_kat+przed_ramie_p_odl_kat)

+lengthdir_y(bron_p_odl*wielkosc*przed_ramie_p_skala,image_angle+ramie_p_kat+przed_ramie_p_odl_kat+bron_p_odl_kat),

image_xscale,image_yscale,image_angle+bron_p_kat,c_black,0.7)

 

draw_sprite_ext(spr_na_graczu,bron_l_index,

x+35*wielkosc+lengthdir_x(ramie_l_odl*wielkosc,image_angle+ramie_l_odl_kat)

+lengthdir_x(przed_ramie_l_odl*wielkosc*ramie_l_skala,image_angle+ramie_l_kat+przed_ramie_l_odl_kat)

+lengthdir_x(bron_p_odl*wielkosc*przed_ramie_l_skala,image_angle+ramie_l_kat+przed_ramie_l_odl_kat+bron_l_odl_kat),

y+35*wielkosc+lengthdir_y(ramie_l_odl*wielkosc,image_angle+ramie_l_odl_kat)

+lengthdir_y(przed_ramie_l_odl*wielkosc*ramie_l_skala,image_angle+ramie_l_kat+przed_ramie_l_odl_kat)

+lengthdir_y(bron_l_odl*wielkosc*przed_ramie_l_skala,image_angle+ramie_l_kat+przed_ramie_l_odl_kat+bron_l_odl_kat),

image_xscale,image_yscale,image_angle+bron_l_kat,c_black,0.7)

 

draw_sprite_ext(spr_przed_ramie,przed_ramie_p_index,

x+35*wielkosc+lengthdir_x(ramie_p_odl*wielkosc,image_angle+ramie_p_odl_kat)

+lengthdir_x(przed_ramie_p_odl*wielkosc*ramie_p_skala,image_angle+ramie_p_kat+przed_ramie_p_odl_kat),

y+35*wielkosc+lengthdir_y(ramie_p_odl*wielkosc,image_angle+ramie_p_odl_kat)

+lengthdir_y(przed_ramie_p_odl*wielkosc*ramie_p_skala,image_angle+ramie_p_kat+przed_ramie_p_odl_kat),

wielkosc*przed_ramie_p_skala,wielkosc,image_angle+przed_ramie_p_kat,c_black,1);

 

draw_sprite_ext(spr_przed_ramie,przed_ramie_l_index,

x+35*wielkosc+lengthdir_x(ramie_l_odl*wielkosc,image_angle+ramie_l_odl_kat)

+lengthdir_x(przed_ramie_l_odl*wielkosc*ramie_l_skala,image_angle+ramie_l_kat+przed_ramie_l_odl_kat),

y+35*wielkosc+lengthdir_y(ramie_l_odl*wielkosc,image_angle+ramie_l_odl_kat)

+lengthdir_y(przed_ramie_l_odl*wielkosc*ramie_l_skala,image_angle+ramie_l_kat+przed_ramie_l_odl_kat),

wielkosc*przed_ramie_l_skala,wielkosc,image_angle+przed_ramie_l_kat,c_black,1);

 

draw_sprite_ext(spr_ramie,ramie_p_index,

x+35*wielkosc+lengthdir_x(ramie_p_odl*wielkosc,image_angle+ramie_p_odl_kat),

y+35*wielkosc+lengthdir_y(ramie_p_odl*wielkosc,image_angle+ramie_p_odl_kat),

wielkosc*ramie_p_skala,wielkosc,image_angle+ramie_p_kat,c_black,1);

 

draw_sprite_ext(spr_ramie,ramie_l_index,

x+35*wielkosc+lengthdir_x(ramie_l_odl*wielkosc,image_angle+ramie_l_odl_kat),

y+35*wielkosc+lengthdir_y(ramie_l_odl*wielkosc,image_angle+ramie_l_odl_kat),

wielkosc*ramie_l_skala,wielkosc,image_angle+ramie_l_kat,c_black,1);

 

draw_sprite_ext(spr_tors,tors_index,x+30*wielkosc,y+30*wielkosc,wielkosc*3,wielkosc,

point_direction(x,y,x+50*wielkosc,y+50*wielkosc),c_black,1);

 

draw_sprite_ext(spr_glowa,glowa_index,

x+40*wielkosc+lengthdir_x(glowa_odl*wielkosc,image_angle+glowa_odl_kat),

y+40*wielkosc+lengthdir_y(glowa_odl*wielkosc,image_angle+glowa_odl_kat),

wielkosc*3,wielkosc,point_direction(x,y,x+50*wielkosc,y+50*wielkosc),c_black,1);

surface_reset_target();

}

 

//odpowiedni kod

if surface_exists(global.surf)

{

surface_set_target(global.surf);

draw_clear_alpha(0,0);

 

draw_sprite_ext(moj_sprite,image_index,x+30,y+30,3,1,

point_direction(x,y,x+50,y+50),c_black,1); // wartość image_xscale wynosi

//jak widać 3, ta wartość rozciąga cień, image yscale pozostało bez zmian (wynosi 1).

surface_reset_target();

}

 

3. WAŻNE

 

Funkcja

GML
draw_clear_alpha(0,0);

może być użyta tylko przez jeden obiekt "rysujący" cień. Np. mamy obiekt o_gracz i dajemy mu tę/ą funkcję i reszta obiektów rysujących cień tym samym kodem się już bez niej obejdzie a i cień będzie "rysowała" dobrze.

 

Czekam na propozycje jak zrobić zmienny depth cienia :D (w zależności od depth obiektu "rysującego" cień).

Odnośnik do komentarza
Udostępnij na innych stronach

Mała uwaga, nie każdy ma na tyle dużo pamięci w karcie graficznej by ogarnąć takiego surfaca: global.surf=surface_create(room_width,room_height);

U mnie już przy roomie około 10000x10000 surface się krzaczy. Optymalnie jest dać obszar o wielkości viewa.

 

Inna miniej istotana uwaga: Niektóre karty wymagają rozmiarów 2^n x 2^m przy czym n może się równać m i są liczbami naturalnymi.

Odnośnik do komentarza
Udostępnij na innych stronach

Mała uwaga, nie każdy ma na tyle dużo pamięci w karcie graficznej by ogarnąć takiego surfaca: global.surf=surface_create(room_width,room_height);

U mnie już przy roomie około 10000x10000 surface się krzaczy. Optymalnie jest dać obszar o wielkości viewa.

 

Inna miniej istotana uwaga: Niektóre karty wymagają rozmiarów 2^n x 2^m przy czym n może się równać m i są liczbami naturalnymi.

 

 

Chyba właśnie rozwiązałeś problem fps'ów u mnie :D.

Odnośnik do komentarza
Udostępnij na innych stronach

Zrobiłem coś dokładnie takiego samego :) Ale z racji długości kodu przerzucam się na twój sposób :P

Twoje i tak wyglądają bardziej realistycznie.

 

Masz piąteczkę :)

 

 

Ps.

Tak samo miałem, ze światłem by Dawidds (sam zrobiłem podobne, tylko oczywiście mniej wydajne i gorsze). Może nie doceniam swojej pracy? :D

Odnośnik do komentarza
Udostępnij na innych stronach

ale ze mnie idiota skoro nie dałem go w roomie:P

 

ale i tak bez przykładu chyba nic nie zdziałam

nie chodzi o to że leniwy jestem ale nie rozumiem kodu i gdzie te zmienne których brakuje dawać

___________________________________________

ERROR in

action number 1

of End Step Event

for object object54:

 

Error in code at line 9:

draw_sprite_ext(spr_noga,noga_p_index,

^

at position 18: Unknown variable spr_noga

Odnośnik do komentarza
Udostępnij na innych stronach

Tego miałeś nie używać, przecież jest napisane :P

Weź to co jest niżej :P

GML
//odpowiedni kod

if surface_exists(global.surf)

{

surface_set_target(global.surf);

draw_clear_alpha(0,0);

 

draw_sprite_ext(moj_sprite,image_index,x+30,y+30,3,1,

point_direction(x,y,x+50,y+50),c_black,1); // wartość image_xscale wynosi

//jak widać 3, ta wartość rozciąga cień, image yscale pozostało bez zmian (wynosi 1).

surface_reset_target();

}

 

Tamto wyżej to jest kod do postaci m@rcixxx-a, więc wiadomo, że nie masz tych zmiennych :S

Odnośnik do komentarza
Udostępnij na innych stronach

Może najpierw niech ten obiekt surface się znajdzie w roomie ?

 

Edit: muszę przyznać, że nie wychodzi mi te rysowanie kilku surface'ów w jednym roomie. Obiekty odwołują się tylko do pierwszego. Możecie pomóc rozwiązać ten problem ?

Po co chcesz zaprzątać w to kilka surfaców, jak wystarczy tylko 1.

Jedyne co trzeba zmienić to rozmiar, na wielkość viewa, sposób jego rysowania tzn:

GML
draw_surface_ext(global.surf,view_xview,view_yview,1,1,0,c_white,0.5);

i przesunąć wszystkie elementy, które rzucają cień o -xview i -yview:

GML
draw_sprite_ext(moj_sprite,image_index,x+30-view_xview,y+30-view_yview,3,1,
Odnośnik do komentarza
Udostępnij na innych stronach

Po co chcesz zaprzątać w to kilka surfaców, jak wystarczy tylko 1.

Jedyne co trzeba zmienić to rozmiar, na wielkość viewa, sposób jego rysowania tzn:

GML
draw_surface_ext(global.surf,view_xview,view_yview,1,1,0,c_white,0.5);

i przesunąć wszystkie elementy, które rzucają cień o -xview i -yview:

GML
draw_sprite_ext(moj_sprite,image_index,x+30-view_xview,y+30-view_yview,3,1,

 

Mistrzu mój : D !

Odnośnik do komentarza
Udostępnij na innych stronach

Czekam na propozycje jak zrobić zmienny depth cienia (w zależności od depth obiektu "rysującego" cień).

Cień u ciebie pada zawsze pod tym samym kątem? Bo mógłbyś nadać każdemu elementowi rzucającemu cień zmienną, która odpowiadała by wysokości obiektu. Później sprawdzał byś przy pomocy na przykład twierdzenia Pitagorasa czy postać znajduje się w zasięgu cienia.

Zaczynając to pisać wiedziałem jak to zrobić, a teraz mam pustkę w głowie :(

Odnośnik do komentarza
Udostępnij na innych stronach

Cień u ciebie pada zawsze pod tym samym kątem? Bo mógłbyś nadać każdemu elementowi rzucającemu cień zmienną, która odpowiadała by wysokości obiektu. Później sprawdzał byś przy pomocy na przykład twierdzenia Pitagorasa czy postać znajduje się w zasięgu cienia.

Zaczynając to pisać wiedziałem jak to zrobić, a teraz mam pustkę w głowie :(

 

Surface jest rysowany przez jeden obiekt o jednym depth. Drzewo może mieć depth -111111111 a i tak depth cienia będzie miał tyle co obiekt surface. A co do cienia pod takim samym kątem to można to zmienić. Wystarczy zamiast

 

GML
draw_sprite_ext(moj_sprite,image_index,x+30,y+30,3,1,

point_direction(x,y,x+50,y+50),c_black,1);

 

dać

 

GML
draw_sprite_ext(moj_sprite,image_index,x+lengthdir_x(30,kat_cienia),y+lengthdir_y(30,kat_cienia),3,1,

point_direction(x,y,x+lengthdir_x(50,kat_cienia),y+lengthdir_y(50,kat_cienia)),c_black,1);

Odnośnik do komentarza
Udostępnij na innych stronach

Co do Depth to można zrobić taki myk jak ja tutaj: GM8.1

GM8

Stworzyć 2 surfacy w 2 osobnych obiektach o różnym depth i nałożyć je na siebie.

Tutaj akurat zrobiłem 2 warstwy, cienie od drzew są na niższej a cień od wieży na wyższej więc pada także na drzewa.

Odnośnik do komentarza
Udostępnij na innych stronach

  • 4 miesiące temu...

bo mam , ale np jak stworze obj_podloga to cien nie pada na nim bawilem sie z depthami i nic kij wie co jest chyba w grze nie będzie objektów typu podłoga bo cień nie pada na niego tylko przykrywa go a robiłem wszytsko , szukam teamu który mnie przyjmie bym mógł się uczyć i dał bym swój silni potem tworzył bym super gry z teamem proszę niehc ktoś mnie przyjmię na naukę póki co.

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

Trochę się cofnę:

 

rozmiar surface to:

 

wys x szer x 32 = ilość bitów (32, bo jest też kanał alpha).

wys x szer x 4 = ilośc bajtów

 

Zatem przykład roomu 10000 x 10000, daje 381MB - to już nie byle jaka karta graficzna jest potrzebna.

Obrazek 1024x768 to 3MB.

Odnośnik do komentarza
Udostępnij na innych stronach

Trochę się cofnę:

 

rozmiar surface to:

 

wys x szer x 32 = ilość bitów (32, bo jest też kanał alpha).

wys x szer x 4 = ilośc bajtów

 

Zatem przykład roomu 10000 x 10000, daje 381MB - to już nie byle jaka karta graficzna jest potrzebna.

Obrazek 1024x768 to 3MB.

Zaraz zdawało mi się że GMowe surface nie mają kanału alpha, natknąłem się parę razy na to jak się bawiłem surfacami + blend mody.

Edit: Chyba próbowałem wtedy zrobić multitexturing

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