Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: ALRAZ en 03 de Octubre de 2004, 11:20:38 PM

Título: Detección De "comandos"
Publicado por: ALRAZ en 03 de Octubre de 2004, 11:20:38 PM
 Alo de nuevo  :lol:


Pregunta ALRAZiana:
Alguien me podría dar alguna guía sobre como se hace eso de captar comandos al estilo de los juegos de lucha?

Ya saben el clásico Street Fighter:
"Abajo, abajo-adelante, Adelante + Botón" = Movimiento especial...

La cosa es... Como sé cuando el usuario ha marcado la secuencia anterior..?

Estoy usando SDL para obtener las entradas, aunque creo que eso es lo de menos, ya que las entradas se pueden convertir a cualquer otra cosa
Título: Detección De "comandos"
Publicado por: Lessman en 03 de Octubre de 2004, 11:47:15 PM
...
Título: Detección De "comandos"
Publicado por: ALRAZ en 03 de Octubre de 2004, 11:51:18 PM
Cita de: "Lessman"Intenta probar con una maquina de estados finita, para interpretar la entrada del usuario.
:huh:

Estem......  :blink:


Qué ser Máquina de Estados Finita?  :(  
Título: Detección De "comandos"
Publicado por: Zaelsius en 04 de Octubre de 2004, 12:07:07 AM
 http://en.wikipedia.org/wiki/Finite_state_machine y http://en.wikipedia.org/wiki/DFA.

En un juego de lucha, el lenguaje a reconocer sería el conjunto de posibles combinaciones de teclas que resultan en un movimiento o ataque. Tendrias que programar/diseñar un autómata para cada combinación que quieras reconocer.
Eso es más o menos lo que habría que hacer, aunque hay más detalles de implementación claro..

Seguramente encuentres mejores explicaciones y tutoriales buscando sobre autómatas de estados finitos aplicados a juegos(busca en los artículos de GameDev.Net por ejemplo).

Con éste método, podrías definir los movimientos en un fichero de texto y crear los autómatas a partir de esta descripción.

Tambien puedes optar por soluciones "caseras" menos rigurosas, pero en el fondo estarás implementando lo anterior, sólo que de mala manera.

Edit: Esta es otra de esas cosas que enseñan en 1º o 2º curso de carrera y que segun algunos no sirve para nada(no me refiero a gente del foro)  :rolleyes:  
Título: Detección De "comandos"
Publicado por: ALRAZ en 04 de Octubre de 2004, 12:18:59 AM
Cita de: "ZaelSiuS"Edit: Esta es otra de esas cosas que enseñan en 1º o 2º curso de carrera y que segun algunos no sirve para nada(no me refiero a gente del foro)  :rolleyes:
O_O

Nunca nos enseñaron tal cosa :angry:
Al menos en los primeros cursos.

Aunque para la cochinada de escuela en la que estoy, no me extraña para nada  <_<

por cierto, gracias por los links  :D  
Título: Detección De "comandos"
Publicado por: Thenend en 04 de Octubre de 2004, 02:08:31 AM
 mmm, yo hice eso para un juego de peleas en div hace unos años, pero he perdido el código (y el juego). Por lo que recuerdo, almacenaba las entradas en una lista junto con el tiempo en el que se habían producido. Cuando había pasado demasiado tiempo desde la pulsacion de una tecla, borraba la lista.

Para reconocer la secuencia usaba la fuerza bruta (comparando con todas las posibles secuencias de movimientos). Sí que es verdad que un autómata es perfecto para esa misión, pero dado que no suele haber más de 6 u 8 movimientos especiales, cualquier código capaz de reconocer la secuencia te puede valer (aunque seguramente llegarás de forma intuitiva a algo parecido a un autómata).

De cualquier modo, estudiate bien los autómatas porque en los juegos en general son muy útiles pero es que en los de lucha son imprescindibles. A poco complejo que lo hagas acabarás con toda una señora máquina de estados.
Título: Detección De "comandos"
Publicado por: Abc7 en 04 de Octubre de 2004, 02:09:07 AM
 mmm.. yo lo q haria seria guardar un array d ints para cada movimiento, y cada valor del array seria un movimiento (SDLK_UP, SDLK_t, etc) y desde el ultimo SDL_KEYUP se activa un timer q indica cuanto tiempo tiene el usuario para hacer otro movimiento hasta q se considere q es otro, y no parte del combo.
entonces cuando se termina el movimiento, chekeo los arrays a ver si alguno coincide con el array d movimientos q hizo el usuario, y si alguno coincide llama a la funcion o lo q sea q se encargue d hacer ese combo =)
pero cmo dijeron, es una mala solucion.. quizas otro t d una mejor
Título: Detección De "comandos"
Publicado por: ALRAZ en 04 de Octubre de 2004, 03:26:40 AM
 (uoh)
