Ten artykuł został stworzony dla starszych wersji GameMakera i może nie być aktualny.

Surfaces - co i jak

Sobota, 31 Marca 2007, 17:00
Czas czytania 3 minuty, 20 sekund
Zgodne z GM: gm6 gm7 gm8
Nie wiesz, czym są surface? Chcesz nauczyć się z nich korzystać? Ten artykuł jest dla Ciebie!
Surfaces (ang. powierzchnia) to jedno z wielu dobrodziejstw Game Makera, które bardzo ułatwiają życie programiście. Przez wielu uważane za skomplikowane, trudne w obsłudze i niepotrzebne. Niesłusznie. W tym krótkim artykule postaram się przybliżyć zasadę działania surfaces.

Czasem mamy potrzebę narysowania na ekranie czegoś, co będzie odseparowane od reszty i łatwe w modyfikacji (np. HUD w grze). W takim wypadku najczęściej bawimy się w rysowanie kolejnych elementów w zależności od wartości jakiejś zmiennej. Jest to metoda może i skuteczna, ale niezbyt wygodna. Zamiast się tak katować, lepiej użyć surfaces - bo właśnie głównie do takiego typu zadań są one przeznaczone.

Jak to działa?

Surface to, mówiąc najprościej, powierzchnia, na której możemy zapisać jakieś elementy (figury, obrazki itp.). Dzięki temu, że wszystkie te elementy są ze sobą powiązane, możemy łatwo je obrócić, zeskalować, pokolorować, oteksturować, czy skopiować do pliku. Do obsługiwania powierzchni służą odpowiednie funkcje. Najważniejsze z nich postaram się opisać tutaj.

Pierwsze, co należy zrobić, to stworzyć nowego surface'a o określonych wymiarach. Służy do tego polecenie
kodnew_surface = surface_create(szerokość, wysokość); Funkcja ta zwraca id powierzchni, które będzie niezbędne do wywołania dalszych funkcji.

Teraz postaramy się narysować coś na naszym surface. Aby tego dokonać, musimy rozpocząć tryb edycji powierzchni. Służy do tego komenda
kodsurface_set_target(id_naszego_surface);Bezpośrednio po tym możemy używać funkcji rysujących np. draw_circle.

Uwaga, ważne!
Surface'a nie wolno edytować w evencie Draw! Może to spowodować niewłaściwe rysowanie.

A jak zakończyć tryb edycji? Wystarczy wpisać
kodsurface_reset_target();
Nie pozostaje nam nic innego jak wyświetlić naszego surface'a. W evencie Draw piszemy
koddraw_surface(id_naszego_surface,x,y);
Proste, prawda?
Teraz czas wykorzystać zdobytą wiedzę w praktyce. Napiszemy program, który pozwoli użytkownikowi stawiać na ekranie kolorowe kółka.

Tworzymy nowy obiekt i nazywamy go obj_surface. Następnie piszemy:

Create:
kodnew_surface = surface_create(room_width,room_height); // tworzymy nowego suface'a o wymiarach room'a
surface_set_target(new_surface);//rozpoczynamy tryb edycji
draw_set_color(c_black);
draw_rectangle(0,0,room_width,room_height,0); //czyścimy surface'a, rysując na ekranie czarny prostokąt
surface_reset_target(); //kończymy tryb edycji

Step:
kodif ( mouse_check_button_pressed (mb_left) )
{

    surface_set_target(new_surface);
    col1 = make_color_rgb(random(255),random(255),random(255));
    col2 = make_color_rgb(random(255),random(255),random(255));
    draw_circle_color(mouse_x,mouse_y,100,col1,col2,0);
    // jeżeli user kliknie myszą, rysujemy koło w losowym kolorze
    surface_reset_target();

}

Draw:
koddraw_surface(new_surface,0,0);
Uruchamiamy grę i chwilę rozkoszujemy się stawianiem kółek na ekranie.

Teraz dodamy do naszego programu możliwość zapisu.
Do eventa Step dopisujemy:
kodif (keyboard_check_pressed(vk_space))
{

    surface_save(new_surface,'obrazek.bmp');

}

Łatwo możemy też dodać obracanie, skalowanie, rozjaśnianie obrazu, posługując się funkcją draw_surface_general. Ale to już pozostawiam Wam. :)


A na koniec kilka ważnych uwag.

-Surfaces nie działają poprawnie w trybie 3D. Można używać ich dopiero po zakończeniu tegoż trybu (d3d_end()), ale należy pamiętać, że po ponownym uruchomieniu trybu 3D, surfaces zostaną zniszczone.
-Surfaces są zapisywane w pamięci karty graficznej. W skutek tego można utracić surface'a podczas np. zmiany rozdzielczości czy włączenia się wygaszacza ekranu.
-Surfaces nie są zapisywane wraz z grą.


Mam nadzieję że ten art pomógł zrozumieć istotę i zastosowanie surfaces. Po więcej zapraszam do helpa i mojego przykładu Menu z użyciem surfaces.
Pozdrawiam.
Komentarze (łącznie 40, wyświetlam 1 - 15):
Cekol (Sob., 31 Mar. 07, 17:01)
#1

Pierwszy! Ja akurat wiem do czego są surface :)
Się namęczyłeś.

krychu90 (Sob., 31 Mar. 07, 17:34)
#2

Dobre, lecz są drobne błędy np. w pierwszym kodzie :)

Dark Maximal (Sob., 31 Mar. 07, 17:38)
#3

Już poprawiłem. x] Wszystko przez te głupie tagi Ranmusa, które trzeba pisać wielkim literami. ;p

