Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Problemas con los combates xD

Iniciado por RobiHm, 15 de Abril de 2007, 09:19:54 PM

« anterior - próximo »

RobiHm

Saludos, soy nuevo en esto de programar para juegos y tengo problemas a la hora de programar el apartado gráfico de los combates.
Os explico:

Utilizo la librería dx_lib32 y el lenguaje de programación es vb6.

Creo un bucle central donde realizo las diferentes fases.

Interacción del Usuario.
Lógica.
Gráficos, Sonido y Texto.

Mi juego es un tablero, las unidades las mueves cada turno y realizan diferentes acciones. Una de ellas es luchar y curarse.

Cuando intento realizar un combate lo que quiero es detener el resto de procesos hasta que el combate finalice, pero como los gráficos van metidos al final del bucle y el combate se encuentra en lógica y tal, no puedo actualizar nada del mapa sin seguir con el resto de la lógica. No se si me he explicado con corrección.

Me gustaría detener todo hasta que termine de desarrollarse el combate.

Con los movimientos del usuarios por ahora creo que tengo la ligera idea de como solventar el problema de los combates, poniendo algunas variables que indiquen que solamente ejecute la animación del gráfico y nada más. Pero cuando mueve el ordenador(IA) no se me ocurre nada ya que no entra en el bucle principal para cada unidad, moviendo todas seguidas.

Ahora mismo estoy bastante confusndido de como hacerlo. Si alguien pudiese explicarme como se hace o me ofrece alguna ayudita le estaría muy agradecido xD

Gracias y disculpen las molestias
Web : Indómita
Blog : MiBlog
Evobas : Evobas
Kobox : Kobox

TrOnTxU

Hola, me parece que lo que tu necesitas es una maquina de estados.
No he entenido muy bien tu problema, pero creo que el problema es que no separas la lógica por estados. La forma más fácil (rápida de programarlo) es con una variable, no recuerdo muchas cosas de BASIC asi que lo escribiré en una especie pseudo-código:

definir { E_SALIR = 0, E_MUEVE_PLAYER = 1, E_ANIMACION = 2, E_COMBATE = 3, ...}
declarar varible estado = E_MUEVE_PLAYER // por ejemplo
// Bucle principal
mientras(estado <> E_SALIR) {
 // Input
 si estado == E_MUEVE_PLAYER entonces
   // Procesar código de entrada
   ....
 final si

 // Logica
 si estado == E_ANIMACION entonces
   // Ejecuta el código de animacion
   ...
   si animacion concluye entonces
     estado = E_... // el estado al que quieras cambiar
   final si
   ...
 sino si estado == E_MUEVE_PLAYER entonces
 ...
 sino si estado == E_COMBATE entonces
 ...
 final si
 // Comprobar final del juego
 si juego acaba entonces
   estado = E_SALIR
 final si

 // Dibujar
 ...
}


En el trozo de dibujar tambien puedes poner sentencias condicionales para seleccionar que dibujar en cada estado del juego.

Espero que esa sea tu pregunta y que hayas entendido el concepto.
Sino he sabido contestarte bien o no te queda algo claro dimelo e intentaré echarte una mano.

Un saludo
Vicent: Linked-In  ***  ¡¡Ya tengo blog!!

RobiHm

Ante todo gracias por la ayuda

Mi problema radica en que la cpu cuando se mueve, llama a un procedimiento que mueve a todas sus unidades en un bucle, ésto se encuentra en la llamada de la lógica principal

si en ese bucle una unidad se pone a combatir o a curarse, no puedo mostrar su animación porque el bucle pasa a la siguiente unidad, que por orden se encuentra antes que la muestra de gráficos

Con lo que tu has comentado me solvento el problema de los movimientos del jugador, que era lo que tenía pensado, pero los de la cpu siguen igual xD

alguna otra idea?
Web : Indómita
Blog : MiBlog
Evobas : Evobas
Kobox : Kobox

TrOnTxU

No sé si te he entendido bien, porque mi respuesta sigue siendo la misma: estados.

Cuando la CPU tenga que mover pasarás al estado E_MUEVE_CPU (por ejemplo) y pones un contador de enemigos actualizados a 0 (una variable). En tu trozo de código de lógica (en el procedimiento o donde lo tengas hecho) actualizas la acción de un enemigo, incrementas la variable de contador y continuas (ejecutas la parte de dibujado y das otra vuelta al bucle principal).
Asegurate de que a la salida de tu bucle se compruebe si has actualizado todos los enemigos, si es asi cambia de nuevo de estado al correspondiente.
En caso de que el cambio de estado provocara (eso es como tu te organices el código, pero por si acaso) que la animación del ultimo enemigo actualizado no se realizara, tendrias que hacer la comprobación antes del procedimiento de lógica, asi evitarias este problema, pero no tiene porque ser un problema si controlas correctamente los estado en todas las partes del código (logica, input y render) que lo necesiten.