XD

Me van a creer que eso de los autómatas es casi exactamente lo que estoy usando para los estados de los personajes
(Que no es un juego de lucha sino de Scroll 2D, pero pienso incluir algo de comandos  :P )

Soy tan bruto (rules)


Se me ha ocurrido hacer algo parecido a lo de los Arrays, pero con árboles, donde cada hijo de un  árbol es la tecla/botón que se debe presionar después de haber presionado la tecla/botón del nodo padre.
Ejemplifico:


                            Abajo
                       /                \
Abajo-Izquierda                   Abajo-Derecha
         |                                   /                  \    
    Izquierda                      Derecha         Abajo
         |                                  |                        |
     Patada                         Puño                  Puño
         |                                  |                         |
(Eh! Esto es un             (Joer! esto es          (Ah caray! Aquí
comando)                      OTRO comando)        tenemos un comando más!)


Seguro no es el árbol más xulo que hayan visto :P

Todavía no termina de convencerme la idea...
Opiniones?
Título: Detección De "comandos"
Publicado por: [EX3] en 04 de Octubre de 2004, 05:19:49 AM
 A mi me convence mas lo de guardar una lista con las teclas pulsadas y realizar la comparacion. Lo veo mas sencillo.

Yo por ejemplo iria concatenando los valores en una sola variable en vez de crear una lista o array y luego solo haria una sencilla comprobacion entre dos valores mediante un Select Case, la variable y una constante por ejemplo, lo veo mas sencillo y "algo" mas optimizado en cuanto a memoria se refiere (Variable < Array)

Salu2...
Título: Detección De "comandos"
Publicado por: ALRAZ en 04 de Octubre de 2004, 06:38:07 AM
Cita de: "[EX3"] A mi me convence mas lo de guardar una lista con las teclas pulsadas y realizar la comparacion. Lo veo mas sencillo.

Yo por ejemplo iria concatenando los valores en una sola variable en vez de crear una lista o array y luego solo haria una sencilla comprobacion entre dos valores mediante un Select Case, la variable y una constante por ejemplo, lo veo mas sencillo y "algo" mas optimizado en cuanto a memoria se refiere (Variable < Array)

Salu2...
O_O

Interesante proposición...
Título: Detección De "comandos"
Publicado por: sés en 04 de Octubre de 2004, 09:25:10 AM
 Te cuento cómo lo tenía hecho yo:

Cada jugador tiene unas teclas, a las que asigno un valor (bit):
Direcciones
IZQ=0x01
DER=0x02
ARR=0x04
ABA=0x08

Puños
P1=0x10
P2=0x20

Patadas
K1=0x40
K2=0x80

Así puedes guardar en un byte (si tienes más botones usa short o int) el estado de las teclas del jugador (IZQ | P1 | P2).

Implementé una lista (una por jugador, claro) como la que ya han comentado, en la que voy introduciendo los estados de las teclas.
En esta lista hacía varias operaciónes según lo que ocurriera:
- Si el estado cambia no hago nada. Yo no lo necesitaba, pero podrías guardar el tiempo que se mantiene el estado para el típico movimiento en el que tienes que cargar en una dirección.
- Si el estado cambia, lo añado a la lista, eliminando el más viejo si la lista estaba llena.
- Cada X tiempo (1s ó así) elimino la lista completa.

Para ver si se había ejecutado algún movimiento especial me hice una especie de "memcmp" que comparaba el contenido de la lista con los movimientos posibles del jugador, añadiendo algo de tolerancia para las diagonales.

