Rimozione del ritardo all'inizio della pressione di un tasto


11

Sto realizzando un gioco semplice e uno dei problemi che ho riscontrato è il fastidioso ritardo nella pressione continua di un tasto.

Quindi, fondamentalmente, quando premo (per molto tempo), ad esempio Up, il mio oggetto si sposterà di 1 unità verso l'alto, non si sposterà (per circa 1 secondo), quindi si sposterà continuamente di 1 unità verso l'alto (senza ritardi).

Attualmente, lo uso per spostare l'oggetto (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
    }
}

Quello che vorrei avere è rimuovere il ritardo, in modo che l'oggetto possa spostarsi immediatamente Upmolto rapidamente. C'è un modo per fare questo?

Risposte:


19

Attendendo che vengano attivati ​​gli eventi key-down, si è probabilmente in balia della frequenza di ripetizione degli eventi chiave controllata dal sistema operativo (e quali utenti possono specificare se stessi).

Invece, potresti voler chiamare SDL_GetKeyboardStatenella parte superiore del ciclo di aggiornamento del gioco (la parte dell'aggiornamento che si verifica in ogni frame, indipendentemente dal fatto che si sia verificato un evento) per ottenere lo stato della tastiera e controllare che per vedere se il il tasto è premuto o meno durante ogni singolo fotogramma.


Non sarebbe meglio ascoltare i messaggi delle finestre? Usando il polling a volte mi mancano pressioni di tasti molto brevi e questo problema peggiora quando il framerate è basso.
Roy T.

@RoyT. Dipende molto dal tuo gioco e dal tipo di azione che vuoi attivare con la chiave. Se la pressione del tasto è una cosa una tantum, come un tasto "azione", che chiude una finestra di dialogo, una coda di messaggi è l'approccio giusto: vuoi ascoltare un evento atomico. - Se invece lo stato della chiave rappresenta uno stato in corso come un tasto "sposta", la logica è di solito while key UP is down move 30 units per second- e al secondo ha senso solo quando si ha un tempo misurabile tra chiave giù e su - di solito più di un fotogramma.
Falco,

@RoyT. Puoi anche ascoltare i messaggi (e usarli per aggiornare il tuo array di stati della tastiera); Ho scelto di suggerire questo approccio per la sua semplicità. Puoi sicuramente scrivere un'altra risposta però. La parte importante è solo quella di evitare di fare affidamento sui messaggi del sistema operativo per verificare se la chiave è continuamente inattiva, perché è ciò che ti lega alla frequenza di ripetizione della chiave del sistema operativo.

E per cornice intendi il segno di spunta del gioco, non il fotogramma video, giusto? Perché non stiamo diventando plebs e codificando la logica di gioco nel loop di rendering. :-)
corsiKa

@JoshPetrie Sono completamente d'accordo, volevo solo sottolineare questo piccolo avvertimento se è necessario controllare un 'clic' invece di una 'stampa'. :)
Roy T.

10

Un modo alternativo (anche l'approccio di Josh è fantastico!) Sarebbe quello di impostare un valore booleano SDL_KEYDOWN, e forse anche ignorare tutti gli eventi chiave ripetuti. Che cosa puoi fare controllando il repeatmembro dell'evento chiave.

Quindi potresti implementare il tuo timer, che non deve essere niente di speciale, e implementare la ripetizione chiave per te stesso. È possibile attivare l'azione direttamente dal timer o persino generare un SDL_KEYDOWNevento e unificare le soluzioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.