Si este no es el problema, por favor, intenta explicarte un poco mejor, ya que no lo pillo.

Un saludo.
Vicent: Linked-In  ***  ¡¡Ya tengo blog!!

blau

Esta claro que necesitas una maquina de estados.


Pero lo que tienes que plantearte es que la animacion no se puede hacer de un tiron. Debes dividirla de forma que cada ciclo del bucle se ejecute una parte de la animacion.

Pongamos que se va a iniciar un ataque:

1.- La logica detecta un ataque y cambia el estado de 'estatico' a 'atacando' y el contador de la animacion a 0

2.- La parte de renderizado chequea todos los estados de lo bichos que tengas, si alguno esta atacando muestra el bicho segun el contador de el contador de la animacion, e incrementa este contador en una unidad.

Aqui te hago un inciso sobre los frames por segundo, aqui quizas no deberias incrementar el contador hasta que pase un determinado tiempo para poder controlar la velocidad de la animacion. Puedes hacerlo mediante un bucle de espera, o simplemente incrementando el contador en funcion del tiempo.

3. La logica ve que el bicho esta atacando, y comprueba si ha llegado a un determinado estado de la animacion, en el cual aparece alguna particula para simular el disparo o la unidad atacada debe defenderse o iniciar una animacion para recibir el ataque. En cualquier caso se cambiaria el estado oportuno y ya esta.

4. La parte de render visualizaria otra vez cada bicho o particula en su estado correspondiente.

Espero que te sirva de algo, ¡¡¡ Divide y venceras !!!

;)

RobiHm

Muchas gracias a ambos por las respuestas, voy a reestructurar todo el tinglao buf... xD

Veamos que sale xD

Gracias
Web : Indómita
Blog : MiBlog
Evobas : Evobas
Kobox : Kobox

[EX3]

Cita de: ""RobiHm"Cuando intento realizar un combate lo que quiero es detener el resto de procesos hasta que el combate finalice, pero como los gráficos van metidos al final del bucle y el combate se encuentra en lógica y tal, no puedo actualizar nada del mapa sin seguir con el resto de la lógica. No se si me he explicado con corrección.

Me gustaría detener todo hasta que termine de desarrollarse el combate.

Con los movimientos del usuarios por ahora creo que tengo la ligera idea de como solventar el problema de los combates, poniendo algunas variables que indiquen que solamente ejecute la animación del gráfico y nada más. Pero cuando mueve el ordenador(IA) no se me ocurre nada ya que no entra en el bucle principal para cada unidad, moviendo todas seguidas.
Si separas correctamente la logica de lo grafico no deberias tener problema. Piensa que lo unico que gestionas realmente es la logica, que es quien define el comportamiento del objeto y donde se define la animacion y fotograma a dibujar. La parte de dibujo siempre es la misma, dibujar y punto. Solo no se deberia dibujar si el objeto no existe como tal (te hablo orientando el tema un poco a clases y una ligera orientacion a objetos). Si leistes el codigo del minimatamarcianos sin terminar que hice con la dx_lib32 lo veras mas claro. Alli los objetos o entidades dividian sus funciones en dos llamadas, un metodo Update() donde se gestiona toda la logica del objeto, la verdadera miga de la entidad, y otro metodo, Draw(), donde siempre se hace las mismas llamadas para dibujar y estas varian su resultado acorde a una variable que se gestiona en Update():
Clase Enemigo
   Dim ... *** Miembros privados de la clase (variables para indicar fotograma a dibujar por ejemplo) ***
   Property Get/Let ... *** Miembros publicos o propiedades de la clase ***
   Sub Class_Initialize()
       *** Constructor de la clase. Codigo que se ejecutara al crear una instancia de este objeto ***
   End Sub
   Sub Class_Terminate()
       *** Destructor de la clase. Codigo que se ejecutara al destruir una instancia de este objeto ***
   Sub Update()
       *** Gestionamos toda la logica ***
   End Sub
   Sub Draw()
       *** Dibujamos el/los grafico/s del objeto ***
   End Sub