Lo de las tolerancias es porque, si has jugado a estos juegos, sabrás que al hacer los movimientos tienes cierta libertad:

Típico "Dragon Punch" = F, D, DF + P
Todos sabemos que si haces algo del tipo: F, DF, D, DF + P funciona igual
También se traga: F, D, DF, P y F, DF, D, DF, P

Vamos que si haces una máquina de estado te tocará poner bastantes estados, a no ser que quieras que el jugador tenga que hacer los movimientos EXACTAMENTE como tú digas... y que se cansen a los 2 minutos porque no les sale nada :P

Tengo la implementación por ahí, esperando a que me ponga a hacer mi motor de juegos de lucha que tengo aparcado... aunque casi hecho -.-
Título: Detección De "comandos"
Publicado por: Malandrin en 04 de Octubre de 2004, 09:36:58 AM
 Hola, hace un tiempecillo estaba con un juego de lucha, y yo lo hacía así:

- Definía en un archivo las posibles combinaciones del personaje. Ej:
 IZQUIERDA, ABAJO, ADELANTE, PUÑO_FUERTE -> ACCION
 DERECHA_ABAJO_IZQUIERDA_PATADA_DEBIL -> ACCION

- Un vez en el juego, tenía un array estático del tamaño de número de teclas que desencadenaban una acción (en el ejemplo PUÑO_FUERTE y PATADA_DEBIL),  luego iba parseando estas combinaciones y creando un arbol 'al revés', algo así:

 [PUÑO_FUERTE][PATADA_DEBIL] --> array estático
          /                         \
         /                           \
 [ADELANTE]           [IZQUIERDA]
       |                             |
 [ABAJO]                 [ABAJO]
      |                               |
 [IZQUIERDA]         [DERECHA]
     |                               |
 (ACCION)               (ACCION)

Y así con el resto de acciones posibles.

- A la hora de detectar estos movimientos: cada pulsación de tecla la iba almacenando en un array, el array se iba 'autoactualizando', vamos, que si durante n ticks no se detectaba pulsación, se pasaba a la siguiente posición del array marcando esa casilla como vacía, y si se pulsaba la misma tecla, se iba actualizando un contador en esa posición del array con el número de ticks pulsados. Cuando detectaba que era una tecla desencadenante de acción, comenzaba a recorrer el arbol de esa tecla a partir del array de entrada de pulsaciones, hasta que encontrara la acción o no.  Un caso particular eran las acciones contenidas en acciones, p.e. ABAJO,DERECHA,PUÑO y IZQUIERDA,ABAJO,DERECHA,PUÑO, que si hago la combinación larga por este método pillaría la corta, para solucionar esto, al encontrar una acción la guardo y sigo mirando el árbol, si encuentro otra pues me quedo con esa  y si no, con la anterior.

Y basicamente era eso :) Un saludo.
Título: Detección De "comandos"
Publicado por: ALRAZ en 04 de Octubre de 2004, 10:07:54 AM
 Wowowowowooooo  (uoh)
Esto se pone cada vez más interesante...

a ver si estoy entendiendo:

Malandrín:

El arreglo lo recorrías a partir de la posición final del movimiento?
 Es decir, si el movimiento termina en Puño, cuando el usuario presionaba Puño,
inmediatamente recorrías buscando en:
1)Las teclas/botones que había presionado el jugador ANTES de presionar Puño
2)tus arreglo de Posibles movimientos de modo que concordaran con lo anterior
Y comparabas que ambas fueran iguales o más o menos iguales
Estoy entendiendo?


sés:

Lo de los "grados de libertad" con las diagonales...
como se implementaría?

He visto que en algunos juegos (como Marvel Vs Capcom 2) esta "característica"
se puede explotar hasta extremos insospechados  :)  
Título: Detección De "comandos"
Publicado por: Malandrin en 04 de Octubre de 2004, 10:40:24 AM
 
CitarEl arreglo lo recorrías a partir de la posición final del movimiento?
Es decir, si el movimiento termina en Puño, cuando el usuario presionaba Puño,
inmediatamente recorrías buscando en:
1)Las teclas/botones que había presionado el jugador ANTES de presionar Puño
2)tus arreglo de Posibles movimientos de modo que concordaran con lo anterior
Y comparabas que ambas fueran iguales o más o menos iguales
Estoy entendiendo?

