GUI - Graphical User Interface, czyli graficzny interfejs użytkownika dostarcza elementów, które są w grze wyświetlana zazwyczaj nad światem gry. Defold dostarcza niestandardowy edytor GUI i potężne możliwości skryptowe, które są specjalnie dostosowane do budowy i implementacji interfejsów użytkownika.
Graficzny interfejs użytkownika w Defoldzie to komponent, który tworzysz i przypisujesz do obiektu gry, umieszczając go w kolekcji. Ten komponent ma następujące właściwości:
Komponenty GUI są tworzone na podstawie pliku prototypu sceny GUI (nazywanego również “prefabem”, “szablonem” lub “blueprintem” w innych silnikach). Aby utworzyć nowy komponent GUI, kliknij prawym przyciskiem myszy w panelu Assets i wybierz New ▸ Gui. Wprowadź nazwę nowego pliku GUI i naciśnij OK.
Teraz Defold automatycznie otwiera plik w edytorze sceny GUI.
W panelu Outline znajdziesz wszystkie elementy GUI: listę węzłów (nodes) i wszelkie zależności (patrz niżej).
Centralny obszar edycji pokazuje GUI. W pasku narzędziowym w prawym górnym rogu obszaru edycji znajdują się narzędzia Move, Rotate i Scale (odpowiednio Przesuń, Obróć i Skaluj), a także selektor układu layout.
Biały prostokąt pokazuje obszar wybranego layoutu, o domyślnej szerokości i wysokości ekranu ustawionej w ustawieniach projektu.
Wybierając węzeł “Gui” w panelu Outline, zostaną wyświetlone Properties komponentu GUI:
Per Node
- dostosowuje każdy węzeł do dostosowanego rozmiaru węzła nadrzędnego lub zmienionego rozmiaru ekranu.Disable
- wyłącza tryb dostosowywania węzła. To wymusza, aby wszystkie węzły zachowały swój ustawiony rozmiar.Drzewo zasobów w grze Defold jest statyczne, więc wszelkie zależności, które potrzebujesz dla swoich węzłów GUI, muszą być dodane do komponentu. W panelu Outline grupuje się wszystkie zależności według typu w “folderach”:
Aby dodać nową zależność, kliknij prawym przyciskiem myszy root “Gui” w panelu Outline, a następnie wybierz Add ▸ [typ] z kontekstowego menu.
Możesz także kliknąć prawym przyciskiem myszy na ikonie folderu dla typu, który chcesz dodać, i wybrać Add ▸ [typ].
Komponent GUI jest tworzony z zestawu węzłów (nodes). Węzły to proste elementy. Mogą być przesuwane (przesuwane, skalowane i obracane) oraz uporządkowane w hierarchi rodzic-dziecko zarówno w edytorze, jak i w trakcie działania skryptu. Istnieją następujące typy węzłów:
Aby dodać węzły, kliknij prawym przyciskiem myszy na folderze Nodes i wybierz Add ▸, a następnie Box, Text, Pie, Template lub ParticleFx.
Możesz także nacisnąć A i wybrać typ, który chcesz dodać do GUI.
Każdy węzeł ma szeroki zestaw właściwości (properties), które kontrolują jego wygląd:
Manual
, możesz zmienić wartość. Rozmiar określa granice węzła i jest używany do wykrywania interakcji z myszą. Tę wartość można animować za pomocą skryptu (dowiedz się więcej).Automatic
, edytor ustawia rozmiar węzła. Jeśli jest ustawiony na Manual
, możesz samodzielnie ustawić rozmiar.gui.pick_node()
. Użyj gui.set_enabled()
i gui.is_enabled()
do zmiany w kodzie i sprawdzenia tej właściwości.gui.pick_node()
. Użyj gui.set_visible()
i gui.get_visible()
do zmiany w kodzie i sprawdzenia tej właściwości.0
oznacza brak rozstawu międzywierszowego. 1
(domyślnie) to normalny rozstaw międzywierszowy.0
.Alpha
- mieszają się wartości pikseli węzła z tłem. Odpowiada to trybowi “Normal” w oprogramowaniu graficznym.Add
- dodaje wartości pikseli węzła do tła. Odpowiada to trybowi “Linear Dodge” w niektórym oprogramowaniu graficznym.Multiply
- mnoży wartości pikseli węzła przez tło.Możliwe wartości to Center
, North
, South
, East
, West
, North West
, North East
, South West
lub South East
.
Jeśli zmienisz punkt obrotu węzła, węzeł zostanie przesunięty tak, że nowy punkt obrotu będzie znajdować się w pozycji węzła. Węzły tekstowe są ustawiane tak, że Center
ustawia środek tekstu, West
ustawia tekst wyrównany do lewej, a East
ustawia tekst wyrównany do prawej.
Dostępne są następujące tryby kotwiczenia:
None
(zarówno X Anchor, jak i Y Anchor) zachowuje pozycję węzła od centrum węzła nadrzędnego lub sceny, w odniesieniu do jego zmienionego rozmiaru.Left
lub Right
(X Anchor) skaluje poziomą pozycję węzła, aby zachować pozycję z lewego i prawego brzegu węzła nadrzędnego lub sceny w tej samej proporcji.Top
lub Bottom
skaluje pionową pozycję węzła, aby zachować pozycję z górnego i dolnego brzegu węzła nadrzędnego lub sceny w tej samej proporcji.Węzeł utworzony w scenie, w której rozdzielczość logiczna jest typową rozdzielczością krajobrazu:
Dostępne są następujące tryby dostosowania:
Fit
Dopasowanie sceny do ekranu pionowego powoduje rozciągnięcie sceny. Każdy obszar ograniczający węzła jest podobnie rozciągany. Jednak ustawiając tryb dostosowania, można zachować niezmieniony stosunek szerokości węzła.Zoom
skaluje zawartość węzła tak, aby była równa rozciągniętej szerokości lub wysokości prostokątnego obszaru ograniczającego, w zależności od tego, która jest większa. Innymi słowy, zawartość w pełni pokryje rozciągnięty obszar ograniczający węzła.Stretch
rozciąga zawartość węzła, tak aby wypełniła rozciągnięty obszar ograniczający węzła.Jeśli właściwość sceny GUI Adjust Reference jest ustawiona na Disabled
, czyli wyłaczona, to ustawienie to będzie ignorowane.
None
renderuje węzeł jak zwykle.Stencil
powoduje, że obrzeża węzła definiują maskę szablonu, która jest używana do przycinania węzłów podrzędnych węzła.Zobacz instrukcję przycinania GUI.
Kombinacja właściwości Pivot, Anchors i Adjust Mode umożliwia bardzo elastyczne projektowanie interfejsów GUI, ale może być to dość trudne do zrozumienia bez konkretnego przykładu. Przyjrzyjmy się temu projektowi interfejsu GUI utworzonemu dla ekranu o rozdzielczości 640x1136 pikseli:
Interfejs użytkownika jest utworzony z kotwicami X i Y ustawionymi na None, a Tryb Dostosowywania Adjust Mode dla każdego węzła pozostawiony na domyślnym ustawieniu Fit. Pivot dla panelu górnego to North, pivot dla panelu dolnego to South, a pivot dla pasków w panelu górnym to West. Reszta węzłów ma punkty obrotu ustawione na Center. Jeśli zmienimy rozmiar okna, aby było szersze, to oto co się stanie:
Teraz, co zrobić, jeśli chcemy, aby górne i dolne paski zawsze miały taką samą szerokość jak ekran? Możemy zmienić Adjust Mode dla paneli tła na kolor szary na Stretch:
To jest lepsze. Panele tła w kolorze szarym będą teraz zawsze rozciągnięte do szerokości okna, ale paski w panelu górnym oraz dwie skrzynki na dole nie są właściwie umieszczone. Jeśli chcemy, aby paski na górze pozostały po lewej stronie, musimy zmienić X Anchor z None na Left:
To jest dokładnie tak, jak chcemy, żeby było w przypadku panelu górnego. Paski w panelu górnym miały już punkty obrotu ustawione na West, co oznacza, że będą się ładnie pozycjonować z lewym/zachodnim brzegiem pasków (Pivot) przywiązanych do lewego brzegu panelu nadrzędnego (X Anchor).
Teraz, jeśli ustawimy X Anchor na Left dla lewej skrzynki i na Right dla prawej skrzynki, otrzymamy następujący wynik:
To nie jest dokładnie oczekiwany wynik. Obie skrzynki powinny być tak blisko lewego i prawego brzegu, jak paski w panelu górnym. Powodem tego jest błędne ustawienie punktu obrotu:
Obie skrzynki mają ustawiony punkt obrotu - Pivot na Center. Oznacza to, że gdy ekran staje się szerszy, środek skrzynki (punkt obrotu) pozostaje na tej samej względnej odległości od brzegów. W przypadku lewej skrzynki było to 17% od lewego brzegu w oryginalnym oknie o rozdzielczości 640x1136 pikseli:
Gdy rozmiar ekranu jest inny, środek lewej skrzynki pozostaje na tej samej odległości 17% od lewego brzegu:
Jeśli zmienimy Pivot z Center na West dla lewej skrzynki i na East dla prawej skrzynki i przesuniemy skrzynki, otrzymamy oczekiwany wynik, nawet gdy ekran zostanie zmieniony w rozmiarze:
Wszystkie węzły są renderowane w kolejności, w jakiej są wymienione w folderze “Nodes”. Węzeł na górze listy jest rysowany jako pierwszy i będzie więc wyglądać tak, jakby był za innymi węzłami. Ostatni węzeł na liście jest rysowany jako ostatni, co oznacza, że będzie wyglądać tak, jakby był z przodu względem wszystkich innych węzłów. Zmiana wartości Z na węźle nie kontroluje kolejności rysowania; jednakże, jeśli ustawisz wartość Z poza zakresem renderowania swojego skryptu renderującego, węzeł nie będzie już renderowany na ekranie. Możesz również nadpisać kolejność indeksów węzłów warstwami (patrz poniżej).
Wybierz węzeł i naciśnij Alt + W górę/W dół, aby przesunąć węzeł w górę lub w dół i zmienić kolejność indeksu.
Kolejność rysowania można zmieniać w skrypcie:
local bean_node = gui.get_node("bean")
local shield_node = gui.get_node("shield")
if gui.get_index(shield_node) < gui.get_index(bean_node) then
gui.move_above(shield_node, bean_node)
end
Węzeł staje się dzieckiem (ang. child) innego węzła, przeciągając go na węzeł, który chcesz, aby był rodzicem (ang. parent) dziecka. Węzeł z rodzicem dziedziczy transformację (pozycję, obrót i skalę) stosowaną do rodzica i względem punktu obrotu rodzica.
Rodzice są rysowani przed swoimi dziećmi. Wykorzystaj warstwy, aby zmienić kolejność rysowania węzłów rodzica i dziecka oraz zoptymalizować renderowanie węzłów (patrz poniżej).
Warstwy (ang. layers) pozwalają na dokładną kontrolę nad tym, w jaki sposób węzły są rysowane i mogą być używane do zmniejszenia liczby wywołań rysowania (ang. draw calls), jakie silnik musi tworzyć, aby narysować scenę GUI. Gdy silnik ma rysować węzły sceny GUI, grupuje je we wskaźniki wywołań rysowania na podstawie następujących warunków:
Jeśli węzeł różni się od poprzedniego pod względem któregoś z tych punktów, nastąpi przerwanie wskaźnika i zostanie utworzone inne wywołanie rysowania. Przycinanie węzłów (clipping nodes) zawsze przerywa wskaźnik, tak jak i każdy zakres szablonu (stencil scope).
Możliwość organizowania węzłów w hierarchie ułatwia grupowanie węzłów w jednostki łatwo zarządzalne. Jednak hierarchie mogą skutecznie przerywać renderowanie wskaźników, jeśli miesza się różne typy węzłów:
Kiedy potok renderowania (ang. rendering pipeline) przechodzi przez listę węzłów, zmuszony jest utworzyć oddzielny wskaźnik dla każdego oddzielnego węzła, ponieważ typy są różne. Ogólnie rzecz biorąc, te trzy przyciski będą wymagały sześciu wywołań rysowania.
Przypisując węzłom warstwy, można je uporządkować w inny sposób, co pozwala potokowi renderowania grupować węzły w mniej wywołań rysowania. Zacznij od dodania potrzebnych warstw do sceny. Kliknij prawym przyciskiem na ikonę folderu “Layers” w widoku “Outline” i wybierz “Add ▸ Layer”. Zaznacz nową warstwę i przypisz jej właściwość “Name” w widoku “Properties”.
Następnie ustaw właściwość “Layer” dla każdego węzła na odpowiadającą mu warstwę. Kolejność rysowania warstw ma pierwszeństwo nad zwykłym porządkiem indeksów węzłów, więc ustawienie węzłów graficznych przycisku na warstwę “graphics” i węzłów tekstowych przycisku na warstwę “text” spowoduje następującą kolejność rysowania:
Najpierw wszystkie węzły w warstwie “text”, od góry:
Następnie wszystkie węzły w warstwie “tekst”, od góry:
Węzły mogą teraz być grupowane w dwóch wywołaniach rysowania, zamiast sześciu. To znaczna wydajnościowa korzyść!
Należy zauważyć, że węzeł potomny (child node) bez ustawionej warstwy dziedziczy domyślne ustawienia warstwy od węzła rodzica. Nieustawienie warstwy na węźle domyślnie dodaje go do warstwy “null”, która jest rysowana przed innymi warstwami.
Did you spot an error or do you have a suggestion? Please let us know on GitHub!
GITHUB