Stałe i enumeratory (constants, macros, enums)

Wtorek, 27 Lipca 2021, 15:55
Czas czytania 3 minuty, 55 sekund
Zgodne z GM: gms1 gms2
Jak korzystać z definicji która podmieni wybrany przez nas identyfikator na konkretną stałą wartość (aby nie korzystać ze zmiennych), oraz jak stworzyć zmienne które pomogą nam w grupowaniu czy odróżnianiu stanów/flag zachowań w grze.
GameMaker jeszcze w zamierzchłych czasach wprowadził zmienne zwane stałymi. Na pewnym jednak etapie YoYoGames postanowiło zmienić im nazwę na macros (makra), głównie z powodu ich faktycznego działania.

Makra (constants, macros)
W przeciwieństwie do prawdziwych stałych, które są w innych językach programowania i są dostępne jako identyfikatory z wartością w czasie działania, makra działają podobnie do chociażby dyrektywy #define z C/C++ i są jedynie definicją stworzoną przez programistę, informującą kompilator, które miejsce kodu należy zwyczajnie zastąpić podaną przez nas wartością.

Po usunięciu dedykowanego okienka znanego z GM i GMS 1.x, stałe definiuje się obecnie w dowolnym miejscu kodu, za pomocą prefiksu #macro, następnie nazwy i wartości, np.:
kod#macro nazwa_makra 15
Potem wystarczy użyć identyfikatora nazwa_macra w dowolnym miejscu kodu, a w momencie kompilacji zostanie ona podmieniona na wybraną przez nas wartość, np.:

kod#macro szerokosc_etapu 2000
if (x > szerokosc_etapu) {
...
Warto dodać, że po definicji makra nie dajemy średnika, gdyż wszystko co znajduje się po pierwszej spacji za jego nazwą, zostanie podmienione i mogłoby powodować błędy składni. Powyższy fragment jeszcze przed odpaleniem gry, w trakcie kompilowania zmieniony zostanie na:
kodif (x > 2000) {
...
a w samej grze po naszej definicji nie zostanie ślad. Działa to więc trochę tak, jakby edytor za nas wykonywał funkcję "Znajdź i zamień" za każdym razem, gdy testujemy/kompilujemy grę.

Makra można oczywiście wykorzystać w bardziej kreatywny sposób, nie tylko podając wartości tekstowe/liczbowe ale np. nazwę zasobu czy nawet cały fragment kodu:
kod#macro pink make_color_rgb(255,192,203)
...
draw_set_color(pink);
// powyższy kod w momencie kompilacji da nam:
// draw_set_color(make_color_rgb(255,192,203));
Wskazówka:
Przez to, że GMS nie wykona funkcji w momencie kompilowania zwracając wartość, a robi jedynie znajdź i zamień, warto w przypadku kolorów podawać gotowe wartości HEX (w odwróconej kolejności BBGGRR), np. kolor różowy #FFC0CB w GMS zapiszemy jako $CBC0FF - znak $ oznacza liczby szesnastkowe)

Nic nie stoi też na przeszkodzie, aby napisać:
kod#macro jest_daleko if (x > 20 && zmienna = true)
...
jest_daleko {
// nasz kod
}

W ten sposób można też nadpisać oryginalne funkcje GMowe:
kod#macro show_debug_message moja_funkcja
show_debug_message(value);
Ponieważ wszystko działa na zasadzie "znajdź i zamień", aby nadal móc wykorzystać oryginalną funkcję, wystarczy zdefiniować ją jako kolejne makro linijkę niżej (ważne, aby nie linijkę przed, bo wtedy nasza definicja zastąpi tę sprzed chwili):
kod#macro show_debug_message moja_funkcja
#macro stare_sdb show_debug_message// teraz wszystkie wywołania stare_sdb staną się show_debug_message
Pamiętajmy jednak, że funkcje tak nadpisane muszą mieć tę samą liczbę argumentów, gdyż GM sprawdzi poprawność przed zastąpieniem makra i będzie się burzył :)

Wielolinijkowe makra zapisujemy natomiast tak:
kod#macro hello show_debug_message("Hej " + \
string(player_name) + \
", jak się masz?");

