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.13.0.190 • 2024.13.0.238
wydana  3 dni temu
LTS
2022.0.3.85 • 2022.0.3.99
wydana 129 dni temu
Beta
2024.1300.0.785 •
2024.1300.0.790
 0.16.1

wydana 15 dni temu
= IDE, = Runtime, = GMRT
Użytkownicy online
2 użytkowników aktywnych:
gości: 1, userów: 1
 Adriann
(~ostatnie 15 minut)
Discord
43 użytkownicy online na discordzie:
Alice, LeD, Nitro Slav, Tymon, Carl-bot, lethian, Wielki Druid, Kysiu, Kowu, Kuzyn, OdrzuconyKrakers, fervi, 𝕳𝖚𝖌𝖔 𝕲𝖔𝖓𝖝𝖆𝖑𝖊𝖝, m..., 42traviss, r..., Threef, Uzjel, 🧁Cupcake🧁, antek, firemark, yazaa, Dyno, 🆅🅸🆃🅾74🅼, Deusald, szmalu, ZYGZAK, LadyLush, Marco, 21Lancz, bagno, Tidżi, Mtax, g..., Sporek, Kandif, l..., Cebul, Borek, s..., Add92, h..., Shockah
Shoutbox
gnysek (13:44, 10.04.25)
Za 3-4 miesiące GM przejdzie na wydania "półroczne", więc korzystanie z wersji beta żeby sprawdzić nowości będzie wskazane :P
Adriann (18:09, 08.04.25)
Odpowiadam, dzisiaj :D
Adriann (20:48, 04.04.25)
A kiedy te UI layery mają wejść do normalnej wersji gma?
gnysek (00:38, 11.03.25)
I jak, zobaczyłeś ? :D Trochę im zjechało na publiczny release, ale były już w ostatnich dniach lutego dostępne jak się wie, jak pobrać kandydatów do bety :P
Kuzyn (21:30, 05.03.25)
uwierzę jak zobaczę :P
gnysek (10:35, 18.02.25)
W ciągu 10 dni mają wyjść w końcu Layery UI :D
Wojo (10:25, 27.12.24)
Jak tworzyłeś* ah ta niecną autokorekta (kiedyś też stworzyłem apki na androida w sumie)
Wojo (10:23, 27.12.24)
O siemka baca, czasami myślę o tobie w kontekście tego jak tworzyłem apki na androida. Swoją drogą czasami zapominam, że forum istnieje bo cały ruch teraz utrzymuje się na discordzie, ale pora to zmienić!
Uzjel (20:17, 10.12.24)
Cały ruch przeniósł się na Discorda.
MagnusArias (17:43, 01.12.24)
O matko... a ja tutaj jestem od ponad 15 lat i czasami zaglądam... biernie bo biernie, ale czasem wpadnę
Starsze wpisy znajdziesz w Archiwum.
Ankieta
Ile zarobiłeś do tej pory na grach stworzonych w GM?