• 24 Avril 2025, 00:32:32


Auteur Sujet: Action lors du maintien d'une touche  (Lu 2228 fois)

0 Membres et 1 Invité sur ce sujet

Hors ligne Jens84

  • *
  • Tueur
  • Pawn un jour, Pawn toujours
  • Messages: 71
    • Voir le profil
    • Mon Site Web
Action lors du maintien d'une touche
« le: 09 Novembre 2008, 10:48:06 »
Bonjour, je voudrais savoir comment, en utilisant (ou pas) la callback "OnPlayerKeyStateChange", je pourrais executer une action, si la touche définie dans la callback est maintenue pendant un certain temps donné.

Merci d'avance pour vos réponses.
Jens84
« Modifié: 11 Novembre 2008, 12:21:44 par Jens84 »
Serveur non-terminé  (MAJ Quotidiennes)


Hors ligne S!m

  • *
  • Messages: 2341
    • Voir le profil
Re : Action lors du maintien d'une touche
« Réponse #1 le: 09 Novembre 2008, 16:50:12 »
Salut,

malheureusement, pour faire ce que tu veut,

il faut utiliser un timer et un GetPlayerKeys,

comme son nom l'indique, la callback OnPlayerKeyStateChange est appelé quand le joueur CHANGE de touche

++Sim++





Hors ligne Jens84

  • *
  • Tueur
  • Pawn un jour, Pawn toujours
  • Messages: 71
    • Voir le profil
    • Mon Site Web
Re : Action lors du maintien d'une touche
« Réponse #2 le: 11 Novembre 2008, 12:23:30 »
Ok pour la callback je comprends. Cependant je ne vois pas comment on peut utiliser un timer pour faire mon action, car un timer sert bien à exécuter une action au bout d'un certain temps, je ne vois pas comment l'utiliser autrement pour effectuer mon action...

Merci pour vos réponses !
Serveur non-terminé  (MAJ Quotidiennes)


Hors ligne [StAfF]MaN

  • [StAfF] forever ^^
  • *
  • Gangster
  • [StAfF] un jour, [StAfF] toujours ^^ !!!
  • Messages: 1040
    • Voir le profil
    • SITE [StAfF]
Re : Action lors du maintien d'une touche
« Réponse #3 le: 11 Novembre 2008, 12:35:07 »
En faite tu lance le timer quand le gars appuis sur la touche, et tu met en place une variable, si le joueur relâche la touche, la variable re bascule a 0 et arrêt le timer, ce qui fait que l'action ne se produit que si le joueur maintient la touche ^^ Happy !!!  :laugh
^v^v^v^v|
   StAfF  |                              IP: gtaunderground.No-Ip.org

^v^v^v^v|

Hors ligne Syg

  • Expert programmeur C/C++/PAWN
  • *
  • The GTAOnline Jesus
  • Messages: 3908
    • Voir le profil
Re : Action lors du maintien d'une touche
« Réponse #4 le: 12 Novembre 2008, 11:59:37 »
En utilisant un GetPlayerKeys et un timer, on risque de "tomber" dans le travers suivant :
Le joueur appuie sur la touche une fois puis il appuie une deuxième fois juste au moment où le timer s'éxécute. Pour le script, il ne fera pas la différence avec un appui long.
Pour éviter ce travers, il fadrait mettre un timer très court et compter le nombre de fois où on passe dedans. Et ceci pour chaque joueur. Pas commode et gourmand en ressource.

En fait il est très facile de la faire avec OnPlayerKeyStateChange :
Lorsque le joueur appuie sur la touche en question, on mémorise le moment où il l'a fait (avec la fonction gettime sous Linux ou mieux, GetTickCount sous Windows).
Pour ce faire, on test le paramètre newkeys pour savoir si c'est la bonne touche (on positionne un flag par exemple).
Lorsque le joueur relache la touche, OnPlayerKeyStateChange est appelé une nouvelle fois.
Il suffit alors de calculer la durée entre les deux appels à OnPlayerKeyStateChange et le tour est joué (on peut faire des tests sur newkeys pour voir si la touche a bien été relachée).