Można też używać makro dla różnych konfiguracji (Configs - manual.yoyogames.com/Settings/Configurations.htm ):
kod#macro rozmiar_ekranu 1920
#macro KonfiguracjaAndroid:rozmiar_ekranu 1270

Enumeratory (enum)
Na podobnej zasadzie działają enumeratory. One także zostają zastąpione w momencie kompilacji gry, ale mogą być tylko typu integer. Zaletą jest jednak fakt, że edytor podpowiada ich składnię i wartości, więc są przydatne do definiowania typów przedmiotów, czy flag/stanów jakiegoś zdarzenia (np. czy bohater biegnie czy idzie, albo jakiego typu jest przeciwnik).
Wskazówka:
wartości liczbowe enum nie są tak naprawdę typem real, a int64, w związku z tym funkcja is_real() zwraca dla nich false. Warto używać zamiast tego funkcji is_numeric()
Domyślnie enumeratory, jeśli nie nadano im wartości, są numerowane od 0 do n (0, 1, 2, 3...).
kodenum moj_enum {
czerwony,
zielony,
niebieski,
czarny
}

show_debug_message(moj_enum.czarny); // zwroci 3
// w momencie kompilacji gry tak naprawdę powyższa linijka zmieni się na:
// show_debug_message(3)

Enumeratory nie muszą być jednak numerowane kolejno i tak długo, jak zachowamy warunek, że ich wartości są liczbowe, można nawet używać zdefiniowanych wcześniej (ale nie później) enumeratorów do ustawiania wartości, włącznie z prostymi działaniami:
kod
enum domki {
parterowy = 250,
pietrowy = domki.parterowy * 2,
wiezowiec = $F + 5,
empire_state_pietra = 102,
drapacz_chmur = domki.parterowy * domki.empire_state_pietra
}

show_debug_message(domki.drapacz_chmur); // zwraca 25500
// w momencie kompilacji powyższa linijka zmieni się na:
// show_debug_message(25550);
Komentarze (łącznie 0):
Nie ma jeszcze żadnego komentarza. Czas to zmienić

Najnowsze wersje GameMakera:

Stabilna
2024.06.2.162 • 2024.6.1.208
wydana 12 dni temu
LTS
2022.0.2.51 • 2022.0.2.49
wydana 284 dni temu
Beta
2024.800.0.597 •
2024.800.0.620
 0.11.0

wydana  2 dni temu
= IDE, = Runtime, = GMRT
Użytkownicy online
1 użytkownik aktywny:
gości: 1,
(~ostatnie 15 minut)
Discord
12 użytkownicy online na discordzie:
Carl-bot, RogerDodg3r, p..., LadyLush, GibkiKaktus, Grela, Moldis, Dyno, LeD, bagno, l..., Alkapivo
Shoutbox
gnysek (18:31, 25.07.24)
Ogłaszam nowy etap w historii GameMakera.
gnysek (11:36, 08.07.24)
Ale w sumie taki numer GG był bezpieczniejszy niż nr. telefonu czy kontakt społecznościowy. Utrudniał stalkowanie i ułatwiał banowanie.
Wojo (08:08, 08.07.24)
Niestety to już nie te czasy kiedy pytało się kasjerki o wiek i numer Gadu-Gadu...
Adriann (08:28, 05.07.24)
Albo okraść :|
Adriann (08:28, 05.07.24)
Może pani chciała zobaczyć twoje dane i Cię poderwać :d
gnysek (10:38, 03.07.24)
Mnie ostatnio w Żabce zapytali o wiek. A mam już ponad dwie osiemnastki.
Wojo (08:27, 30.06.24)
Ogólnie to miał być żart ponieważ portal internetowy, którego można opisać jako PH jest portalem przeznaczonym dla dorosłych. Miało być śmiesznie wyszło żenująco, a wiadomości w shoutboxie nie mogę skasować :P
Wojo (09:40, 28.06.24)
Tymon jak co wizytę musiałem potwierdzić wiek
gnysek (14:15, 17.06.24)
Bo Łapusz woli alkohol, niż się organizować. Co tam Pixel Heaven, sprawdźcie jego zbiórki na książki...
Adriann (21:02, 13.06.24)
Bardzo słusznie, straszna patola z tą organizacją :D
Starsze wpisy znajdziesz w Archiwum.
Ankieta
Ile zarobiłeś do tej pory na grach stworzonych w GM?