Skocz do zawartości

Krew i jej rysowanie na surface


Paindemonium

Rekomendowane odpowiedzi

Witam. Może jest to banalne pytanie ale od jakiegoś czasu z tym walczę. Staram się zrozumieć jak zrobić by obiekty i partykle były rysowane na surface, podłożu czy jak tam leci. Najlepszy przykład to krew. Robię grę top down shooter a raczej na tym typie gry się uczę ją robić. Efekty nie są głupie, coś już działa :). Posiadam też wprowadzoną w formie partykli krew, która leci we wszystkie strony z różną prędkością co fajnie imituje krew. Pytanie brzmi jak zrobić by te owe partykle zostawaiały za sobą trwały ślad niczym w tej dennej gierce Zombie Zoeds (taki syf że głowa boli ale dobry przykład prostego wykorzystania tego efektu).Natrafiłem na coś takiego aczkolwiek z wykorzystaniem obiektów (tu też bym miał pytanie ale zakładam ze zasada jest taka sama z wykorzystaniem surface dla partykli jak i obiektów)

. Gość co prawda fajnie tłumaczy ale dość mało konkretnie i przeskakuje trochę kwestii. oraz natrafiłem na troszeczkę konkretów http://forums.tigsource.com/index.php?topic=7441.0 . Oczywiście chciałbym jednak to zrozumieć w dość prosty sposób, od czego zacząć i co przygotować by stworzyć taki efekt. Oczywiście nie jest on tylko na celu by dodać zajefajne rozmazywanie krwi po podłodze ale surface to droga do optymalizacji gry, bo lepiej by na surface był narysowany obiekt niż stał w grze obiekt (np dywan) i zamulał grę, no chyba ze się mylę bo doświadczonym na GM jeszcze nie jestem na tyle by wysnuwać takie wnioski po przejrzeniu wielu tutoriali. Liczę na waszą pomoc i pomysły. Jeżeli będzie taka potrzeba przedstawię kod określonego elementu na którym chcę zaimplementować ten efekt ale najpierw chciałbym poznać konkrety bo nie będę wklejał połowy projektu do posta :).
Odnośnik do komentarza
Udostępnij na innych stronach

Nie jest to łatwe zagadnienie, więc przeniosłem temat do działu "Pytania zaawansowanych".

 

Surface jest najbardziej sensownym i tak na prawdę najłatwiejszym rozwiązaniem. Niestety wymaga od ciebie sporej świadomości co robisz. Musisz pamiętać że surface są przechowywane w pamięci karty graficznej, więc im większa powierzchnia surface tym więcej pamięci zabiera. Surface mniejsze od 1024x1024 będą w porządku.

 

Ogółem najprościej będzie zrobić surface rozmiaru mapy. Wtedy po prostu rysujesz na nim swoją krew. To jest bardzo proste ale musisz umieć obsługiwać surface. Świetne opracowanie tego sposobu masz tutaj w punkcie Debris

Odnośnik do komentarza
Udostępnij na innych stronach

Mialem cos wczoraj napisac, ale nie czulem jak sie zabrac za cos rzetelniejszego. Napisze Ci pare informacji, nie beda wystarczyly, ale krok po kroku dojdziesz do tego z pomoca kilku osób(bo wątpie aby jednej osobie chciało się wszystko pisać).

 

Surface to przestrzeń na której rysujesz jak na obrazku czy jak na ekranie. Podstawowo kiedy coś rysujesz, jest to automatycznie rysowane do surface'u aplikacji, czyli powierzchni która jest wyświetlana w oknie gry.

W momencie w którym zaczynasz rysować do innego surface'u niż ekran gry, koordynaty gry nie są istotne. W grze pozycja [0,0] to lewy górny róg room'u. W nowym surface, [0,0] to lewy górny róg surface, nie ważne gdzie go chcesz potem narysować.

 

Krok 1: Stwórz surface

Aby stworzyć surface musisz skorzystać z funkcji surface_create(szerokosc,wysokosc).

Ta funkcja stworzy surface podanych wymiarów i zapisze go w pamięci karty graficznej. Ta druga połowa zdania jest bardzo ważna. Są tutaj 3 rzeczy to zapamiętania:

1.Surface może zostać usunięty przez system, więc jeżeli będziesz chciał się odwołać do nieistniejącego, wywali błąd.

2.Surface należy usunąć kiedy nie będziesz go potrzebował. Jeżeli ten surface ma ślady krwi na mapie, to powinieneś go usunąć, albo chociaż wyczyścić, przechodząc do innego poziomu.

3.Surface zajmie trochę miejsca w pamięci. Tę pamięć możęsz wyliczyć tak: Szerokość * Wysokość * 4 Bajtów. Np. 1024x1024 będzie ważyło 1024*1024*4 = 4194304 Bajtów = 4096 Kilobajtów = 4Megabajty. Gratuluję, wiesz jak policzyć czy nie wysadzisz komuś karty graficznej w powietrze.

 

Kiedy wywołasz funkcję surface_create zwróci ona ID surface'a, więc musisz je sobie zapisać do jakieś zmiennej.

GML
MojSurface = surface_create(room_width,room_height); //Stworzy surface wymiarow roomu i zapisze jego ID do zmiennej MojSurface</span>

 

Krok 2: Edytuj surface

Tutaj podam 4 kluczowe funkcje dla pracy z surface'ami.

Rysowanie na surface to jego zmienianie. Jeżeli zastanawiało Cię dlaczego surface jest dobre do śladów krwi, to dlatego, że nie wyczyści się. Normalnie, za każdym razem gdy ekran ma być narysowany, jest on całkowicie czyszczony a następnie wszystkie elementy są na nowo na niego rysowane. Surface się wyczyści tylko kiedy i jeżeli będziesz tego chciał.

Aby rozpocząć edycję surface korzystasz z funkcji surface_set_target(ID Surface'a), gdzie w argumencie podajesz nazwę zmiennej w której wcześniej zapisałeś ID surface.

Zanim jednak rozpoczniesz pracę nad surface, musisz się upewnić, że nie został usunięty z pamięci(to się może stać jak zminimalizujesz grę). Do tego służy surface_exists(ID surface).

Jeżeli surface nie istnieje chciałbyś go wpierw na nowo stworzyć.

GML
if !surface_exists(MojSurface) then MojSurface = surface_create(room_width,room_height);

 

Tutaj bardzo ważna rzecz do zapamiętania - Kiedy rysujesz na surface, zostaje tak dopóki nie zresetujesz rysowania spowrotem do normalnego. Musisz pamiętać o wyłączeniu rysowania, bo inaczej wszystko się walnie. Do tego służy surface_reset_target().

Oznacza to, że Twoje rysowanie na surface mieści się między surface_set_target(ID) a surface_reset_target().

 

Ostatnia rzecz przy pracy z surface do zapamiętania, to że kiedy stworzysz surface, nie jest on przezroczysty. Zazwyczaj chcesz aby był, od tego jest funkcja rysowania zwana draw_clear_alpha(0,0) .

W twoim przypadku chcesz wyczyścić surface tylko raz - kiedy zostanie stworzony. Chcesz to zrobić tylko raz, ponieważ chcesz się pozbyć nieprzezroczystych czesci surface'a, ale nie chcesz sie pozbywac namalowanych sladow krwi.

 

W tym momencie caly kod wygladalby tak:

GML
//Create

MojSurface = surface_create(room_width,room_height);

surface_set_target(MojSurface); //Aktywuj ten surface

draw_clear_alpha(0,0); //Wyczysc surface

surface_reset_target(); //Wylacz surface</span>

 

GML
//Update surface, np. w Step

if !surface_exists(MojSurface) //Jezeli surface nie istnieje

{

MojSurface = surface_create(room_width,room_height); //Stworz go na nowo

surface_set_target(MojSurface); //Aktywuj ten surface

draw_clear_alpha(0,0); //Wyczysc surface

surface_reset_target(); //Wylacz surface

}

surface_set_target(MojSurface); //Start rysowania

//Cos co rysujemy

//Jeszcze cos co rysujemy

//A tutaj tez cos jeszcze

surface_reset_target(); //Koniec rysowania</span>

 

 

Krok 3: Narysowanie surface w grze

Aby surface byl widoczny w grze musisz go narysowac w grze. Robisz to tak samo jak ze spritami i backgroundami. Uzywasz do tego funkcji draw_surface(ID Surface,x,y)

 

 

Wiecej szczegolow mozesz przeczytac w dokumentacji w GM'ie lub w wersji zamieszczonej online. Uzyteczne linki:

 

1.Ogólnie o Surface'ach

2.surface_create

3.surface_set_target

4.surface_reset_target

5.draw_clear_alpha

6.surface_exists

7.draw_surface

Odnośnik do komentarza
Udostępnij na innych stronach

Super. Biore się dziś do obadania tego. Pytanie jeszcze na boku. To działa tak samo jak inne elementy dodawane do roomu czyli surrface musi być dodany do roomu jako np obj_surface by na tym roomie to działało (tak jak na tym filmiku youtube co podałem)? Z góry dziękuję za wyczerpujące informacje podane w tym temacie :).

