Mantener tecla pulsada en SDL

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

Mantener tecla pulsada en SDL

Notapor pablo9891 » Mié Dic 29, 2010 1:58 am

Estoy retomando todo este tema del SDL, y siento que se me olvidaron algunas cosas, y una de ellas es esta. Mi problema es que estoy volviendo a hacer un juego de Pong (ya habia hecho un thread sobre una version anterior), y tengo problemas cuando mantengo apretada la tecla, es decir, si apreto la tecla el frame se mueve, pero si mantengo la tecla apretada no se mueve, como puedo hacer para solucionarlo?

El codigo que tengo hasta el moment es este:

Código: Seleccionar todo
    while(ejecuta)
    {
        miPersonaje.dibujarImagen(pantalla);
        while(SDL_PollEvent(&evento))
        {
        if(evento.type == SDL_QUIT)
         {
          ejecuta = false;
         }
          else
          {
           if (evento.type == SDL_KEYDOWN)
           {
            if(evento.key.keysym.sym == SDLK_UP)
            {
                val = val+5;

            }
           }
            if (evento.type == SDL_KEYUP)
           {
            if(evento.key.keysym.sym == SDLK_UP)
            {
                rectangulo.x = miPersonaje.getX();
                rectangulo.y = miPersonaje.getY();
                rectangulo.h = miPersonaje.getAltura();
                rectangulo.w = miPersonaje.getAncho();
                SDL_FillRect(pantalla,&rectangulo,SDL_MapRGB(pantalla->format,0,0,0));
                miPersonaje.setY(miPersonaje.getY()+val);
                miPersonaje.dibujarImagen(pantalla);

                SDL_Flip(pantalla);           }
            }
         }
       }
    }
pablo9891
 
Mensajes: 32
Registrado: Lun Dic 28, 2009 2:48 am

Re: Mantener tecla pulsada en SDL

Notapor carlostex » Mié Dic 29, 2010 2:17 am

No veo el por que dibujas cuando al tecla se suelta, que es lo que quisiste hacer, por eso no funciona y no lo hará de esa forma.
la parte del código que se encarga de dibujar nunca debe estar dentro de las condiciones de los eventos, pues solo estas limitando dibujar cuando se produce uno, y en general en un juego se siguen corriendo las animaciones se produzcan o no eventos.
Yo lo pondría así:
Código: Seleccionar todo
while(ejecuta)
    {
        miPersonaje.dibujarImagen(pantalla);
        while(SDL_PollEvent(&evento))
        {
             if(evento.type == SDL_QUIT)
             {
                 ejecuta = false;
             }
         
             if (evento.type == SDL_KEYDOWN)
             {
                    if(evento.key.keysym.sym == SDLK_UP)
                    {
                         val = val+5;
                         rectangulo.x = miPersonaje.getX();
                         rectangulo.y = miPersonaje.getY();
                          rectangulo.h = miPersonaje.getAltura();
                          rectangulo.w = miPersonaje.getAncho();
                          SDL_FillRect(pantalla,&rectangulo,SDL_MapRGB(pantalla->format,0,0,0));
                          miPersonaje.setY(miPersonaje.getY()+val);
                         miPersonaje.dibujarImagen(pantalla);
                    }
            }
           
                   

                   
               
            }
            SDL_Flip(pantalla);   
       }
El conocimiento de unos es conocimiento de todos.
Avatar de Usuario
carlostex
 
Mensajes: 249
Registrado: Mar Jul 14, 2009 4:13 am
Ubicación: mexico

Re: Mantener tecla pulsada en SDL

Notapor pablo9891 » Mié Dic 29, 2010 3:01 am

Vos sabes que sigue funcionando de la misma manera, o sea si mantengo la tecla apretada ejecuta una sola vez
pablo9891
 
Mensajes: 32
Registrado: Lun Dic 28, 2009 2:48 am

Re: Mantener tecla pulsada en SDL

Notapor carlostex » Mié Dic 29, 2010 3:45 am

ha ok, no recuerdo ahora muy bien si al poner event.type == SDL_KEYDOWN solo se testea cuando se presiona, pero estoy casi seguro, por que he checado un programa que tengo, y cuando se que tengo que hacer una animación cuando la tecla esta apretada por tiempo indefinido no uso la técnica del polling, testeo directamente el estado del teclado en ese momento.
eso lo logras con la función:

key=SDL_GetKeyState(NULL);

donde key es un vector de esta forma:

Uint8 *key;

solo contiene ceros y unos, si quieres checar una tecla pones if (k(SDLK_UP)){...}
El conocimiento de unos es conocimiento de todos.
Avatar de Usuario
carlostex
 
Mensajes: 249
Registrado: Mar Jul 14, 2009 4:13 am
Ubicación: mexico

Re: Mantener tecla pulsada en SDL

Notapor Juan Carlos » Mié Dic 29, 2010 11:22 am

Hola, lo que sucede es que cuando se presiona una tecla (o se libera) se produce un evento en SDL keydown (o keyup) pero solo cuando la tecla es presionada o liberada.

Si la tecla es presionada (un evento es generado) y luego se la retiene presionada, no habra nuevos eventos.

La solucion mas simple seria escribir algo asi (en pseudo codigo)

Código: Seleccionar todo
//Los eventos NO controlan la posicion, sino que controlan la velocidad
velocidad = 0;

while(ejecuta)
    {
     ...
    if (evento.type == SDL_KEYDOWN)
        {
         if(evento.key.keysym.sym == SDLK_UP and velocidad == 0)
              {
               //Se presiono la tecla correcta y dado que la velocidad era 0
               //se interpreta que el jugador quiere comenzarse a mover
                velocidad = 5;
              }
         }
    else if(evento.type == SDL_KEYUP)
        {
         if(evento.key.keysym.sym == SDLK_UP and velocidad != 0)
             {
               //Se libero la tecla y dado se estaba moviendo (velocidad != 0)
               //se interpreta que el jugador quiere dejarse de mover
                 velocidad = 0
             }
        }

      ....
     //Este pseudo codigo indica como se actualiza la nueva posicion
     //Si el jugador nunca presiono la tecla keyup, velocidad sera igual a 0
     //y el jugador no se movera
      posicionNueva = posicionActual + velocidad;
}
     


Por supuesto esto puede hacerse mas elaborado como por ejemplo hacer que la tecla Up aumente la velocidad (de 0 pasa a 5), mientras que la tecla Down la reduzca (de 0 a -5).
Pero eso dependera del juego que estes haciendo.

Saludos
Juan Carlos
 
Mensajes: 97
Registrado: Sab Jul 07, 2007 1:05 pm

Re: Mantener tecla pulsada en SDL

Notapor Geo » Vie Ene 21, 2011 5:04 am

También puedes configurar SDL para que repita los eventos de teclas cuando se mantienen pulsadas:

Código: Seleccionar todo
// Permite repetir teclas
SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );

Esto lo haces antes del ciclo principal de tu juego. El primer parámetro indica cuánto tiempo esperar a partir de la primera vez que se presiona la tecla para empezar la repetición de eventos, el segundo indica cada cuánto tiempo emitir nuevamente los eventos. El tiempo se indica en milisegundos, los valores por defecto (los que usé en el ejemplo) son 500 y 30, respectivamente.

Otra forma, es que no lo manejes por eventos, sino que obtengas el estado de todo el teclado y revises si cada tecla está siendo pulsada o no:
Código: Seleccionar todo
Uint8* keystate = SDL_GetKeyState( NULL );
if ( keystate[ SDLK_RETURN ] ) ejecutar_codigo();
La imaginación es el límite.
Visita mi blog en inglés o en español.
Geo
 
Mensajes: 244
Registrado: Jue Ago 10, 2006 3:51 am
Ubicación: México


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