1) Efectivamente, si el array contiene [ATRAS][VACIO][ADELANTE][ATRAS][ABAJO][ADELANTE][PUÑO], cuando detecto el puño, entro en su árbol y busco el nodo de la tecla 'Adelante', si hay, me metó en él y busco el nodo de la tecla 'Abajo', y así sucesivamente, hasta que encuentre una acción, o un nodo que no lleve a ningún lado.

2) Realmente no hago ninguna comparación, simplemente voy recorriendo el árbol de acciones, en el que puedo llegar a un nodo hoja que será el que tenga la acción definida -p.e. un aduken-, o puedo llegar a un nodo en el que con la tecla del array de pulsaciones no me lleve a ningún lado.


       [PUÑO]
           |
    [ADELANTE]


En este ejemplo, si pulso puño, entraré en el array de puño y miraré la anterior tecla del array de pulsaciones, si es un 'Adelante', veo que existe ese nodo y que al ser hoja realiza una acción, (cada nodo hoja tiene información de la acción que realiza), si en vez de adelante, el array de pulsaciones tiene un 'Atrás', veo que desde 'Puño' no llego a ningún nodo 'Atrás', por lo tanto no hago nada.
Título: Detección De "comandos"
Publicado por: sés en 04 de Octubre de 2004, 10:40:34 AM
 Pues no me aceurdo bien. Si tengo un rato (y me acuerdo) busco el código, a ver si es legible.

Por cierto, lo de la tecla desencadenante de un movimiento no me convence. ¿IZQUIERDA no desencadena un movimiento? ¿Solo son movimientos si terminan con un disparo?
No olvidemos que F,F es un movimiento (salto alante o correr), D, U es otro (salto largo), etc.

Yo considero movimientos básicos: B, F, D, U, P1, P2, K1, K2. El resto son movimientos especiales.
Título: Detección De "comandos"
Publicado por: ALRAZ en 04 de Octubre de 2004, 10:46:59 AM
 
Cita de: "sés"...

Yo considero movimientos básicos: B, F, D, U, P1, P2, K1, K2. El resto son movimientos especiales.
Pero los movimientos básicos podrían capturarse también con las mismas funciones, no crees?

es decir
si se presiona
F

y se sabe que no se ha presionado nada Antes de F
entonces sabremos que lo que el jugar quiere es caminar hacia adelante

Imagino que para eso es lo de
"No detenerse en el primer comando que se encuentre, seguir buscando hasta encontrar el más largo posible"

De todos modos sigo teniendo curiosidad por lo de la tolerancia a las diagonales  (genial)


Por cierto:
No creen que esto sería un buen tema para "Código de la semana"?
Claro, suponiendo que se logre algo XD
Título: Detección De "comandos"
Publicado por: Malandrin en 04 de Octubre de 2004, 11:08:26 AM
 
Citaror cierto, lo de la tecla desencadenante de un movimiento no me convence. ¿IZQUIERDA no desencadena un movimiento? ¿Solo son movimientos si terminan con un disparo?
No olvidemos que F,F es un movimiento (salto alante o correr), D, U es otro (salto largo), etc.

Con movimientos desencadenantes me refería a los que crean ... mmm.. 'magias' (p.e. un aduken), y los tengo separados de los movimientos 'normales' -avance, retroceso, salto, correr...-
Título: Detección De "comandos"
Publicado por: sés en 04 de Octubre de 2004, 11:12:53 AM
 
Cita de: "ALRAZ"Pero los movimientos básicos podrían capturarse también con las mismas funciones, no crees?
:P No, soy ateo.

Bueno, yo creo que esos movimiento son demasiado importantes como para incluirlos ahí. Me explico.
Mi contrincante salta hacia mí. Tengo varias opciones, por ejemplo:
- Contraatacar.
- Cubrirme.
- Saltar hacia atrás.