Odnośnik do komentarza
Udostępnij na innych stronach

Możesz surface rysować przez istniejący obiekt lub nowy obiekt którego zadaniem może być właśnie pilnowanie tego surface'a, wybór należy do Ciebie.

Istotne jest, abyś go rysował w evencie Draw i aby miał DEPTH mniejszy od innych obiektów, bo krew jest przecież pod wszystkim innym, na podłodze.

Odnośnik do komentarza
Udostępnij na innych stronach

Super. O wiele więcej kumam z waszych wypowiedzi niż niektórych paplanin tutorialowych na temat surfacu. Mam nadzieję że na tyle to opanuje by zadziałał a potem doszlifowac sprawę by rzeczywiście było to wydajne. Planuje by to coś wyglądało podobnie do tego co mamy w Crimsonland.

 

EDIT: Ok więc wracając jeszcze do fragmentu kodu, który mi zaprezentowaliście a mianowicie:

 

surface_set_target(MojSurface); //Start rysowania

//Cos co rysujemy

//Jeszcze cos co rysujemy

//A tutaj tez cos jeszcze

surface_reset_target(); //Koniec rysowania</span>

 

Jeżeli chodzi o Cos co rysujemy itp ttp, to w tym miejscu mam wprowadzić albo jakiś obiekt np sprite z krwią albo obiekt odpowiadający za tworzenie się konkretnych partykli?

Odnośnik do komentarza
Udostępnij na innych stronach

A więc tak. Jest gra, i stworzony obiekt pod nazwą "obj_blood_surface" którego kod wygląda tak:

 

Create:

 

MojSurface = surface_create(room_width,room_height);

surface_set_target(MojSurface);

draw_clear_alpha(0,0);

surface_reset_target();

 

Step:

 

if !surface_exists(MojSurface)

{

MojSurface = surface_create(room_width,room_height);

surface_set_target(MojSurface);

draw_clear_alpha(0,0);

surface_reset_target();

}

surface_set_target(MojSurface);

draw_surface_ext(MojSurface,0,0,1,1,0,130,1);

surface_reset_target(); /

 

 

Sugerowałem się waszym kodem i informacjami z poprzednich tutoriali.

 

Teraz jednak pytanie brzmi co zrobić by to określony obiekt był celem rysowania. Bo w kodzie nigdzie tego nie widze a np obiekt "obj_sp" dodany do mapy odpowiada za tworzenie sie kropek wylatujących od potwora, który dostał hita/zginął. I np chce by te kropki były celem tej operacji, czyli partykle rysowały na surface ślad. Na razie nic mi z tego nie wychodzi a chce na tyle to zrozumieć by potem samodzielnie modyfikować cały surface tak by np elementy pokroju deski na ziemi narysowały swój ślad czy coś by nie zaśmiecać obiektami mapy.

 

 

Odnośnik do komentarza
Udostępnij na innych stronach

surface_set_target(MojSurface);

draw_surface_ext(MojSurface,0,0,1,1,0,130,1);

surface_reset_target();

 

 

To jest niepoprawne. ustawiasz(i resetujesz) target po to aby rysować NA surface. Aby narysować surface sam w sobie, rysujesz go NORMALNIE .

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