Suppression du retard au début d'une pression sur une touche

11

Je fais un jeu simple, et l'un des problèmes que j'ai rencontrés est le retard ennuyeux lorsque j'appuie sur une touche en continu.

Donc, fondamentalement, lorsque j'appuie (pendant très longtemps) par exemple Up, mon objet se déplace d'une unité vers le haut, ne se déplace pas (pendant environ 1 seconde), puis se déplace continuellement d'une unité vers le haut (sans aucun retard).

Actuellement, j'utilise ceci pour déplacer l'objet (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
    }
}

Ce que j'aimerais, c'est supprimer le retard, afin que l'objet puisse se déplacer immédiatement Uptrès rapidement. Est-ce qu'il y a un moyen de faire ça?

Rakete1111
la source

Réponses:

19

En attendant que des événements de frappe soient déclenchés, vous êtes probablement à la merci du taux de répétition des événements clés que le système d'exploitation contrôle (et que les utilisateurs peuvent spécifier eux-mêmes).

Au lieu de cela, vous voudrez peut-être appeler SDL_GetKeyboardStateen haut de votre boucle de mise à jour du jeu (la partie de la mise à jour qui se produit à chaque image, qu'un événement se soit produit ou non) pour obtenir l'état du clavier et vérifier que pour voir si le haut la touche est enfoncée ou non pendant une image individuelle.


la source
Ne serait-il pas préférable d'écouter les messages des fenêtres? En utilisant l'interrogation, je manque parfois des pressions très courtes sur les touches et ce problème s'aggrave lorsque le taux de rafraîchissement est faible.
Roy T.
@RoyT. Cela dépend vraiment de votre jeu et du type d'action que vous souhaitez déclencher avec la touche. Si la pression sur une touche est une chose ponctuelle, comme une touche "action", qui ferme une boîte de dialogue, alors une file d'attente de messages est la bonne approche - vous voulez écouter un événement atomique. - Si, d'autre part, l'état de la clé représente un état en cours comme une touche de "déplacement", la logique est généralement while key UP is down move 30 units per second- et par seconde n'a de sens que lorsque vous avez un temps mesurable entre la clé vers le bas et vers le haut - généralement plus d'une image.
Falco
@RoyT. Vous pouvez également écouter des messages (et les utiliser pour mettre à jour votre propre tableau d'état du clavier); J'ai choisi de suggérer cette approche pour sa simplicité. Vous pouvez certainement écrire une autre réponse. L'important est simplement d'éviter de s'appuyer sur les messages du système d'exploitation pour vérifier si la clé est constamment enfoncée, car c'est ce qui vous enchaîne au taux de répétition de la clé du système d'exploitation.
Et par image, vous voulez dire tick de jeu, pas d'image vidéo, non? Parce que nous ne sommes pas des plebs et n'encodons pas la logique du jeu dans la boucle de rendu. :-)
corsiKa
@JoshPetrie Je suis entièrement d'accord, je voulais juste souligner cette petite mise en garde si vous devez vérifier un «clic» au lieu d'une «presse». :)
Roy T.
10

Une autre façon (l'approche de Josh est également excellente!) Serait de configurer un booléen SDL_KEYDOWN, et peut-être aussi d'ignorer tous les événements clés répétés. Pour ce faire, vérifiez le repeatmembre de l'événement clé.

Ensuite, vous pouvez implémenter votre propre minuterie, qui n'a rien de compliqué, et implémenter vous-même la répétition des touches. Vous pouvez soit déclencher l'action directement à partir du minuteur, soit même générer un SDL_KEYDOWNévénement et unifier les solutions.

Tyyppi_77
la source