Tymon (Sob., 31 Mar. 07, 17:48)
#4

Pozwoliłem sobie na małą modyfikację. :P

Art jest super! :3

Jakim (Sob., 31 Mar. 07, 18:50)
#5

Popieram przedmówcę :). Przy okazji: poprawiono drobne literówki.

K
Kubx (Sob., 31 Mar. 07, 18:52)
#6

Art jest ok. Trochę bardziej teraz rozumiem surface's.

Ranmus (Nie., 01 Kwi. 07, 12:31)
#7

Moim zdaniem artykuł nie jest taki super, bo po prostu brakuje w nim paru bardzo ważnych rzeczy. Jeszcze przed jego przeczytaniem zastanawiałem się czy autor o tym zapomni.... i zapomniał. :)

Mianowicie chodzi mi o to, że surface to dość kontrowersyjny temat i powinno się wymienić jego zalety oraz przede wszystkim WADY. Samo napisanie o separacji jako zalecie nie wystarczy. Warto tutaj dodać coś o odciążeniu gm'a w rutynowym rysowaniu tych samych elementów. A z wad autor nie wspomniał o tej najważniejszej, że surface jest umiejscowiony w pamięci karty graficznej, a co przez to idzie - są limity. Bodajże na karcie grafiki z 32 MB ramu możliwe jest zrobienie 3 surface'ów na raz o rozmiarze 1024x768 (lub 1280x1024 - nie pamiętam bo dawno nie testowałem już), zanim kolejny nowy surface nie spowoduje utratę najstarszego. I to jest bardzo ważne, bo prowadzi do wielu nieoczekiwanych błędów.

Krótko mówiąc, Dark Maximal, musisz dodać to i owo. :) Mały hint z helpa:
You should never change the drawing target while you are actually drawing on the screen, that is, never use it in drawing events. This will cause serious problems with the projection and viewport.
Surfaces do not work correctly with 3D mode. You can use them while not in 3D mode (by calling d3d_end() before using them, but once you start 3D mode again the surfaces will be destroyed.
For reasons of speed, the surface is maintained in videomemory only. As a result, you might loose the surface when e.g. the screen resolution changes or the screensaver pops up.
Surfaces will not be saved when saving a game.

Matthew_Kane (Nie., 01 Kwi. 07, 14:15)
#8

LOL, pomieszało mi się z particlesami XD

Art jest spox. Surface'y też gdyby nie mulenie... nie spotkałem się z tym w swoich grach, w których wykorzystałem surface'y, ale pewnie dlatego, że mało ich używałem.

Tymon (Nie., 01 Kwi. 07, 14:19)
#9

Jakie mulenie? Używanie surface'ów jest lepszą alternatywą dla zwykłego drawa.

Dark Maximal (Nie., 01 Kwi. 07, 15:06)
#10

Ranma:
Co do wycinka z helpa: na śmierć zapomniałem. ;p Zaraz dodam.
Co do reszty: omg, nie wiedziałem, że jest aż tak źle. =0 Pozostaje mi tylko zasłaniać się faktem, że to mój pierwszy art. ;p

P
Patrysław (Nie., 01 Kwi. 07, 16:12)
#11

Czepiacie się, ładny art jest. :D

Issen (śro., 04 Kwi. 07, 11:17)
#12

a nie powinni być round(random(255))??

Tymon (śro., 04 Kwi. 07, 11:18)
#13

A po co?

Issen (śro., 04 Kwi. 07, 11:21)
#14

żeby były liczby całkowite. Po co nam wartości z przecinkiem w losowaniu koloru??

Tymon (śro., 04 Kwi. 07, 11:40)
#15

A wiesz kochany że ta funkcja i tak przybliża sobie wartości do całkowitych? :3

Najnowsze wersje GameMakera:

Stabilna
2024.2.0.132 • 2024.2.0.163
wydana 15 dni temu
LTS
2022.0.2.51 • 2022.0.2.49
wydana 154 dni temu
Beta
2024.400.0.516 • 2024.400.0.537
wydana  5 dni temu
= IDE, = Runtime
Użytkownicy online
1 użytkownik aktywny:
gości: 1,
(~ostatnie 15 minut)
Discord
Shoutbox
I am Lord (19:15, 17.03.24)
6h mam na to hmmm
I am Lord (19:06, 17.03.24)
Ale temat fajny
gnysek (01:33, 13.03.24)
Powinno działać, jest w kodzie sortowanie wg. najbliższego startu :)
Uzjel (21:59, 11.03.24)
Nie, ale za pierwszym razem zrobiłem fuckup, że było "Tura testowa" X_X
I am Lord (16:58, 11.03.24)
A co Uzjel już masz nawymyślane 100 tematów? 😅
Uzjel (20:08, 10.03.24)
@gnysek a jak bym dodał kilka lig na raz to walnie?
Uzjel (20:08, 10.03.24)
Liga będzie zawsze od piątku 16:00 do poniedziałku 23:59, zawsze w środku miesiąca.
gnysek (08:48, 10.03.24)
Tak, to też jest do poprawy X_X
Adriann (18:22, 09.03.24)
Tylko myślę czy nie leiej gdyby mówiło że zostało tyle i tyle dni i ileś godzin a nie tylko w godzinach ;d Albo konkretna data obok, byłoby czytelniej
I am Lord (15:08, 08.03.24)
o super z tą ligą :)
Starsze wpisy znajdziesz w Archiwum.
Ankieta
Ile zarobiłeś do tej pory na grach stworzonych w GM?