PsichiX
Użytkownicy-
Postów
5 647 -
Dołączył
-
Ostatnia wizyta
-
Wygrane w rankingu
12
Typ zawartości
Profile
Forum
Wydarzenia
Treść opublikowana przez PsichiX
-
if ( distance_to_object(bohater) < 60 && >= 20 distance_to_object(bohater) ) { bajery }
-
Surfaces Tutorial
PsichiX odpowiedział(a) na PsichiX temat w Gotowe Skrypty, przykłady, dodatki, silniki 3D dla GM
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. -
Surfaces Tutorial
PsichiX odpowiedział(a) na PsichiX temat w Gotowe Skrypty, przykłady, dodatki, silniki 3D dla GM
@UP: juz poprawiam - na szybkiego ostatnie poprawki robilem xD -
Surfaces Tutorial
PsichiX opublikował(a) temat w Gotowe Skrypty, przykłady, dodatki, silniki 3D dla GM
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! ^^ -
obiekt background3d: Create: depth=power(255,3) Draw: d3d_set_projection_ortho(0,0,window_get_width(),window_get_height(),0) d3d_set_hidden(true) draw_background(back,0,0) d3d_set_hidden(false) d3d_set_projection(<argumenty takie jakie stosujesz w kamerze>) // np. d3d_set_projection(x,y,z,xlook,ylook,zlook,0,0,1) To powinno dzialac
-
Hmm. postaram sie na jutro cos wykombinowac... :) @DOWN: Cos sie wymysli ;)
-
sprite_index=choose(krzak1,krzak2,krzak3)
-
Ja mysle ze to przez to ze gm w kazda aplikacje implementuje swoj jezyk skryptowy (gml) - bo jak inaczej wytlumaczyc ze gm moze po uruchomieniu wykonywac instrukcje z zewnatrz (i skad niby byloby to 1mb??)?
-
No to analogicznie zrob to w draw_sprite auta <_< Ludzie, kombinujcie...
-
image_angle=direction w obiekcie auta
-
@UP: A jakze by inaczej :] xD No wiec tak: Aby zrobic wyswietlanie 2d w 3d NIE WOLNO(!) uzywac wylaczania 3d (d3d_end()) bo renderowanie 3d odbywa sie po 'przeleceniu' wszystkich instancji roomu - czyli w przeciwienstwie do 2d dane do rysowania sa zapisywane w macierzy i wykonywane na koncu (po rysowaniu normalnego 2d), tak wiec jesli w pierwszym obiekcie wlaczymy 3d, a w przedostatnim wylaczymy to 3d nie bedzie wogole rysowane (tzn. bedzie, ale wszystkie obiekty jako 2d). Co zatem jest alternatywa? Odpowiedz brzmi: d3d_set_projection_ortho() - wlacza renderowanie 2d podczas wlaczanego trybu 3d. d3d_set_projection_ortho(x,y,width,height,rotation) // wlacza rysowanie 2d d3d_set_hidden(false) // wylacza ukrywanie niepotrzebnych surface <kod rysowania 2d> d3d_set_hidden(true) // zpowrotem wlacza ukrywanie niepotrzebnych surface Ale jest jedna uwaga! obiekt ktory rysuje za pomoca tego kodu MUSI byc pierwsza lub ostatnia instancja w roomie (zeby nie rysowal nastepnych primitywow jako 2d) - naj lepiej jak bedzie pierwszy. No chyba ze po tamtym kodzie dopiszemy spowrotem d3d_set_projection() to obiekt ten moze byc ktorakolwiek instancja. Mam nadzieje ze rozumiecie :) Pozdrawiam :]
-
los=10+random(6) :huh:
-
Wcale nie trudniej, ale polecam top-down - przyjemniejszy
-
Tak jak obiecalem, dzialajacy sposob (postepowac zgodnie z wskazowkami i czytac uwaznie): ReLoader
-
Nie musisz. po poludniu wrzuce na upload dzialajacy przyklad - tak jak mowilem mi dziala :)
-
Jakoz ze mam troche wolnego czasu w dniach szkolnych, to oferuje sie do zrobienia innym uzytkownikom cover'ow (okladek) do ich gier (2 wersje: kolorowa i Red-Gray do gry lowridera). Tak wiec jak ktos chce miec cos takiego a nie ma czasu robic to piszcie na moje PM a w tresci podajcie jaka gra (tytul, itp.), link (jesli nie bylo premiery to opis), oraz co chcecie na tej okladce zobaczyc. W ten sposob wzbogacimy gre lowridera :)
-
https://gmclan.org/up1105_11_tree.html
-
Pokaz kod rysowania i strzelania to bedzie latwiej
-
fname = get_save_filename('Bmp(*.bmp)|*.bmp',''); fname=string_replace_all(fname,'.bmp','')+'.bmp' // tej linilki chyba brakowalo :) if (fname == '') exit; screen_save_part(fname,112,124,112,154)
-
stworz obiekt smuga. Create: alpha=1 rate=1/max(1,player.speed) sprite=player.sprite_index frame=player.image_index xscale=player.image_xscale yscale=player.image_yscale dir=player.image_angle Draw: draw_sprite_ext(sprite,frame,x,y,xscale,yscale,dir,c_black,alpha) alpha-=rate A w obiekcie player Step: instance_create(x,y,smuga)
-
PS. Zrob inne sterowanie, bo te jest sp*****one (czytaj: trudne) :/ Ale powiem ze takie demko mnie wciagnelo. Grywalnosc bedzie to mialo (jak poprawisz sterowanie) :thumbsup:
-
A jestes pewny ze obiekty: twoj oraz waypont3 maja maski? jesli ktorys z nich nie ma maski to ustaw im je.
-
Zrobimy na backgroundach - mniej roboty z nimi obiekt blur (musi byc ostatnia instancja w roomie): Create: blur_bac=-1 Draw: if(background_exists(blur_bac))draw_background(blur_bac,0,0) blur_bac=background_create_from_screen(0,0,window_get_width(),window_get_height(),0,0,0)
-
W 3d czy 2d? W 3d to trzeba dll'a uzyc, bo w gm sie nie zrobi (sprawdzalem wszystkie mozliwe sposoby (nawet ten ponizszy), serio) w 2D wystarczy robic zrzut ekranu, zapisac do sprite'a, a potem rysowac z alpha rownym np. 0.5
-
To ja dam ci okladke z ProLogos Jak sie podoba, moze byc? :)