PsichiX Opublikowano 27 Października 2007 Udostępnij Opublikowano 27 Października 2007 Witam! Artykuł ten pokaże wam jak używać surfaces, które są baaardzo przydatne do gier (np. strategicznych - mgła). Na początek potrzeba nam zarejestrowanej wersji GM. Mamy? No to do dzieła! ;) Artykuł podzieliłem na kilka części: - Wstęp - Proste rysowanie (Paint) - Tworzenie mgły (Fog) - Efektowny ogień (Fire) Na końcu zamieściłem przykład w pliku gm6 byście mogli zobaczyć jak to działa Wstęp Po krótce opiszę wam funkcje rodziny surfaces: surface_create(width,height) - tworzy nową powierzchnię (surfaces) i zwraca do zmiennej jej identyfikator. Argumenty width oraz height oznaczają szerokość i wysokość powierzchni. surface_free(id) - zwalnia powierzchnię o indentyfikatorze id z pamięci (powierzchnie są przechowywane tylko w pamięci karty graficznej, więc od niej zależy ilość możliwych surfaces), by nie zabierała miejsca gdy jej nie używamy. surface_exists(id) - sprawdza czy surfaces o danym id istnieje i zwraca odpowiednią wartość (true - istnieje, false - nie istnieje). surface_get_width(id) - zwraca wartość szerokości danej powierzchni. surface_get_height(id) - zwraca wartość wysokości danej powierzchni. surface_get_texture(id) - zwraca id tekstury danej powierzchni. surface_set_target(id) - kluczowa funkcja powierzchni. Ustala cel dalszego rysowania dla danej powierzchni, czyli wszystko po użyciu tej funkcji będzie rysowane na danej powierzchni. surface_reset_target(id) - gdy skończymy rysować na powierzchni, musimy użyć tej funkcji - ona przywraca cel rysowania do okna gry (po użyciu tej funkcji znów rysowanie będzie się odbywać na ekranie gry). surface_getpixel(id,x,y) - zwraca kolor pixela na pozycji x, y na danej powierzchni (bardzo wolna funkcja - należy używać sporadycznie). surface_save(id,fname) - zapisuje powierzchnię do bitmapy (raczej pixelmapy, czyli kolorowej bitmapy ;P) z podaną nazwą pliku. surface_save_part(id,fname,x,y,w,h) - wykonuje to co powyższa funkcja, tyle że zapisuje część powierzchni (od pozycji x, y, z daną szerokością i wysokością). draw_surface(id,x,y) - rysuje powierzchnię na pozycji x, y. draw_surface_stretched(id,x,y,w,h) - rysuje powierzchnię na pozycji x, y rozciągniętą na daną szerokość i wysokość. draw_surface_tiled(id,x,y) - wypełnia room 'kafelkując' (czyli zapełnia cały room - surfaces obok surfaces :P ) daną powierzchnią, z przesunięciem x oraz y. draw_surface_part(id,left,top,width,height,x,y) - rysuje część powierzchni zaczynając od położenia left oraz top, o szerokości width i wysokości height, na pozycji x, y. draw_surface_ext(id,x,y,xscale,yscale,rot,color,alpha) - rysuje powierzchnię na pozycji x i y, o skali xscale i yscale, obróconą o kąt rot, blendowane (kolorowane) kolorem color i z przezroczystością alpha. draw_surface_stretched_ext(id,x,y,w,h,color,alpha) - rysuje powierzchnię na pozycji x, y rozciągniętą na daną szerokość i wysokość, z nałożonym kolorem color i z przezroczystością alpha. draw_surface_tiled_ext(id,x,y,xscale,yscale,color,alpha) - i znów rysowanie 'kafelkowane' xD, tyle że dodatkowo skalowane, kolorowane i z daną przezroczystością. draw_surface_part_ext(id,left,top,width,height,x,y,xscale,yscale,color,alpha) - rysuje część powierzchni, z możliwością skalowania, kolorowania i przezroczystością. draw_surface_general(id,left,top,width,height,x,y,xscale,yscale,rot,c1,c2,c3,c4, alpha) - ulepszona wersja draw_surface_part_ext() ^^ - rysuje część powierzchni tak jak draw_surface_part_ext(), ale zamiast jednego koloru rysowania ma 4 dla każdego wierzchołka owierzchni. surface_copy(dest,x,y,src) - kopiuje powierzchnię ze źródła src do powierzchni dest na pozycji x oraz y. surface_copy_part(destination,x,y,source,xs,ys,ws,hs) - kopiuje część powierzchni ze źródła src, od pozycji sx i sy, o wysokości ws i szerokości hs źródła, do powierzchni dest na pozycji x, y. Proste rysowanie (Paint) Na początek tworzymy obiekt obj_paint, w create piszemy: color=c_black // kolor rysowania - czarny // początek linii tx=mouse_x ty=mouse_y painting=false // wylaczamy rysowanie linii paint_sur=surface_create(room_width,room_height) // tworzymy nową powierzchnię o szerokości i wysokości zgodnej z rozmiarem rooma surface_set_target(paint_sur) // ustawiamy cel rysowania na powierzchnię paint_sur draw_set_color(c_white) // ustalamy kolor tła powierzchni draw_rectangle(0,0,surface_get_width(paint_sur),surface_get_height(paint_sur),0) // rysujemy tło powierzchni o rozmiarze takim jak nasza powierzchnia surface_reset_target() // resetujemy cel rysowania do ekranu gry Teraz step: // gdy naciskamy LPM ustalana jest pozycja początku linii oraz włączane jest jej rysowanie if(mouse_check_button_pressed(mb_left)) { tx=mouse_x ty=mouse_y painting=true } // jeśli rysowanie linii jest włączone to rysujemy linię i ustalamy znów początek linii if(painting) { // rysujemy linię na powierzchni paint_sur surface_set_target(paint_sur) draw_line_color(tx,ty,mouse_x,mouse_y,color,color) surface_reset_target() // ustalamy początek linii tx=mouse_x ty=mouse_y } if(mouse_check_button_released(mb_left))painting=false // jeśli puścimy LPM to wyłączamy rysowanie linii I na koniec draw: draw_surface(paint_sur,0,0) // rysujemy nasz surface To tyle jeśli chodzi o rysowanie prostych powierzchni :) Tworzenie mgły (Fog) No to teraz nieco trudniej, bo nauczymy sie robić mgłe. Stwórzmy obiekt obj_fog. W create dajemy: // ustalamy pozycje mgły na x=0 i y=0 fog_x=0 fog_y=0 fog_sur=surface_create(room_width,room_height) // tworzymy powierzchnię mgły o rozmiarze roomu surface_set_target(fog_sur) // cel rysowania - powierzchnia fog_sur draw_set_color(c_white) // kolor mgły - czarny, więc czemu napisałem c_white? Bo podczas blendingu typu subtract wszystkie kolory są 'odwracane', tzn. kolor biały jest czarny, a zielony jest fioletowy;P draw_rectangle(0,0,room_width,room_height,0) // rysujemy mgłe surface_reset_target() // resetujemy cel rysowania jako ekran gry draw_set_color(c_white) Event Mouse Global Left Pressed: surface_set_target(fog_sur) // ustalamy cel rysowania do fog_sur draw_set_color(c_black) // ustalamy kolor - biały (w subtract blending odwrócenie czarnego) draw_set_blend_mode(bm_subtract) // ustalamy tryb blendingu (kolorowania) na subtract, czyli co dalej bedzie rysowane z odwróconymi kolorami draw_circle_color(mouse_x-fog_x,mouse_y-fog_y,128,c_white,c_black,0) // rysujemy dwukolorowy okrąg na pozycji myszki względem pozycji mgły, o promieniu 128 pixeli. Dwukolorowy dlatego, by występowało płynne przejście mgły draw_set_blend_mode(bm_normal) // przywracamy blending do normalności surface_reset_target() // resetujemy cel rysowania draw_set_color(c_white) // domyślny kolor - biały A teraz rysowanie w draw: draw_set_blend_mode(bm_subtract) // ustalamy blending na subtract by mgła nie była biała, tylko czarna draw_surface(fog_sur,fog_x,fog_y) // rysujemy nasz surface mgły draw_set_blend_mode(bm_normal) // reset blendingu I to był nieco trudniejszy przykład, który można zastosować np. do gier strategicznych. Efektowny ogień (Fire) No to teraz trudniej, bo do surfaces dochodzą obliczenia dotyczące płomieni. Przykład ten stosujcie rozważnie - jakość szczegółów płomieni będzie wpływała na szybkość gry. Zróbmy obiekt obj_fire. Create: fire_sur=surface_create(0,0) // tworzymy powierzchnię ognia fire_sur fire_delay=0 // alarm odświerzania powierzchni fire_delay_max=3 // czas odświerzania powierzchni - co 3 klatki (stepy, etc.) Następnie step uzupełniamy o kod: if(fire_delay<=0) // jeśli alarm odświerzania ognia jest aktywny { quality=12 // jakość płomieni width=128 // szerokość ognia height=128 // wysokość ognia // tymczasowe zmienne opisujące wielkość płomieni tmns=width/quality tmxs=tmns*1.5 if(surface_exists(fire_sur))surface_free(fire_sur) // jeśli istnieje powierzchnia fire_sur to jest ona kasowana fire_sur=surface_create(width,height) // na nowo tworzymy powierzchnię ognia z nowym rozmiarem surface_set_target(fire_sur) // cel rysowania - powierzchnia fire_sur draw_set_color(c_black) // tło czarne bo takie nie będzie rysowane draw_rectangle(0,0,argument1,argument2,0) // rysujemy tło dla ognia draw_set_color(c_white) // kolor domyślny - biały for(j=0;j<2;j+=1) // ilość warstw koloru płomieni (dwie - czerwona i żółta) { if(j=0)tc=c_red // jeśli j=0 to rysujemy czerwone płomienie if(j=1)tc=c_yellow // jeśli j=0 to rysujemy żółte płomienie for(i=0;i<quality;i+=1) // rysowanie zaczyna się od dołu ku górze ognia { repeat(quality-i) // rysowanie płomieni poziomo zależnie od wysokości { // wyliczenia losowego położenia płomienia tak, by ogień 'zachował' kształt trójkąta ts=tmns+random(tmxs-tmns) tl=random((width-2*ts)/sqrt(sqrt(i+1)))-((width-2*ts)/sqrt(sqrt(i+1)))/2 tx=width/2+tl ty=height-ts-i*(height-2*ts)/quality draw_set_alpha(1/sqrt(i+1)/(j+1)) // ustalenie przeźroczystości płomienia zależnie od wysokości draw_set_blend_mode(bm_add) // blending typu add - przezroczystość dla czarnego koloru draw_ellipse_color(tx-ts,ty-ts*height/width,tx+ts,ty+ts*height/width,tc,c_black,0) // rysowanie elipsy jako płomienia z zachowanym skalowaniem względem wysokości i szerokości ognia draw_set_blend_mode(bm_normal) // reset blendingu - bez przezroczystości draw_set_alpha(1) } } } surface_reset_target() // cel rysowania - ekran gry fire_delay=fire_delay_max // ustalenie alarmu odświerzania na maksymalną wartość podaną jako czas } fire_delay-=1 // tik-tak naszego alarmu odświerzania To co wyżej uważam za najtrudniejsze w tym dziale (opisać te obliczenia to koszmar xD). To teraz draw: draw_set_blend_mode(bm_add) // blending typu add - przezroczystość czarnego koloru draw_surface(fire_sur,x-surface_get_width(fire_sur)/2,y-surface_get_height(fire_sur)) // rysowanie ognia na pozycji x i y względem szerokości i wysokości ognia draw_set_blend_mode(bm_normal) // reset blendingu Tak więc nauczyliśmy się robić painta, mgłę oraz ogień. Miła zabawa, nie? A jeszcze milsze uczucie, że znamy teraz surfaces i wiemy jak je używać :) Do tutka dołączam plik z przykładami: https://gmclan.org/up1105_11_surface_tutorial.html Życzę ciekawych pomysłów na wykorzystanie powierzchni do Waszych gier! PS. Już nie długo pojawi się seria kursów o tworzeniu gier poszczególnych gatunków - cierpliwego czekania! ^^ Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
murdalow Opublikowano 27 Października 2007 Udostępnij Opublikowano 27 Października 2007 ładnie dobra robota :) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Pentalinio Opublikowano 27 Października 2007 Udostępnij Opublikowano 27 Października 2007 Świetna robota! Powinni dodać do zasobów ;) ! Gratuluje chęci i czasu :P . Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Yoda Opublikowano 27 Października 2007 Udostępnij Opublikowano 27 Października 2007 Chyba jest błędzik : :P draw_surface_ext(id,x,y,xscale,yscale,rot,color,alpha) - rysuje powierzchnię na pozycji x i y... draw_surface_ext(id,x,y,w,h,color,alpha) - rysuje powierzchnię na pozycji x, y ... Co nie? Chyba winno być streched_ext :P A poza tym - świetna robota - naprawdę dobry tutek- właśnie zasysam przykład ;) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 27 Października 2007 Autor Udostępnij Opublikowano 27 Października 2007 @UP: juz poprawiam - na szybkiego ostatnie poprawki robilem xD Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Tymon Opublikowano 27 Października 2007 Udostępnij Opublikowano 27 Października 2007 Sporo błędów w opisach, a do tego to miał być artykuł! :P Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 27 Października 2007 Autor Udostępnij Opublikowano 27 Października 2007 Etam, po prostu poszedlem im na reke i pokazalem co jak zrobic i dalem w miare zrozumiale opisy. Jak chcesz to popraw opisy Tymon ;P Grunt że sie przyda. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Snake Opublikowano 27 Października 2007 Udostępnij Opublikowano 27 Października 2007 Muszę przyznać że fajny tutek :P dobra robota :) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Kubx Opublikowano 28 Października 2007 Udostępnij Opublikowano 28 Października 2007 Dobry tutek, widać znasz się na rzeczy ;) Na pewno skorzystam, mam nadzieję inni też. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
CuB3 Opublikowano 28 Października 2007 Udostępnij Opublikowano 28 Października 2007 No nie no :) Widze, iz moj mistrz PsichiX wykresal z siebie siodme poty i napisal na wczorej ten tutek. Co do tutka to omawia on najwazniejsze zagadnienia ktore interesuja ludzi. Jak na przyklad mgla, albo tez rysowanie :) Co do ognia... Hmm... Ogien w surfaces ssie i to mocno :P Najlepszy ogien (ktory zachowuje sie jak realistyczny) mozesz wykrzesac z particli :) Jezeli tutki sie ocenia... To dalbym mu z cala satysfakcja 4.7/5 (Drobne problemy w zrozumieniu mialem. ) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Mistyk Opublikowano 1 Listopada 2007 Udostępnij Opublikowano 1 Listopada 2007 fajne :P Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
masher Opublikowano 1 Listopada 2007 Udostępnij Opublikowano 1 Listopada 2007 Dobry tutek, bravo :thumbsup: Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
mike_p Opublikowano 1 Listopada 2007 Udostępnij Opublikowano 1 Listopada 2007 Nieźle, parę błędów ortograficznych (odświerzać? wtf?), ale ogólnie porządna robota ;) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
CuB3 Opublikowano 1 Listopada 2007 Udostępnij Opublikowano 1 Listopada 2007 O Boze... Odczep sie od mojego mistrza mike'u_p :P BTW. To jest tutek a nie artykul wiec bledy ortograficzne moga byc :) Wazne jest to zeby nooby i nie tylko zrozumialy o co chodzi w Surfaces :) 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ę