Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Paradigmas De Preogramacion De Juegos

Iniciado por Pogacha, 06 de Julio de 2005, 03:05:53 PM

« anterior - próximo »

sés

 El sistema que utilizo creo que es prácticamente idéntico al de senior wapo... si no lo entendí mal.

Yo utilizo varios módulos (menú, juego...), cada uno con sus propios estados, pudiendo cambiar el estado de los demás módulos.

Ej.: Mientras se juega se pulsa ESC. El módulo de juego activa la opción de continuar en el menú y cambia al menú.
Soy indeciso... ¿o no?

tiutiu

 Pero si es que el sistema de estados no esta reñido con la disponibilidad de modulos en cada estado. Un estado simplemente es una abstraccion de tu metodo.
Si que te da mas flexibilidad tener cada modulo con su propio conjunto de estados, pero tampoco te creas que tanta (flexibilidad practica, la teorica no me sirve puesto que solo añade complejidad al final ;) ). En cambio, si quieres poder ver el menu mientras estas cargando solo tienes que habilitarlo en el susodicho estado y ya esta.

La maquina de estados 'global' por asi decirlo es un wrapper que representa un comportamiento del engine en un momento dado. Tienes una vision mas general de lo que esta pasando y no tienes que preocuparte de la maquina de estados interna de cada modulo. Reducir la complejidad, amigo!

Con respecto al sistema de eventos, tambien es independiente del estado de la aplicacion. Puedes mandar mensajes y eventos aunque solo tengas un unico estado.


PD: por supuesto que para gustos colores y todo eso...

b>:: Pandora's Box project ::
Notas e ideas sobre desarrollo de engines para juegos

Pogacha

 Por supuesto ...

Uno tiene cosas en paralelo, pero a su vez el desarrollo de un juego implica el uso de diferentes estados del juego, por ejemplo el momento en que te dice "ready", cuando te dice "game over", el momento en que pasas de nivel y recuenta los objetivos ...
Pasa tambien que uno por ahí tiene diferentes graficos de interface, por ejemplo un renderer, un movie player, y un inventario o mapa del lugar, que en definitiva tienen diferentes respuestas a la interface humana tambien, y generalmente diferentes metodos de interacción o sea que no se parecen en nada y como el motor debe estar dando vueltas en un gran loop, mas si es un servidor o algo por el estilo no tiene sentido crear 5 game loops los cuales dependeran del sistema operativo.
La complicación aumenta si por ejemplo el juego se desarrolla al estilo flashback, estas caminando por ahí se hace un gran push y te muestra una cinematica y luego pop y el juego sigue donde estaba ... y a su vez, la cinematica pude desencadenar un "grabar juego?" en otra pantalla o no ... entonces hay que tener una pila con los estados, y ya entonces los estados los hago una clase donde guarden su información propia, y ya entonces los hago auto-updatables y meto todo el codigo en una virtual y dejo la forma del motor muy ligera de codigo.
Yo todavia no lo pruebo, pero lo veo mucho mas claro.

class ObjetoActualizable
{
 protected:
    ObjetoActualizable *Anterior, *Siguiente;
    friend class PilaDeObjetosActualizables;
    friend class ColeccionDeObjetosActualizables;
 public:
    virtual Actualizar(float delta_tiempo);
    virtual ~ObjetoActualizable();
};


Y esta seria la estructura basica de todo lo dinamico de mi juego actual, aun así no me animo a cambiarlo por ahora, pero no se ... tengo una pila para las cinematicas y demas pero no son muy enredadas así no tiene sentido por ahora.

Saludos.






Lord Trancos 2

 Mi "interface". (Realmente es una clase normal, y tiene algo de codigo para manejar el stack de subestados)


const
 C_SUBSTATES_MAX_STACK_DEPTH = 32;

type
 TStateInterface = class
 private
   // used for sub-states
   FSubState_Stack    : array[0..C_SUBSTATES_MAX_STACK_DEPTH-1] of longint;
   FSubState_StackPos : longint;
   // -------------------
 public
   // used for sub-states
   FSubState_Current : longint;
   function SubState_Push(_state: longint): boolean;
   function SubState_Pop: longint;
   function SubState_PopCurrent: boolean;
   // -------------------

   procedure Init(); virtual; abstract;              // initialization (app init)
   procedure Shutdown(); virtual; abstract;          // finalization (app exit)
   procedure InitAfterOGL(); virtual; abstract;      // initialization (after SDL/OGL init)
   procedure ShutdownBeforeOGL(); virtual; abstract; // finalization (before SDL/OGL exit)
   procedure Activate(); virtual; abstract;          // called when activated
   procedure DeActivate(); virtual; abstract;        // called when deactivated
   procedure Render(var _cancel: boolean); virtual; abstract;               // draw
   procedure ProcessInput(_lastFrameTime: cardinal); virtual; abstract; // process user input
   procedure Run(_lastFrameTime: cardinal); virtual; abstract;          // other processing

   constructor Create();
 end;


El loop de mi engine:


procedure SS2_MainLoop;

var
 _elapsed : cardinal;

begin
 g_LastTickCount := SDL_GetTicks;
 g_ExitNow := false;
 repeat
   // we need a current sub-state
   if (g_StateCurrent.FSubState_Current >= 0) then
   begin
     RenderCurrentFrame;                    // render
     _elapsed := fps_TimeElapsed;           // get last frame time
     g_LastTickCount := SDL_GetTicks;       // get current time
     g_StateCurrent.ProcessInput(_elapsed); // process input (and system events)
     g_StateCurrent.Run(_elapsed);          // run
   end else
   begin
     // get new state from stack
     // if we can't; exit from game
     if not g_StateCurrent.SubState_PopCurrent then
     begin
        LogWriteLn('WARNING: No more substates for current state!');
        g_ExitNow := true;
     end;
   end;
 until (g_ExitNow);
end;


La funcion RenderCurrentFrame ya se encarga de renderizar el estado actual (g_StateCurrent.Render), solo que tambien tiene en cuenta otas cosas para realizar algun q otro efecto de "postproduccion".

Cuando termino un subestado simplemente pongo g_StateCurrent.FSubState_Current = -1 y el solito ya pilla el siguiente subestado del stack.

Para cambiar de estado, basta asignarlo:  g_StateCurrent := g_StateMainMenu;
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
Gate to Avalon (mi Blog)






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.