Luego, llevando una jerarquia limpia y clara mediante clases, separando de esta forma la logica de la parte grafica en cada objeto de tu programa y a rasgos generales en el programa, te queda un codigo asi de comodo en el bucle principal:
Do While <condicion>
   Juego.Update() *** Metodo que gestiona la logica de todos los objetos del juego ***
   Juego.Draw() *** Metodo que gestiona el dibujo de todos los objetos ***
Loop

Donde el Update() general podria ser algo similar a esto:
Clase Juego
*** Listas o colecciones de entidades: ***
Enemigos[]
Items[]
Tiles[]
...

Sub Update()
   Dim var As Object *** El tipo Object en VB 6.0 puede apuntar o hacer referencia como tipo de dato de un modulo clase.
   ' Ejecutamos la logica de los enemigos:
   For Each var In Enemigos
       var.Update()
   Next var
   ' Ejecutamos la logica de los items:
   For Each var In Items
       var.Update()
   Next var
   ...
End Sub

Y lo mismo para dibujar:
Sub Draw()
   Dim var As Object
   ' Dibujamos los enemigos:
   For Each var In Enemigos
       var.Draw()
   Next var
   ' Dibujamos los items:
   For Each var In Items
       var.Draw()
   Next var
   ...

   Graphics.Frame(0, 60) *** Llamada a la funcion de presentacion en pantalla de la clase grafica de dx_lib32 ***
End Sub

Un ejemplo o pseudocodigo muy muy basico de una maquina de estados (quizas alguien pueda ilustrate un ejemplo mejor o mas claro :P):
Select Case Estado
   Case Vigilar
       *** Ejecutar comportamiento de vigilancia del enemigo ***
       *** Actualizamos el indice del fotograma a dibujar de la secuencia de animacion de vigilar ***
       *** Comprobamos existencia del jugador en nuestra cercania ***
   Case Atacar
       *** Ejecutar comportamiento de atacar ***
       *** Actualizamos el indice del fotograma a dibujar de la secuencia de disparar ***
       *** Evaluamos situacion o comprobamos si hemos matado al jugador ***
   Case Muerte
       *** Actualizamos el indice del fotograma a dibujar de la secuencia de animacion de morir ***
       *** Cambiamos su estado a muerto ***
   Case Muerto
       *** Simplemente dibujamos el fotograma de enemigo abatido ***
   Case ... *** Demas estados que tengas definido ***
End Select

De esta forma, y gestionando una maquina de estados como te han comentado (algo como el ejemplo de arriba), no deberias tener problema a la hora implementar tanto la parte logica como la parte grafica.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

TrOnTxU

Juer, cuando yo pregunto nadie contesta tanto :P
Vicent: Linked-In  ***  ¡¡Ya tengo blog!!

RobiHm

Cita de: "TrOnTxU"Juer, cuando yo pregunto nadie contesta tanto :P

Es que estoy utilizando su librería xDDDD

asias [EX3] xD

ya tengo terminada gran parte del tema de estados xD

me mire el juego del matamarcianos pero es que no tiene nada que ver con un juego por turnos en el que la lógica de la IA no se mueve a la vez que las acciones que tu realizas, de ahí el tener tantos problemas a la hora de cambiar de estado o detener las acciones del resto de participantes xD
si hubiese sido otro estilo de juego si lo habría estructurado de ese modo xD

lo dicho muchisimas gracias a todos por la ayuda xD

haber si logro terminar el jueguecillo y se lo muestro (será la nueva referencia de dx_lib32, al menos en el apartado de como no programar un juego con dx_lib32 xD)
Web : Indómita
Blog : MiBlog
Evobas : Evobas
Kobox : Kobox

[EX3]

Cita de: "RobiHm"Es que estoy utilizando su librería xDDDD
Nada de exclusividades, que esto que escribi se puede aplicar a cualquier implementacion, motor, libreria o lenguaje :P Simple casualidad, nada mas :lol:

Cita de: "RobiHm"me mire el juego del matamarcianos pero es que no tiene nada que ver con un juego por turnos en el que la lógica de la IA no se mueve a la vez que las acciones que tu realizas
La idea de que te lo miraras era para que vieras una forma clara de separar la logica de la parte de dibujo en las entidades (que al fin y al cabo es la misma que se usa en XNA, de donde baso mi implementacion)

Salu2...

P.D.: Creo que en foro de IA habia unos articulos sobre maquinas de estados. Echa un vistazo a ver si los ves.
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt






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.