W samym sercu koncepcji silnika Defold znajduje się kilka elementów, których zrozumienie ułatwia dalszą pracę z silnikiem. Instrukcja ta wyjaśnia czym są takie bloki służące do budowania aplikacji. Po zapoznaniu się z poniższą instrukcją, warto przejść do Instrukcji adresowania i przesyłania wiadomości. Na stronie Defold znajdziesz również tutoriale dla początkujących dostępne nawet z poziomu edytora, aby umożliwić Ci szybki start z silnikiem Defold.
Przy budowaniu gier na silniku Defold używa się trzech podstawowych elementów:
Kolekcje mają strukturę drzewa, która przechowuje obiekty i inne kolekcje. Kolekcje są zawsze przechowywane w formie pliku.
Kiedy Defold startuje, wczytuje pojedynczą, główną kolekcję bootrstrapową określoną w pliku “game.project”. Kolekcja bootstrapowa jest często nazywana “main.collection” (i tak jest też domyślnie nazwana po otwarciu każdego nowego projektu), ale oczywiście możesz używać dowolnej nazwy.
Kolekcja może zawierać obiekty i inne kolekcje (przez referencję do pliku sub-kolekcji) zagnieżdżone na dowolną “głębokość”. Poniżej jest przykład kolekcji “main.collection”. Zawiera ona jeden obiekt gry (z id “can”)i jedną sub-kolekcję (z id “bean”). Sub-kolekcja ta zawiera z kolei obiekty “bean” i “shield”.
Zauważ, że sub-kolekcja z id “bean” jest przechowywana w osobnym pliku nazwanym “/main/bean.collection”, a kolekcja nadrzędna “main.collection” zawiera do tego pliku jedynie referencję:
Nie można zaadresować kolekcji samej w sobie, ponieważ nie istnieją obiekty w czasie rzeczywistym, które reprezentują kolekcje “main” czy “bean” - nie można więc wysłać wiadomości do kolekcji samej w sobie, a tylko do obiektów i komponentów. Jednak czasem chcesz wysłać wiadomość do obiektu z innej kolekcji niż kolekcja, w której nadawca się znajduje, więc dlatego określą się ścieżkę (ang. path) do takiego obiektu z uwzględnieniem id kolekcji (Szczegóły znajdziesz w Instrukcji adresowania):
-- file: can.script
-- get position of the "bean" game object in the "bean" collection
local pos = go.get_position("bean/bean")
Kolekcja dodawana do innej kolekcji jest zawsze referencją do pliku kolekcji:
Naciśnij Prawy-przycisk-myszki na kolekcji w panelu Outline i wybierz Add Collection File.
Obiekty gry to bardzo proste obiekty posiadające indywidualny czas życia w trakcie wykonywania programu. Posiadają pozycję, orientację i skalę, a parametry te mogą być manipulowane i animowane osobno w czasie działania programu.
-- animate X position of "can" game object
go.animate("can", "position.x", go.PLAYBACK_LOOP_PINGPONG, 100, go.EASING_LINEAR, 1.0)
Obiekty gry mogą być używane jako puste obiekty (jako znacznik pozycji (ang. waypoint, startpoint, checkpoint etc.)), ale najczęściej zawierają komponenty, takie jak sprite’y, dźwięki, skrypty, modele, fabryki, efekty cząsteczkowe i inne. Obiekty te są tworzone albo z poziomu edytora i umieszczane bezpośrednio w plikach kolekcji (statycznie) albo dynamicznie, w kodzie, dzięki fabrykom (ang. factory).
Obiekty gry są więc dodawane jako nowe obiekty zdefiniowane w pliku kolekcji lub również w pliku kolekcji, ale jako referencja do osobnego pliku z definicją obiektu gry:
Naciśnij Prawy-przycisk-myszki na kolekcji w panelu Outline i wybierz Add Game Object (dodasz definicję do kolekcji) or Add Game Object File (dodasz do kolekcji referencję do pliku z definicją obiektu).
Jest to jeszcze dogłębniej wytłumaczone poniżej.
Components are used to give specific expression and/or functionality to game objects. Components have to be contained inside game objects and are affected by the position, rotation and scale of the game object that contains the component:
Many components have type specific properties that can be manipulated and there are component type specific functions available for interacting with them in runtime:
-- disable the can "body" sprite
msg.post("can#body", "disable")
-- play "hoohoo" sound on "bean" in 1 second
sound.play("bean#hoohoo", { delay = 1, gain = 0.5 } )
Components are either added in-place in a game object, or added to a game object as a reference to a component file:
Right-click the game object in the Outline view and select Add Component (add in-place) or Add Component File (add as file reference).
In most cases it makes most sense to create components in-place, but the following component types must be created in separate resource files before being added by reference to a game object:
Odsyłamy do osobnej Instrukcji do komponentów, gdzie znajduje się lista wszystkich komponentów silnika Defold.
Kiedy tworzysz plik kolekcji, obiektu gry lub nawet komponentu (np. w panelu Assets), tak naprawdę tworzysz tylko szablon, prototyp (ang. blueprint, prototype). Tworzy to tylko i wyłącznie plik w strukturze Twojego projektu, natomiast nic nie jest dodawane do samej gry. Aby stworzyć instancję kolekcji, obiektu czy komponentu do gry, która bazuje na takim pliku-szablonie, dodać należy taką instancję w jednej z Twoich kolekcji.
W panelu Outline możesz zobaczyć na jakim pliku bazuje dana instancja, jeśli była ona stworzona z pliku, a nie bezpośrednio w panelu Outline właśnie. Przykładowo, kolekcja “main.collection” poniżej zawiera trzy instancje, które bazują na już utworzonych plikach:
Korzyścią z używania szablonów/plików jest zdecydowanie możliwość stworzenia wielu instancji obiektu gry lub kolekcji i zmiana ich wszystkich naraz w jednym pliku:
Przy zmianie pliku każda instancja utworzona z tego pliku zostaje natychmiastowo zaktualizowana:
W pliku kolekcji możesz tworzyć hierarchie obiektów gry (game objects) w ten sposób, że jeden z obiektów jest dzieckiem innego obiektu - rodzica. Po prostu przeciągnij jeden z obiektów gry i upuść nad innym obiektem - zostanie on umieszczony w drzewku pod tym obiektem i stanie się jego dzieckiem:
Relacja rodzic-dziecko jest dynamiczną relacją wpływającą na zmianę pozycji, orientacji i skali obu obiektów. Każda transformacja tych wartości zaaplikowana do obiektu rodzica zostanie następnie zaaplikowana do obiektu dziecka, aby ich wzajemna, względna pozycja/orientacja/skala pozostała taka sama, 1:1, zarówno w edytorze jak i w czasie działania programu:
Z kolei wszystkie transformacje na obiekcie dziecku są wykonywane w układzie odniesienia rodzica. W edytorze Defold możesz wybrać, czy operacje na obiekcie dziecku są wykonywane w układzie lokalnym rodzica (local space) czy w głównym układzie odniesienia (world space) klikając Edit ▸ World Space (domyślnie ustawione) lub Edit ▸ Local Space.
Jest też możliwe zmienienie rodzica danego obiektu przez wysłanie do niego wiadomości set_parent
.
local parent = go.get_id("bean")
msg.post("child_bean", "set_parent", { parent_id = parent })
Częstym błędem jest postrzeganie przypisania obiektu jako dziecka innego obiektu w kolekcji jako zmiana miejsca tego obiektu w hierarchii kolekcji. Są to jednak dwie osobne rzeczy. Relacje rodzic-dziecko dynamicznie zmieniają graf w panelu Outline, co pozwala wizualnie ją przedstawić. Jedyną rzeczą, która określa adres obiektu jest jej miejsce w hierarchii kolekcji. Adres jest statyczny podczas całego cyklu życia obiektu.
Did you spot an error or do you have a suggestion? Please let us know on GitHub!
GITHUB