2010-04-20 16 views
11

Proszę, pomóż klasyfikować sposoby organizowania kodu gry C++/Lua i rozdzielać ich obowiązki. Jakie są najbardziej dogodne sposoby, z których korzystasz?Lua i C++: rozdział obowiązków

Na przykład Lua może być użyty do inicjalizacji obiektów C++ lub w każdej iteracji pętli gry. Może być używany tylko do logiki gier lub grafiki. Niektóre silniki gier zapewniają pełną kontrolę wszystkim podsystemom ze skryptów! Naprawdę nie podoba mi się to podejście (w ogóle nie ma separacji).

Czy to dobry pomysł, aby zaimplementować wszystkie obiekty gry (npc, lokalizacje) jako tabele Lua bez obiektów C++? Lub lepiej jest je zwierciadło (tabele Lua do kontroli obiektów C++)? Albo coś innego?

Dziękuję.

Edit. Moja klasyfikacja: Lua and C++: separation of duties.

Tematy kontynuacja: Lua, game state and game loop

Odpowiedz

4

Moje podejście polegało na ograniczeniu tego, co jest najbardziej narażone na Lua. Nigdy nie znalazłem potrzeby "głównej" lub innej takiej funkcji, która jest wywoływana za każdym razem, gdy scena jest renderowana (lub więcej). Niektóre silniki Lua (takie jak MIŁOŚĆ) robią to jednak. Wolę definiować obiekty z opcjonalnymi funkcjami wywołania zwrotnego dla typowych zdarzeń, na które obiekt może reagować, na przykład kolizja, kliknięcie myszą, wejście lub wyjście ze świata gry, itp.

Wynik końcowy jest bardzo deklaratywny, prawie plik konfiguracyjny dla obiektów. Mam funkcję tworzenia klas lub typów obiektów i inną dla tworzenia obiektów opartych na tych typach. Obiekty mają wtedy kolekcję metod, które można wywoływać podczas reagowania na różne zdarzenia. Wszystkie te metody Lua mapują na metody C/C++, które z kolei modyfikują prywatne właściwości obiektu. Oto przykład z obiektu wiadra, które mogą rejestrować obiekty kulowe:

define { 
    name='ball'; 
    texture=png('images/orb.png'); 
    model='active'; 
    shape='circle'; 
    radius=16; 
    mass=1.0; 
    elastic=.7; 
    friction=.4; 
} 

define { 
    name='bucket'; 
    model='active'; 
    mass=1; 
    shape='rect'; 
    width=60; 
    height=52; 
    texture=png('images/bucket.png'); 
    elastic=.5; 
    friction=.4; 
    oncontact = function(self, data) 
     if data.subject:type() == 'ball' then 
      local a = data.subject:angleTo(self:getxy()) 
      if a < 130 and a > 50 then 
       --update score etc.. 
      end 
     end 
    end; 
} 

nie zajęłoby to jako „jedyną prawdziwą drogę”, aby wdrożyć skryptów API. Jednym z uroków Lua jest to, że obsługuje wiele różnych stylów API. Właśnie to znalazłem działa dobrze dla gier, które tworzę - gry oparte na fizyce 2D.

+0

Dzięki, bardzo podoba mi się twoja odpowiedź. Używasz więc Lua głównie jako pliku konfiguracyjnego i repozytorium funkcji wywołania zwrotnego. A każdy obiekt gry jest zaimplementowany jako obiekt C++ i obiekt Lua. Czy to jest poprawne? Jak synchronizujesz ich stany? Jak zapisać grę - wygenerować nowy plik konfiguracyjny Lua? –

+0

Obiekty Lua są tak naprawdę tylko interfejsami, które odwzorowują obiekty w c za pomocą pojedynczego pola lightuserdata, które określa, czym jest "self". Jeśli chodzi o zapisywanie, generalnie zapisuję tylko poziom, na którym znajduje się gracz, ale mogę wprowadzić funkcję, która odtwarza cały stan gry w całości w Lua, po prostu pobierając stan każdego obiektu, a następnie wypisując skrypt, aby ustawić je wszystkie - być może nie bardzo zoptymalizowany i prawdopodobnie spojrzę na serializację w tym przypadku. –

1

zacząć od drobnych. Zezwól na dostęp do encji gry, aby móc wykonywać skrypty map/poziomów. Zachowanie spójne na różnych mapach/poziomach prawdopodobnie nie wymaga skryptowania.

Daj także dostęp do publicznego interfejsu Twoich obiektów.

+0

Dziękuję za pierwszą odpowiedź. Powiedzmy, czy dobrze jest zaimplementować wszystkie obiekty gry (npc, lokalizacje) jako tabele Lua bez obiektów C++? Czy lepiej jest je zwierciadlać? Albo coś innego? –

+0

Chciałbym zaimplementować obiekty gry w C++, ale stwórz je za pomocą Lua. Podczas wprowadzania można ustawić właściwości, które mają być dla danej sytuacji. Możesz również ustawić wywołania zwrotne do skryptów Lua, na przykład: jeśli drzwi 47 zostaną otwarte, wywołaj funkcję luki xyz. Zalecam używanie Lua do "historii" gry, C++ do mechaniki. – bitc

2

proponuję tę klasyfikację:

  1. Ekstremalne wariantowej: skrypty Lua kontrolować wszystko (gra logiczna, grafiki, AI itp.) Co więcej: skrypt działa jako program-host, jest właścicielem pętli gry. Niektóre silniki robią takie rzeczy. Ba-reklama: bez rozdzielania obowiązków i bez bezpieczeństwa skryptów.

  2. Skrypty Lua utrzymują logikę gier stanu i procesu gry. Prawdopodobnie wywoływane są skrypty w każdej iteracji pętli gry.

  3. Skrypty Lua są rzadko używane do inicjalizacji, konfiguracji, wywołań zwrotnych. Program hosta zapewnia (wiąże) bardzo minimalistyczny interfejs dla skryptów. Skrypty są zbudowane z tak dobrze zaprojektowanych i dostarczonych bloków.