Si quiero cubrirme (B) o saltar hacia atrás (U+B), lo suyo es que la respuesta sea inmediata. Si incluimos estos movimientos con los demás, tendremos que esperar a ver si hace algún movimiento más antes de movernos... respuesta pobre = jugador cabreado = "que le den a este juego".

Cita de: "ALRAZ"..y se sabe que no se ha presionado nada Antes de F
Como ves, el problema no es lo que se pulsó antes, es lo que se pulse después.

La cosa es:
¿Pulsa F? Pues nos movemos p'alante. Si luego pulsa otra cosa ya se verá si es algún movimiento especial o no.

Además de los básicos que dije antes, hay alguno más que se me pasó y que deben ser gestionados aparte, como cubrirse.

Cita de: "ALRAZ"De todos modos sigo teniendo curiosidad por lo de la tolerancia a las diagonales  (genial)
Vaaale, intentaré buscar ese código. Total, pronto lo necesitaré yo.
Título: Detección De "comandos"
Publicado por: Lessman en 04 de Octubre de 2004, 11:25:46 AM
...
Título: Detección De "comandos"
Publicado por: sés en 04 de Octubre de 2004, 11:51:41 AM
 Lo hagas como lo hagas, hay movimientos que quedan fuera de esos estados.
Si no, mira Akuma del SF. ¿Cómo era su "superespecialquetecagaslaspatasabajo"?
Era algo como: LP, LP, F, LK, HP

¿Qué ves cúando lo haces? Pues que el personaje da dos puños pequeños, se mueve un poco alante y da una patada pequeña. O sea, que el "motor" ejecuta los movimientos básicos según se pulsan los botones. Al llegar HP reconoce un movimiento especial y entonces lo ejecuta.

Esto mismo lo puedes comprobar prácticamente con cualquier movimiento, pero he puesto este porque es bastante claro. De todas formas empieza a trastear y ya irás descubriendo los detalles sobre la marcha y verás lo que más te convenga.

Creo que tenía un programa de pruebas que solo hacía esto... buscarelo a ver.
Título: Detección De "comandos"
Publicado por: Lessman en 04 de Octubre de 2004, 02:20:16 PM
...
Título: Detección De "comandos"
Publicado por: ALRAZ en 04 de Octubre de 2004, 09:51:49 PM
 Muchisimas gracias a todos los que han mostrado su interés en el tema  (ole)

Veré si en la semana, en esos ratos que no tengo clases, me pongo a implementar algo usando lo que se ha discutido aquí y algunas ideas que me han salido mientras leía  :D
Por supuesto, se aceptan más sugerencias  ;)


Respecto a lo último del LP, LP, F...
(Hubiera jurado que el movimiento se llama "shun goku satsu", pero me gusta más ese nombre que le has puesto sés)

La idea básica sería que, los comandos que se van ejecutando no se van perdiendo.
Creo que se puede explicar mejor con un ejemplillo:
En Marvel vs Capcom 2 tienes la posibilidad de "cancelar" movimientos en "Supers"
(Llamados Hyper combos en el juego)
Diferencias entre uno y otro para quienes no conozca: Un movimiento se ejecuta normalmente con una secuencia y un botón, mientras que un Hyper Combo utiliza una secuencia y dos o más botones además de requerir una barra de poder para poder ejecutarse ;)

Dicho eso...
Cuando ejecutas un movimiento, lo puedes cancelar en un Hyper
Esto es: después de ejecutar el movimiento, marcas la secuencia del Hyper y el primero se detiene, ejecutando inmediatamente el segundo.

A qué viene todo esto?
Bueno, muy seguido me ha tocado ver que cuand marcas un Hyper sencillito (Sin haber marcado movimiento especial primero), de vez en cuando el juego hace algún movimiento especial que concuerda con la secuencia del Hyper e inmediatamente lo cancela en el Hyper.

hasta se puede escuchar al personaje "pronunciando" las palabras del movimiento, se corta y luego la cambia por las palabras del Hyper

Todo este chorro anterior me hace pensar que el sistema registra las entradas en una pila o una lista o alguna cosa de esas pero nunca la vacía, de modo que siempre se puede saber que se ha hecho y que se puede hacer
La comprovació de estados vendría en una etapa posterior