SDL - soltar pulsación de teclas

Tratamos sobre el manejo de APIs frecuentemente utilizadas en el desarrollo de videojuegos, como SDL, pygame o SFML.

SDL - soltar pulsación de teclas

Notapor Requeteguay » Dom Ago 13, 2006 11:41 am

Hola a tod@s,

Estaba experimentando con el código del juego Volleyball y me he encontrado un pequeño problema que me gustaría explicaros.

Deseaba que el pingüiino saltase una sóla ocasión por cada pulsación de la tecla de salto en vez de saltar continuamente mientras se tiene pulsada la tecla.

De arrancada este problema lo he resuelto añadiendo el código que voy a ponerles, pero estoy me ha causado un problema que ya no he sabido solucionar.

Dentro de util.c he añadido este código al método "procesar_eventos":

int procesar_eventos (void)
{
static SDL_Event event;

while (SDL_PollEvent (&event))
{

if (event.type == SDL_QUIT)
return 0;

//comprueba procesos de pulsación de teclas
if (event.type == SDL_KEYDOWN)
{
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
return 0;
break;

default:
break;
}
}

//comprueba procesos cuando se sueltan las teclas
if (event.type == SDL_KEYUP)
{
switch (event.key.keysym.sym)
{
case SDLK_n:
printf("Se ha soltado la tecla de golpe del personaje 1\n");
break;
}
}
}

return 1;
}

Bien. Mi intención es sustituir la instrucción "printf("Se ha soltado la tecla de golpe del personaje 1\n");" por otra que consiga pasarle a la estructura "personaje" un valor para una de sus propiedades. Algo así:

Estructura personaje ->

typedef struct Personaje
{
SDL_Surface * imagen;
SDLKey tecla_derecha;
SDLKey tecla_izquierda;
SDLKey tecla_arriba;
SDLKey tecla_abajo;
SDLKey tecla_saltar;
SDLKey tecla_golpe;
enum estados estado;
int x;
int y;
int z;
int limite_izquierdo;
int limite_derecho;
int limite_arriba;
int limite_abajo;
int lado; //hacia donde mira el personaje...
int posicion_salto; //guardo la coordenada x donde se encuentra el jugador
float velocidad_salto;
int saltando;
int pulsado;
int soltar_tecla;
int paso;
int cuadro;
int delay;
int delay_golpe;
enum golpes golpe;
} Personaje;

Y donde tengo el printf de util.c pasarle algo así:

personaje->soltar_tecla=1;

Siento lo extenso de mi post. Si no se me ha entendido bien intentaré exponerlo de alguna otra manera.

Muchas gracias!!!
Avatar de Usuario
Requeteguay
 
Mensajes: 9
Registrado: Mié Ago 09, 2006 4:37 pm

Re: SDL - soltar pulsación de teclas

Notapor hugoruscitti » Dom Ago 13, 2006 10:21 pm

Requeteguay escribió:Deseaba que el pingüiino saltase una sóla ocasión por cada pulsación de la tecla de salto en vez de saltar continuamente mientras se tiene pulsada la tecla.


Seguramente existen muchas formas de lograrlo, aunque pensando en el código de ese juego pienso que la forma mas práctica de hacerlo es ampliando las condiciones a la hora de inicial el salto.
Cuando el personaje está "parado" o "caminando" se realiza una verificación en los controles del usuario para "impulsar" el salto.
Por ejemplo, en la función "personaje_parado" de "personaje.c" encontré:

Código: Seleccionar todo
        if (control_pulso (data->control, UP))
        {
                personaje_cambiar_estado (data, personaje_iniciar_salto,
                        personaje_saltando);
        }


Es decir, el único requisito para comenzar a "saltar" es la pulsación de la tecla "UP". Dejar pulsada la tecla es equivalente a pulsarla reiteradas veces.
Encontré dos posibles formas de resolver esto, la primera consiste en llamar a la función "control_pulso_sin_repeticion" en lugar de "control_pulso".
Quedaría:

Código: Seleccionar todo
        if (control_pulso_sin_repeticion (data->control, UP))
        {
                personaje_cambiar_estado (data, personaje_iniciar_salto,
                        personaje_saltando);
        }


Otra posibilidad, algo mas compleja, consiste en ampliar la condición de salto.
Podrías incluir otro atributo en la estructura del personaje que indique si se está pulsado la tecla "UP" a causa de un salto:
Por ejemplo:

Código: Seleccionar todo
struct personaje
{
        int x;
        int y;
        int saltado; /* Nuevo atributo, campo o variable */


Esa variable tomaría el valor 0 o 1, indicando si el usuario comenzó a saltar o no. Así, la variable serviría como condición de "corte" evitando que el usuario pueda dejar pulsada la tecla de salto.
Veamos como se podría manipular:

Cuando el módulo se inicia (función "personaje_iniciar") la variable tendría que tener el valor 0. Cuando el personaje está "parado" o "caminando" se debe iniciar el "salto" solo si la variable "saltando" lo permite (esa es la condición de corte a la que me refería):

Código: Seleccionar todo
        if (control_pulso (data->control, UP) && data->saltando == 0)
        {
                personaje_cambiar_estado (data, personaje_iniciar_salto,
                        personaje_saltando);

                data->saltando = 1;
        }


Hasta aquí, el personaje solo saltaría una sola vez. La variable tomó el valor 1 y eso imposibilita cualquier otro salto.
Como queremos que el personaje pueda saltar nuevamente, pero solo después de soltar y pulsar nuevamente la tecla, podemos devolver el valor 0 a la variable "saltando" solo cuando el usuario deje de pulsar la tecla UP:

Código: Seleccionar todo
        if (data->saltando == 1 && ! control_pulso (data->control, UP))
        {
                printf ("El personaje había saltado. Como ahora soltó la ");
                printf ("tecla UP, podemos permitirle saltar nuevamente \n");

                data->saltando = 0;
        }


Esa porción de código debería evaluarse constantemente, se podría añadir en la función "personaje_actualizar".
En fin, esas son dos soluciones que podrían funcionar (creo).

Saludos y mucha suerte.
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina

Notapor Requeteguay » Mar Ago 15, 2006 10:24 am

Hola Hugo,

Al final lo he hecho con el control de corte.

En todos los sitios recomiendan usar la forma en la que SDL controla cuando se suelta una tecla, pero en este caso he adaptado la explicación que me has dado al código que tengo actualmente y todo está OK.

Gracias por todo, espero que pronto pueda enseñaros los resultados de lo que estoy haciendo partiendo del código de Volleyball xD.
Avatar de Usuario
Requeteguay
 
Mensajes: 9
Registrado: Mié Ago 09, 2006 4:37 pm


Volver a Sobre las bibliotecas multimedia

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron