Partage
  • Partager sur Facebook
  • Partager sur Twitter

Compter les pressions sur une touche en X secondes

Sujet résolu
    24 janvier 2020 à 21:07:18

    Bonjour, je suis en train de créer un RPG au tour par tour en console.

    J'ai eu l'idée de définir les stats du joueur selon sa capacité à appuyer rapidement sur la touche entrée pendant 10 secondes par exemple.

    J'ai beau réfléchir, je ne trouve pas comment faire... Il faudrait une boucle à la fois limitée par un timer ET qui compte ses itérations (avec une fonction getch() ). J'ai l'impression que c'est impossible, sans SDL. 

    Merci de vos réponses

    • Partager sur Facebook
    • Partager sur Twitter
      25 janvier 2020 à 0:08:19

      Hello,

      C'est peut-être possible. Une piste, mais ce code (windows) ne tient pas compte du fait que la touche n'a été pressée qu'une seule fois et maintenue enfoncée:

      #include <time.h>
      #include <conio.h>
      #include <stdio.h>
      
      #define ESCAPE	'\x1b'
      
      int countKeyPressed(int key,int max_seconds) {
      	time_t end_time=time(NULL)+max_seconds;
      	int count=0;
      	
      	while(time(NULL)<end_time)
      		if(kbhit())
      			if(getch()==key)
      				count++;
      	
      	return(count);
      }
      
      int main(void) {
      	int max_sec=3;
      	
      	printf("Appuyer sur la touche escape (%d secondes)\n",max_sec);
      	printf("Nombre d'appuis: %d x\n",countKeyPressed(ESCAPE,max_sec));
      	
      	return(0);
      }

      Edit: après rélexion (je suis --souvent-- lent à la détente), je me dis qu'en passant par l'api windows et les VK_KEY et la focntion GetKeyState(), ça doit être faisable. Je testerai peut-être un jour.

      -
      Edité par edgarjacobs 25 janvier 2020 à 0:58:19

      • Partager sur Facebook
      • Partager sur Twitter

      On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

        25 janvier 2020 à 2:10:11

        Salut,
        Sur certains systèmes, si on garde le doigt appuyé sur la touche, la répétition se fait automatiquement. Je ne sais pas à quelle vitesse.
        Un test rapide me donne moins de 10 caractères par seconde.
        @edgarjacobs:
        Si on n'est pas assez rapide, on a 0 caractères :)
        Même en gardant le doigt appuyé sur le Escape, j'ai une variation dans le nombre de touches.
        Je suppose que la variation vient du fait que le premier appel à time() peut se faire en début ou en fin de la seconde (les premiers ou les derniers ms).
        Il y a donc une variation de près de une seconde.
        J'ai modifié le code pour appeler kbhit() tant que je n'ai pas de caractère.
        J'ai essayé d'appeler time() à répétitions jusqu'au changement de seconde.
        (c'est brutal, il n'y a pas de sleep() de un ms)
        Cela varie toujours ...

        -
        Edité par PierrotLeFou 25 janvier 2020 à 4:33:56

        • Partager sur Facebook
        • Partager sur Twitter

        Le Tout est souvent plus grand que la somme de ses parties.

          25 janvier 2020 à 9:59:26

          Merci beaucoup edgarjacobs pour ton bout de code, il m'aide fortement ^^. Je n'y connais rien à l'api windows et ce genre de trucs, mais ta version est déjà vraiment pas mal !

          Est ce que tu pourrais juste m'expliquer d'où sort ton '\x1b'  ?

          J'aimerais remplacer la touche échap par la touche entrée mais '\n' ne fonctionne pas...

          -
          Edité par RaphaëlOester 25 janvier 2020 à 11:45:45

          • Partager sur Facebook
          • Partager sur Twitter
            25 janvier 2020 à 14:39:55

            Le 0x1b est le code hexadécimal pour le caractère Escape, il vaut 27 décimal ou 33 octal si tu préfères :)
            • Partager sur Facebook
            • Partager sur Twitter

            Le Tout est souvent plus grand que la somme de ses parties.

              25 janvier 2020 à 17:06:39

              #define ENTER '\x0d'

              codes ascii

              -
              Edité par edgarjacobs 25 janvier 2020 à 17:09:05

              • Partager sur Facebook
              • Partager sur Twitter

              On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                25 janvier 2020 à 17:40:07

                J'avoue être plus familier avec le code octal des caractèeres de contrôle. Ainsi 0x0d = 015 = 13
                Sur certains systèemes, on peut mettre Ctrl+M, car M est la 13ième lettre.
                • Partager sur Facebook
                • Partager sur Twitter

                Le Tout est souvent plus grand que la somme de ses parties.

                  25 janvier 2020 à 19:23:39

                  Bien vuuuu j'ai remplacé ça par 13 et ça marche nickel, merci beaucoup ! 

                  Maintenant si quelqu'un a une solution simple pour empêcher que le maintien de la touche compte pour plein d'appuyages, ça m'intéresse :)

                  • Partager sur Facebook
                  • Partager sur Twitter
                    26 janvier 2020 à 1:01:57

                    La solution serait de savoir à quelle fréquence se fait la répétition automatique sur l'ordi en question.
                    Malgré mes tests peu concluants, j'ai l'impression que c'est de l'ordre de 30 frappes par seconde.
                    Je ne crois pas qu'on soit capable d'aller aussi vite en tapant et relâchant.
                    Autrefois, on disait qu'une bonne secrétaire pouvait taper 60 mots à la minute (combien de caractères par mot?).
                    Même en posant que c'était 10 caractères par mot, cela donnerait 600 caractères par minute, ou 10 caractères par seconde.
                    Si tu ne peux pas connaître la fréquence de frappe de l'ordi, une estimation de 20 caractères par seconde serait acceptable.
                    • Partager sur Facebook
                    • Partager sur Twitter

                    Le Tout est souvent plus grand que la somme de ses parties.

                      26 janvier 2020 à 10:09:15

                      Je comprends, mais qu'est ce que cette fréquence nous permettrait de faire ?

                      J'ai posé 10 caractères par secondes pour aboutir à ce code : 

                      int compteTouche(int touche, int secondesMax)
                      {
                          time_t tempsDeFin=time(NULL)+ secondesMax;
                          int compteur=0;
                          while(time(NULL)<tempsDeFin)
                              if(kbhit())
                              {
                                  if(getch() == touche)
                                  {
                                      compteur++;
                                      Sleep(100); //10 clics par seconde maximum
                                  }
                              }
                          return compteur ;
                      }

                      On tombe sur des résultats à peu près cohérents : en maintenant enfoncée la touche entrée, on arrive à environ 60 clics en 7 secondes. Mais le problème reste entier : il faudrait que la touche entrée ne compte qu'un clic par pression, non pas un clic toutes les fois où la boucle s'exécute et que la touche est enfoncée.

                      Est ce qu'il existe un fonction qui détecte lorsqu'une touche est enfoncée et lorsqu'elle ne l'est pas ? 

                      • Partager sur Facebook
                      • Partager sur Twitter
                        27 janvier 2020 à 3:56:23

                        Je ne crois pas que de mettre un sleep(100) soit une bonne idée même si j'ai dit que c'est difficile de taper plus de 10 caractères par secondes.
                        Au fait, sleep accepte un paramètre en secondes. As-tu testé cela?
                        La fonction kbhit() te retourne 0 s'il n'y a pas de caractère, donc tu boucles dessus tant que ce n'est pas différent de 0.
                        À ce moment, tu vas chercher le caractère avec getch() et kbhit() devrait à nouveau te retourner 0 jusqu'au prochain caractère.
                        Voici un lien qui décrit kbhit:
                        http://perso.iut-nimes.fr/wdesrat/faq05.html
                        Quand la touche est maintenue enfoncée, le système détecte cette condition et ralentit artificiellement le rithme où le caractère est envoyé au programme.
                        Sinon, on pourrait envoyer un million de caractères par seconde au programme ...
                        Je ne sais pas où trouver la constante (ou variable) dans le système qui définit l'intervalle de temps dans ce cas.
                        Quand tu touches une clé, ce n'est pas instantané. Tu reste appuyé pendant combien de temps? Un milliseconde? Dix millisecondes?
                        Il y a donc une autre constante qui dit au système quand il doit considérer qu'on est appuyé.
                        J'ai déjà noté des délais de réaction comme si le système n'était pas certain si je maintenais ma touche enfoncée ou pas.
                        • Partager sur Facebook
                        • Partager sur Twitter

                        Le Tout est souvent plus grand que la somme de ses parties.

                          28 janvier 2020 à 16:44:29

                          Re,-

                          J'ai fait un petit test, ceci semble fonctionner:

                          #include <time.h>
                          #include <stdio.h>
                          #include <limits.h>
                          #include <stdbool.h>
                          #include <windows.h>
                          
                          #define DELAY			2				// en seconde
                          #define KEY				VK_ESCAPE		// https://docs.microsoft.com/fr-fr/windows/win32/inputdev/virtual-key-codes
                          #define KEY_IS_PRESSED	(1<<(sizeof(SHORT)*(CHAR_BIT)-1))
                          
                          int main(void) {
                          	int npressed=0;
                          	bool key_has_been_released=true;	// pour ne pas compter une touche qui reste enfoncée
                          	time_t tsync,tend;
                          	
                          	/* pour être "certain" de démarrer sur une seconde "juste", pas sur 1.8 seconde */ 
                          	tsync=time(NULL);
                          	while(time(NULL)-tsync<1);
                          	
                          	tend=time(NULL)+DELAY;
                          	do {
                          		if(GetKeyState(KEY) & KEY_IS_PRESSED) {
                          			if(key_has_been_released) {
                          				npressed++;
                          				key_has_been_released=false;
                          			}
                          		}
                          		else
                          			key_has_been_released=true;
                          	} while(time(NULL)<tend);
                          	
                          	printf("key has been pressed %d times\n",npressed);
                          
                          	return(0);
                          }

                          -
                          Edité par edgarjacobs 28 janvier 2020 à 17:43:36

                          • Partager sur Facebook
                          • Partager sur Twitter

                          On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                            29 janvier 2020 à 15:23:12

                            Ouah merci ça a l'air de fonctionner 

                            par contre j'ai vraiment rien compris mais je vais faire des recherches :))

                            • Partager sur Facebook
                            • Partager sur Twitter

                            Compter les pressions sur une touche en X secondes

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown