Eliminar la demora al inicio de presionar una tecla

11

Estoy haciendo un juego simple, y uno de los problemas que encontré es el molesto retraso al presionar una tecla continuamente.

Básicamente, cuando presiono (durante mucho tiempo), por ejemplo Up, mi objeto se moverá 1 unidad hacia arriba, no se moverá (durante aproximadamente 1 segundo), y luego se moverá continuamente 1 unidad hacia arriba (sin demoras).

Actualmente, uso esto para mover el objeto (SDL2):

while (SDL_PollEvent(&event))
{
    switch (event.type)
    {
    case SDL_KEYDOWN:
        switch (event.key.keysym.sym)
        {
        case SDLK_UP:
            //Move object 1 unit up
            break;
        //Other unrelated things omitted
        }
        break;
    //Omitted other cases
    }
}

Lo que me gustaría tener es eliminar el retraso, para que el objeto pueda moverse inmediatamente Upmuy rápidamente. ¿Hay alguna forma de hacer esto?

Rakete1111
fuente

Respuestas:

19

Al esperar que se activen los eventos de pulsación de tecla, es probable que esté a merced de la frecuencia de repetición de eventos clave que controla el sistema operativo (y qué usuarios pueden especificar ellos mismos).

En su lugar, es posible que desee llamar SDL_GetKeyboardStateal principio del ciclo de actualización del juego (la parte de la actualización que ocurre en cada cuadro, ya sea que haya entrado o no un evento) para obtener el estado del teclado y verificar eso para ver si la tecla está presionada o no durante cualquier fotograma individual.


fuente
¿No sería mejor escuchar mensajes de ventana? Al usar el sondeo, a veces pierdo pulsaciones de teclas muy cortas y este problema empeora cuando la velocidad de fotogramas es baja.
Roy T.
@RoyT. Realmente depende de tu juego y del tipo de acción que quieras activar con la tecla. Si presionar una tecla es algo único, como una tecla de "acción", que cierra un cuadro de diálogo, entonces una cola de mensajes es el enfoque correcto: desea escuchar un evento atómico. - Si, por otro lado, el estado de la tecla representa un estado continuo como una tecla "mover", la lógica suele ser while key UP is down move 30 units per second, y por segundo solo tiene sentido cuando tiene un tiempo medible entre la tecla hacia abajo y hacia arriba, generalmente más de un cuadro.
Falco
@RoyT. También puede escuchar mensajes (y usarlos para actualizar su propia matriz de estado del teclado); Opté por sugerir este enfoque por su simplicidad. Sin embargo, puedes escribir otra respuesta. La parte importante es simplemente evitar depender de los mensajes del sistema operativo para verificar si la tecla está continuamente presionada, porque eso es lo que lo encadena a la tasa de repetición de la tecla del sistema operativo.
Y por cuadro te refieres a la marca del juego, no al cuadro de video, ¿verdad? Porque no estamos siendo plebeyos y codificando la lógica del juego en el bucle de renderizado. :-)
corsiKa
@JoshPetrie Estoy completamente de acuerdo, solo quería señalar esta pequeña advertencia si necesita marcar un 'clic' en lugar de una 'prensa'. :)
Roy T.
10

Una forma alternativa (¡el enfoque de Josh también es genial!) Sería configurar un booleano SDL_KEYDOWNy posiblemente también ignorar todos los eventos clave repetidos. Eso puede hacerlo comprobando el repeatmiembro del evento clave.

Entonces podría implementar su propio temporizador, que no tiene que ser nada lujoso, e implementar la repetición de teclas usted mismo. Puede activar la acción directamente desde el temporizador o incluso generar un SDL_KEYDOWNevento y unificar las soluciones.

Tyyppi_77
fuente