NB : La fonction GetTickCount (qui renvoie le nombre de miliseconde écoulées depuis le démarrage de la machine) est très pratique pour faire ce genre de chose et elle est très précise. Par contre, elle n'existe pas sous Linux. Mais on peut trouver des plugins qui émulent cette fonction.

++
Syg
Courtesy of GtaManiac

Hors ligne [StAfF]MaN

  • [StAfF] forever ^^
  • *
  • Gangster
  • [StAfF] un jour, [StAfF] toujours ^^ !!!
  • Messages: 1040
    • Voir le profil
    • SITE [StAfF]
Re : Action lors du maintien d'une touche
« Réponse #5 le: 12 Novembre 2008, 14:22:28 »
Heu le gettime marche aussi sous windows :p Je me suis servis pour mettre l'heure sur mon serveur ;)
^v^v^v^v|
   StAfF  |                              IP: gtaunderground.No-Ip.org

^v^v^v^v|

Hors ligne Jens84

  • *
  • Tueur
  • Pawn un jour, Pawn toujours
  • Messages: 71
    • Voir le profil
    • Mon Site Web
Re : Action lors du maintien d'une touche
« Réponse #6 le: 12 Novembre 2008, 16:27:04 »
Ok merci, je comprends à peu près et en effet, si le GetPlayerKeys est gourmand et (comme je le pensais ^^ : Eh oui ça m'arrive de penser XD) si on ne définit pas un temps court, il ne fait pas la différence entre un appui long et deux appuis courts aux bons moments, c'est mieux d'utiliser la callback OnPlayerKeyStateChange comme tu le dis Syg.

Je vois donc comment vérifier si newkeys est la bonne touche (avec une condition si je ne m'abuse : if(newkeys == KEY_FIRE){ par exemple) par contre je ne vois pas comment rappeller la callback quand la touche est relachée et je n'ai jamais utilisé GetTickCount donc je ne sais pas comment il fonctionne.

Pourrais-tu me détailler cette méthode Syg s'il te plait ?

Merci d'avance !
Jens84
« Modifié: 12 Novembre 2008, 16:29:15 par Jens84 »
Serveur non-terminé  (MAJ Quotidiennes)


Hors ligne Syg

  • Expert programmeur C/C++/PAWN
  • *
  • The GTAOnline Jesus
  • Messages: 3908
    • Voir le profil
Re : Action lors du maintien d'une touche
« Réponse #7 le: 12 Novembre 2008, 17:07:36 »
Tout d'abord, tu n'as pas besoin de rappeler la callback OnPlayerKeyStateChange, le moteur de SAMP va le faire tout seul pour toi, à chaque appui ou relachement d'une touche.

Ensuite, je n'ai jamais dit que gettime n'existait pas sous Windows, ce que je voulais dire c'est que gettime donne heures, minutes et secondes alors que GetTickCount donne des milisecondes (donc 1000 fois plus précis).

Pour le test sur newkeys, il faut passer par un masque, pas par une comparaison à l'égalité car newkeys peut contenir plusieurs codes touche à la fois.
if (newkeys & KEY_FIRE)
Pour la méthode, c'est facile, lors de l'appuie sur la touche voulue tu stockes l'instant à laquelle la touche est appuyée. Lors du relachement de la touche, tu fais la différence entre l'instant présent et l'instant stocké avant. Ceci te donne la durée d'appui sur la touche. Il ne reste plus qu'à comparer avec la durée voulue.

Pour n'importe quel serveur :
new Temps[MAX_PLAYERS];

public OnPlayerKeyStateChange (playerid, newkeys, oldkeys)
{
   new H, M, S;
   gettime (H, M, S);

   /* On vient d'appuyer sur la touche KEY_FIRE */
   if (newkeys & KEY_FIRE)
   {
      /* On stocke l'instant d'appui sur la touche */
      Temps[playerid] = H*3600 + M*60 + S;
   }

   /* On vient de relacher la touche KEY_FIRE */
   else if (oldkeys & KEY_FIRE)
   {
      /* On stocke l'instant de relachement de la touche */
      Temps2 = H*3600 + M*60 + S;

      /* Si appui assez long (supérieur à 5 secondes) */
      if (Temps2-Temps[playerid] > 5)
      {
          /* Tu fais ce que tu as à faire */
      }
   }
}

Pour un serveur sous Windows (seulement) :
new Temps[MAX_PLAYERS];

public OnPlayerKeyStateChange (playerid, newkeys, oldkeys)
{
   /* On vient d'appuyer sur la touche KEY_FIRE */
   if (newkeys & KEY_FIRE)
   {
      /* On stocke l'instant d'appui sur la touche */
      Temps[playerid] = GetTickCount ();
   }

   /* On vient de relacher la touche KEY_FIRE */
   else if (oldkeys & KEY_FIRE)
   {
      /* On stocke l'instant de relachement de la touche */
      new Temps2 = GetTickCount ();

      /* Si appui assez long (supérieur à 5 secondes) */
      if (Temps2-Temps[playerid] > 5000)
      {
          /* Tu fais ce que tu as à faire */
      }
   }
}

Attention, pour la première version (sans GetTickCount), il faut gérer le passage à minuit si on veut faire les chose correctement. Effectivement, si le joueur appuie sur la touche à 23:59:58 et la relâche à 00:00:04, il se sera passé plus de 5 secondes mais le script ne le verra pas car la différence entre les deux temps sera négative vu qu'on repasse à 0.
23:59:58 -> 23*3600+59*60+58 = 86398 (Temps[playerid] dans le script)
00:00:04 -> 00*3600+00*60+04 = 4 (Temps2 dans le script)
4 - 86398 = -86394 (qui n'est bien évidement pas supérieur à 5).

Mais bon, la gestion du passage à minuit n'est pas indispensable.

++
Syg
Courtesy of GtaManiac

Hors ligne S!m

  • *
  • Messages: 2341
    • Voir le profil
Re : Action lors du maintien d'une touche
« Réponse #8 le: 13 Novembre 2008, 00:38:07 »
Salut,

et j'ajouterais un cours sur le symbole '&' de notre maitre à tous Syg:

http://www.gtaonline.fr/forums/index.php/topic,3916.0.html

++Sim++





Hors ligne Jens84

  • *
  • Tueur
  • Pawn un jour, Pawn toujours
  • Messages: 71
    • Voir le profil
    • Mon Site Web
Re : Action lors du maintien d'une touche
« Réponse #9 le: 13 Novembre 2008, 07:30:48 »
Merci beaucoup Syg, on remarque un vrai professionnel en la matière, et c'est bien ton cas !
Il me semblait bien avoir dit une conner** avec mon if(newkeys == KEY_FIRE){ car j'utilise assez OnPlayerKeyStateChange et je connais donc la bonne formule XD.
Ben en tout cas merci beaucoup, je testerai ça ce soir !

A bientôt !
Jens84
Serveur non-terminé  (MAJ Quotidiennes)


Hors ligne [StAfF]MaN

  • [StAfF] forever ^^
  • *
  • Gangster
  • [StAfF] un jour, [StAfF] toujours ^^ !!!
  • Messages: 1040
    • Voir le profil
    • SITE [StAfF]
Re : Action lors du maintien d'une touche
« Réponse #10 le: 13 Novembre 2008, 12:01:59 »
A chaque fois que syg explique je reste sur le cul xD C'est impressionnant on vois bien que c'est ton domaine a 100% ;)
^v^v^v^v|
   StAfF  |                              IP: gtaunderground.No-Ip.org

^v^v^v^v|