2010-04-20 11 views
11

Por favor ayúdenos a clasificar las formas de organizar el código del juego C++/Lua y separar sus tareas. ¿Cuáles son las formas más convenientes, cuál usas?Lua y C++: separación de funciones

Por ejemplo, Lua se puede utilizar para inicializar objetos de C++ solo o en cada iteración de bucle de juego. También se puede utilizar para la lógica del juego o para gráficos. ¡Algunos motores de juego proporcionan un control total a todos los subsistemas desde los scripts! Realmente no me gusta este enfoque (no hay separación en absoluto).

¿Es una buena idea implementar todos los objetos del juego (npc, ubicaciones) como tablas Lua sin objetos C++? ¿O es mejor reflejarlos (tablas Lua para controlar objetos C++)? ¿O algo mas?

Gracias.

Editar. Mi clasificación: Lua and C++: separation of duties.

la continuación del tema: Lua, game state and game loop

Respuesta

4

Mi enfoque ha sido limitar lo que está expuesto a Lua tanto como sea posible. Nunca he encontrado la necesidad de una función "principal" u otra función que se invoque cada vez que se renderiza la escena (o más). Algunos motores Lua (como AMOR) hacen esto sin embargo. Prefiero definir objetos con funciones de devolución de llamada opcionales para eventos comunes a los que puede querer que responda el objeto, como colisión, clic del mouse, entrar o salir del mundo del juego, etc.

El resultado final es muy declarativo, casi un archivo de configuración para objetos. Tengo una función para crear clases o tipos de objetos y otra para crear objetos basados ​​en estos tipos. Los objetos tienen una colección de métodos a los que se puede llamar cuando responden a varios eventos. Todos estos métodos Lua se asignan a métodos C/C++ que a su vez modifican las propiedades privadas del objeto. He aquí un ejemplo de un objeto de cubo que puede capturar objetos de bolas:

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

yo no tomaría esto como el "verdadero camino" para poner en práctica su API de secuencias de comandos. Una de las bellezas de Lua es que admite muchos estilos diferentes de API. Esto es justo lo que he encontrado que funciona bien para los juegos que hago: juegos basados ​​en la física 2D.

+0

Gracias, me gusta mucho su respuesta. Entonces, usas Lua principalmente como archivo de configuración y repositorio de función de devolución de llamada. Y cada objeto del juego se implementa como objeto C++ y objeto Lua. ¿Es eso correcto? ¿Cómo sincronizas sus estados? ¿Cómo se guarda el juego? ¿Se genera un nuevo archivo de configuración de Lua? –

+0

Los objetos Lua son realmente solo interfaces que se asignan a objetos en c a través de un único campo lightuserdata que resuelve lo que es "self". En cuanto al ahorro, generalmente solo guardo el nivel en el que se encuentra un jugador, pero podría implementar una función que recrea el estado del juego completo en Lua simplemente obteniendo el estado de cada objeto y luego escribiendo un guión para establecerlos a todos, quizás no muy optimizado y probablemente miraría la serialización en este caso. –

1

inicio pequeña. Permita el acceso a las entidades del juego para que pueda realizar scripts de mapa/nivel específico. El comportamiento consistente en los mapas/niveles probablemente no necesite secuencias de comandos.

Además, solo dé acceso a la interfaz pública de sus objetos.

+0

Gracias por la primera respuesta. Diga, ¿es una buena idea implementar todos los objetos del juego (npc, ubicaciones) como tablas Lua sin objetos C++? ¿O es mejor reflejarlos? ¿O algo mas? –

+0

Implementaría los objetos del juego en C++, pero los crearía con Lua. Durante la instalación, puede establecer las propiedades según lo que le gustaría que fueran para la situación específica. También puede establecer devoluciones de llamadas a sus scripts Lua, por ejemplo: si door47 está abierto, llame a Lua-function xyz. Recomiendo que uses Lua para la "historia" del juego, C++ para la mecánica. – bitc

2

propongo esta clasificación:

  1. variante extrema: los scripts Lua controlan todo (la lógica del juego, gráficos, etc. AI). Aún más: el script funciona como un programa de host, posee un bucle de juego. Algunos motores hacen tal cosa. Lo Ba-Ad: no hay separación de tareas y no hay seguridad de script.

  2. Las secuencias de comandos Lua mantienen el estado del juego y procesan la lógica del juego. Probablemente se invocan scripts en cada iteración de bucle de juego.

  3. Los scripts de Lua rara vez se utilizan para inicializaciones, configuraciones y devoluciones de llamadas. Un programa host proporciona (vincula) una interfaz muy minimalista para los scripts. Por lo tanto, los scripts se crean a partir de bloques bien diseñados y proporcionados.