2010-04-20 16 views
11

Si prega di aiutare a classificare i modi di organizzare il codice di gioco C++/Lua e di separare i loro compiti. Quali sono i modi più convenienti, quale usi?Lua e C++: separazione dei compiti

Ad esempio, Lua può essere utilizzato per inizializzare solo oggetti C++ o ad ogni iterazione del ciclo di gioco. Può essere utilizzato solo per la logica di gioco o per la grafica. Alcuni motori di gioco offrono il controllo completo di tutti i sottosistemi dagli script! Non mi piace davvero questo approccio (nessuna separazione).

È una buona idea implementare tutti gli oggetti di gioco (npc, posizioni) come tabelle Lua senza oggetti C++? O è meglio specchiarli (tabelle Lua per controllare oggetti C++)? O qualcos'altro?

Grazie.

Modifica. La mia classificazione: Lua and C++: separation of duties.

continuazione del Topic: Lua, game state and game loop

risposta

4

Il mio approccio è stato quello di limitare quanto esposto a Lua il più possibile. Non ho mai trovato la necessità di una funzione "principale" o altra funzione che viene chiamata ogni volta che la scena viene renderizzata (o più). Alcuni motori Lua (come LOVE) lo fanno comunque. Preferisco definire gli oggetti con funzioni di callback opzionali per eventi comuni a cui l'oggetto può rispondere come collisione, clic del mouse, entrare o uscire dal mondo di gioco, ecc.

Il risultato finale è molto dichiarativo, quasi un file di configurazione per oggetti. Ho una funzione per creare classi o tipi di oggetti e un'altra per creare oggetti basati su questi tipi. Gli oggetti hanno quindi una collezione di metodi che possono essere chiamati quando si risponde a vari eventi. Tutti questi metodi Lua si associano ai metodi C/C++ che a loro volta modificano le proprietà private dell'oggetto. Ecco un esempio di un oggetto secchio che può catturare oggetti a sfera:

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

non vorrei prendere questo come "un vero modo" per implementare l'API di scripting. Una delle bellezze di Lua è che supporta molti diversi stili di API. Questo è proprio quello che ho trovato funziona bene per i giochi che faccio - giochi basati sulla fisica 2D.

+0

Grazie, la tua risposta mi piace molto. Quindi, tu usi Lua principalmente come file di configurazione e repository di funzioni di callback. E ogni oggetto di gioco è implementato come oggetto C++ e oggetto Lua. È corretto? Come sincronizzi i loro stati? Come si salva il gioco? Generare un nuovo file di configurazione Lua? –

+0

Gli oggetti Lua sono in realtà solo interfacce che si associano agli oggetti in c attraverso un singolo campo lightuserdata che risolve il "sé". Per quanto riguarda il salvataggio, in genere, salvo solo il livello di un giocatore, ma posso implementare una funzione che ricrea l'intero stato del gioco interamente in Lua semplicemente ottenendo lo stato di ogni oggetto e quindi scrivendo uno script per impostarli tutti - forse no molto ottimizzato e probabilmente guarderei la serializzazione in questo caso. –

1

avviare piccole. Consentire l'accesso alle entità di gioco in modo da poter eseguire script mappa/livello specifico. Probabilmente il comportamento coerente su mappe/livelli non ha bisogno di script.

Inoltre, concedere l'accesso all'interfaccia pubblica dei propri oggetti.

+0

Grazie per la prima risposta. Supponiamo, è una buona idea implementare tutti gli oggetti di gioco (npc, posizioni) come tabelle Lua senza oggetti C++? O è meglio rispecchiarli? O qualcos'altro? –

+0

Implementerei gli oggetti di gioco in C++, ma li istanziamo con Lua. Durante l'instatiazione puoi impostare le proprietà su ciò che vorresti fosse per la situazione specifica. È inoltre possibile impostare i callback ai propri script Lua, ad esempio: se viene aperta door47, chiamare la funzione Lua xyz. Vi raccomando di usare Lua per la "storia" del gioco, C++ per i meccanici. – bitc

2

propongo questa classificazione:

  1. variante estrema: gli script Lua controllano tutto (logica di gioco, grafica, intelligenza artificiale, ecc). Ancora di più: lo script funziona come un programma host, possiede un loop di gioco. Alcuni motori fanno una cosa del genere. Cosa Ba-Ad: nessuna separazione dei doveri e nessuna sicurezza di script.

  2. Gli script Lua mantengono lo stato del gioco e la logica di processo. Probabilmente gli script vengono chiamati ad ogni iterazione del ciclo di gioco.

  3. Gli script Lua vengono utilizzati raramente per inizializzazioni, configurazioni, callback. Un programma host fornisce (collega) un'interfaccia molto minimalista per gli script. Quindi gli script sono costruiti con blocchi ben progettati e forniti.