2010-04-20 9 views
11

Bitte helfen Sie bei der Klassifizierung von C++/Lua Spielcode und trennen Sie ihre Aufgaben. Was sind die bequemsten Wege, welche benutzt du?Lua und C++: Aufgabentrennung

Zum Beispiel kann Lua nur zum Initialisieren von C++ - Objekten oder bei jeder Spielschleifeniteration verwendet werden. Es kann nur für die Spiellogik oder für Grafiken verwendet werden. Einige Game-Engines bieten die volle Kontrolle über alle Subsysteme von Skripten! Ich mag diesen Ansatz wirklich nicht (keine Trennung).

Ist es eine gute Idee, alle Spielobjekte (NPC, Standorte) als Lua-Tabellen ohne C++ - Objekte zu implementieren? Oder es ist besser, sie zu spiegeln (Lua-Tabellen, um C++ - Objekte zu steuern)? Oder etwas anderes?

Vielen Dank.

Bearbeiten. Meine Klassifizierung: Lua and C++: separation of duties.

Themen Fortsetzung: Lua, game state and game loop

Antwort

4

Meine Herangehensweise war es, zu begrenzen, was mit Lua so viel wie möglich ausgesetzt ist. Ich habe nie eine Notwendigkeit für eine "Haupt" oder andere solche Funktion gefunden, die jedes Mal aufgerufen wird, wenn die Szene gerendert wird (oder mehr). Einige Lua-Engines (wie LOVE) tun dies jedoch. Ich bevorzuge es, Objekte mit optionalen Callback-Funktionen für häufige Ereignisse zu definieren, auf die das Objekt reagieren soll, wie etwa eine Kollision, ein Mausklick, das Betreten oder Verlassen der Spielwelt, etc.

Das Endergebnis ist sehr deklarativ, fast eine Konfigurationsdatei für Objekte. Ich habe eine Funktion zum Erstellen von Klassen oder Arten von Objekten und eine andere zum Erstellen von Objekten basierend auf diesen Typen. Die Objekte haben dann eine Sammlung von Methoden, die aufgerufen werden können, wenn auf verschiedene Ereignisse reagiert wird. Alle diese Lua-Methoden bilden C/C++ - Methoden ab, die wiederum die privaten Eigenschaften des Objekts modifizieren. Hier ist ein Beispiel eines Eimers Objekt, das Ball-Objekte erfassen können:

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; 
} 

Ich würde das nicht nehmen, wie die „einzig wahre Weg“ Ihr Skript-API zu implementieren. Eine der Schönheiten von Lua ist, dass es viele verschiedene Arten von API unterstützt. Dies ist genau das, was ich gefunden habe, funktioniert gut für die Spiele, die ich mache - 2D Physik basierte Spiele.

+0

Danke, ich mag deine Antwort sehr. Daher verwenden Sie Lua hauptsächlich als Konfigurationsdatei und Callback-Funktions-Repository. Und jedes Spielobjekt wird als C++ - Objekt und Lua-Objekt implementiert. Ist das korrekt? Wie synchronisieren Sie ihre Zustände? Wie speichern Sie das Spiel - generieren Sie eine neue Lua-Konfigurationsdatei? –

+0

Die Lua-Objekte sind wirklich nur Interfaces, die Objekte in c über ein einziges lightuserdata-Feld abbilden, welches das "self" auflöst. Was das Speichern angeht, speichere ich im Allgemeinen nur das Niveau, auf dem ein Spieler ist, aber ich könnte eine Funktion implementieren, die den gesamten Spielzustand komplett in Lua wieder herstellt, indem man einfach den Status jedes Objekts erhält und dann ein Skript schreibt, um alle zu setzen - vielleicht nicht sehr optimiert und ich würde in diesem Fall wahrscheinlich Serialisierung betrachten. –

1

Fangen Sie klein an. Erlaube den Zugriff auf Spiel-Entities, damit du Map/Level-spezifische Skripte erstellen kannst. Verhalten, das über Karten/Ebenen konsistent ist, benötigt wahrscheinlich kein Skripting.

Geben Sie auch nur Zugriff auf die öffentliche Schnittstelle Ihrer Objekte.

+0

Vielen Dank für die erste Antwort. Sag mal, ist es eine gute Idee, alle Spielobjekte (NPC, Locations) als Lua-Tabellen ohne C++ - Objekte zu implementieren? Oder ist es besser, sie zu spiegeln? Oder etwas anderes? –

+0

Ich würde die Spielobjekte in C++ implementieren, aber sie mit Lua instanziieren. Während der Installation können Sie die Eigenschaften so einstellen, wie Sie sie für die spezifische Situation haben möchten. Sie können auch Callbacks zu Ihren Lua-Skripten setzen, zum Beispiel: wenn door47 geöffnet ist, dann rufen Sie die Lua-Funktion xyz auf. Ich empfehle Lua für die "Geschichte" des Spiels, C++ für die Mechanik. – bitc

2

Ich schlage vor, diese Einstufung:

  1. Extreme Variante: Lua-Skripten alles (Spiellogik, Grafiken, AI etc.) steuern. Mehr noch: Das Skript funktioniert als Host-Programm, besitzt eine Spielschleife. Manche Motoren machen so etwas. Ba-Ad-Ding: keine Trennung der Aufgaben überhaupt und keine Skript-Sicherheit.

  2. Lua-Skripte behalten den Spielstatus bei und verarbeiten Spiellogik. Wahrscheinlich werden Skripte bei jeder Spielschleifeniteration aufgerufen.

  3. Lua-Skripte werden selten für Initialisierungen, Konfigurationen und Rückrufe verwendet. Ein Host-Programm liefert (bindet) eine sehr minimalistische Schnittstelle für die Skripte. So werden Skripte aus solchen gut gestalteten und bereitgestellten Blöcken erstellt.