MTProd > Dev4all > Articles > APIs > DirectX > Votre premier jeu Windows - C++/DirectX > 8 input.h
Rechercher13 Personnes en-ligne
Votre premier jeu Windows - C++/DirectX

8  input.h

Nous allons voir dans ce chapitre trois fonctions DirectInput utilisées pour gérer nos périphériques (clavier et souris).
Les autres fonctions se chargent d'initialiser, gérer et "libérer" nos périphériques DirectInput, elles sont "trop complexes" pour l'instant, je tiens surtout à ne pas trop vous "bourrer" le crâne pour l'instant, nous reviendrons en détails sur la gestion de DirectInput dans un article futur.
Les deux "sous chapitres" qui suivent tenterons d'éxpliquer comme fonctionne le clavier et la souris, ainsi que la manière que nous avons utilisée pour lire et stocker les enfoncements et relachements de touches et de boutons.



8.1  Boutons et axes

Un bouton est un commutateur qui a deux positions : ouvert (on) et fermé (off). DirectInput ne fait aucune distinction entre les boutons, qu'ils se trouvent sur une souris, un clavier, une manette ou sur une tablette de jeu (game pad).
La plupart des souris ont deux axes, et certaines trois. Par défaut, les axes se comportent tous de la même manière.

La souris est un animal qui bouge ; elle peut aller aussi loin qu'elle veut, dans toutes les directions. Il est donc naturel que, par défaut, DirectInput considère les axes de la souris comme relatifs.
Lors de l'acquisition du périphérique, DirectInput affecte une valeur arbitraire à la position de chaque axe. Lorsque DirectInput lit les données d'un axe, celles-ci sont exprimées par rapport à la dernière position connue. La valeur initiale n'est pas forcément 0 ; il faut donc mémoriser cette valeur initiale afin d'avoir quelque chose à comparer avec la valeur courante.
Les déplacements de la souris fonctionnent de la manière suivante : les déplacements vers la gauche (ceux qui s'éloignent de l'utilisateur) sont négatifs et ceux vers la droite (ils se rapprochent de l'utilisateur) sont positifs.
En résumé, nous comparons les coordonnées de la dernière position connue (figure 8.1.1, temps a) aux coordonnées de la position actuelle (figure 8.1.1, temps b).



Figure 8.1.1: Déplacements de la souris





8.2  Stocker et lire les boutons

Si vous ne connaissez pas les opérations binaires, je vous conseil vivement de lire l'article Opération Binaire qui traite justement de ce sujet

Voilà, notre fonction ReadKeyboardInput() (pour le clavier) et ReadMouseInput() (pour la souris) se chargent de lire les boutons appuyés ou non et renvoit l'êtat de ces derniers. Nous utilisons alors la DoKeyboardInput() et DoMouseInput() pour effectuer les actions désirées.
Chaque bouton est représenté par une valeur hexadécimale d'un octet (char (octet signé de -127 à 127) ou BYTE (octet non signé de 0 à 255)), nous allons stocker ces valeurs dans une variable de type DWORD soit 32 octets non signés, nous pourrons donc stocker 32 touches simultanément.
Nous devons donc donner une valeur hexadécimale unique à chaqu'un de nos boutons, nous le faisons par l'intermédiaire de macros définit dans notre fichier globals.h comme ceci :

#define KEY_ESCAPE                0x00000001l
#define KEY_UP                    0x00000002l
#define KEY_DOWN                0x00000004l
#define KEY_LEFT                0x00000008l
#define KEY_RIGHT                0x00000010l
#define KEY_ENTER                0x00000020l
#define KEY_CONTROL                0x00000040l
#define KEY_S                    0x00000080l
#define KEY_L                    0x00000100l
#define KEY_ADD                    0x00000200l
#define KEY_SUBTRACT            0x00000400l
#define KEY_SPACE                0x00000800l
#define KEY_SHIFT                0x00001000l
#define BUTTON_LEFT                0x00000001l
#define BUTTON_RIGHT            0x00000002l

Regardons notre premier macro KEY_ESCAPE, il vaut 0x00000001 (le l pour long, norme ANSI) soit 1.
Le deuxième KEY_UP vaut 0x00000002 soit 2, le troisième : 4, puis 8, 16, 32, 64, 128, 256, etc. Chaque bouton a donc une valeur unique.
Lorsqu'un bouton est enfoncé nous utilisons l'opérateur binaire OR afin de stocker la valeur du bouton.
Lorsqu'un bouton n'est pas enfoncé nous utilisons l'opérateur binaire AND et ~ (tilde) afin de "déstocker" la valeur du bouton.

Voyons maintenant comment interpreter et gérer les actions pour nos différents boutons.




8.3  DoKeyboardAction()

Listing 8.3.1 : DoKeyboardAction()
(
ouvrir dans une nouvelle fenêtre)

 1  void DoKeyboardAction( void )
 2  {
 3      DWORD            key;
 4      key = ReadKeyboardInput();
 5  
 6      // Rotation droite
 7      if ( key & KEY_RIGHT )
 8          balle.dir += 1;
 9  
 10      // Rotation gauche
 11      else if ( key & KEY_LEFT )
 12          balle.dir -= 1;
 13  
 14      // Vérifie les dépassements de directions
 15      // Si la direction est inférieure à zéro, par exemple "-1" nous ajoutons le nombre de directions (NBRE_DIRS) à la direction actuelle, par exemple pour "-1 + 40" cela nous donnera "39" l'objet à fait un tour
 16      if ( balle.dir < 0 )
 17          balle.dir += NBRE_DIRS;
 18  
 19      // La meme chose qu'avant mais à l'inverse
 20      else if ( balle.dir >= NBRE_DIRS )
 21          balle.dir -= NBRE_DIRS;
 22  
 23      // On avance
 24      if ( key & KEY_UP )
 25      {
 26          balle.posX += dirX[balle.dir];
 27          balle.posY += dirY[balle.dir];
 28      }
 29  
 30      // On recule
 31      else if ( key & KEY_DOWN )
 32      {
 33          balle.posX -= dirX[balle.dir];
 34          balle.posY -= dirY[balle.dir];
 35      }
 36  
 37      // L'utilisateur désire quitter l'application
 38      if ( key & KEY_ESCAPE )
 39          PostMessage(hWnd, WM_CLOSE, 0, 0);
 40  }


Cette fonction se charge des actions à effectuer lors de l'appuie d'une touche au clavier, elle est de type void (donc ne retourne rien) et n'a pas d'arguement.
Ligne 3, nous définissons une variable de type DWORD afin de lire le status des touches que nous optenons grâce à la fonction ReadKeyboardInput() en ligne 4.
Lignes 7 à 35 nous gérons les rotations et déplacements de notre objet balle, pour plus d'informatons sur ces opérations, consulter l'article Déplacements & Directions dans un jeu 2D.
Remarquez juste que nous utilisons l'opérateur AND afin de lire l'état des boutons et ainsi définir s'il est enfoncé ou non.
Ligne 38, si le bouton KEY_ESCAPE est enfoncé, nous postons un message Windows (géré par WindowProc(), voir chapitre 3) grace a la fonction PostMessage(), qui prend les arguments suivant :

  1. HWND hWnd : L'handle de la fenêtre recevant le message, ici hWnd

  2. UINT Msg : Le message à poster, ici WM_CLOSE qui aura pour effet de fermer notre application

  3. WPARAM wParam : Message additionel

  4. LPARAM lParam : Message additionel






8.4  DoMouseAction()

Listing 8.4.1 : DoMouseAction()
(
ouvrir dans une nouvelle fenêtre)

 1  void DoMouseAction( void )
 2  {
 3      DWORD            button;
 4  
 5      button = ReadMouseInput();
 6  
 7      //    if ( button & BUTTON_LEFT )
 8  }


Cette fonction, comme la précédente ne prend pas d'argument et ne retourne rien.
Elle se limite pour l'instant à lire le status des boutons de la souris avec la fonction ReadMouseInput(), ligne 5 et la place dans la variable button déclaré en ligne 3.
Ligne 7, il s'agit d'un commentaire, il montre comment tester si un bouton est enfoncé ou non.




8.5  UpdateCursorPos()

Listing 8.5.1 : UpdateCursorPos()
(
ouvrir dans une nouvelle fenêtre)

 1  void UpdateCursorPos( int x, int y )
 2  {
 3      cursor.x += x;
 4      cursor.y += y;
 5  
 6      // clip le curseur
 7      if ( cursor.x < 0 )
 8          cursor.x = 0;
 9      if ( cursor.x >= RES_X )
 10          cursor.x = RES_X-1;
 11      if ( cursor.y < 0 )
 12          cursor.y = 0;
 13      if ( cursor.y >= RES_Y )
 14          cursor.y = RES_Y-1;
 15  }


Cette fonction ne retourne rien, elle s'occupe uniquement de mettre à jour la position du curseur de notre souris, elle prend les arguments suivant :

  1. int x : Nouvelles coordonnées de la souris par rapport aux dernières coordonnées enregistrées sur l'axe X (horizontal)

  2. int y : Nouvelles coordonnées de la souris par rapport aux dernières coordonnées enregistrées sur l'axe Y (vertical)


Ligne 3 et 4, nos deux coordonnées (x et y) sont incrémentés à la position actuelle de la souris.
Lignes 7 à 14 nous testons si le curseur est hors de l'écran :

  • Ligne 7 : est-ce que la position X de notre curseur est plus petite que 0 ? Si oui nous fixons (ligne 8) sa position X à 0 (tout a gauche de l'écran)

  • Ligne 9 : est-ce que la position X de notre curseur est plus grande ou égale à la longueur de l'écran (RES_X) ? Si oui nous fixons (ligne 10) sa position X à la longueur de l'écran (RES_X) - 1 (tout a droite de l'écran)

  • Ligne 11 : est-ce que la position Y de notre curseur est plus petite que 0 ? Si oui nous fixons (ligne 12) sa position Y à 0 (tout en haut de l'écran)

  • Ligne 13 : est-ce que la position Y de notre curseur est plus grande ou égale à la hauteur de l'écran (RES_Y) ? Si oui nous fixons (ligne 14) sa position Y à la hauteur de l'écran (RES_Y) - 1 (tout en bas de l'écran)







<<  7  fonctions.hSommaire9  Conclusion  >>

 Accés rapide

1  Introduction
2  Les fichiers et répertoires
3  WindowProc()
4  InitApp()
5  WinMain()
6  UpdateFrame()
7  fonctions.h
8  input.h

Boutons et axes

Stocker et lire les boutons

DoKeyboardAction()

DoMouseAction()

UpdateCursorPos()

9  Conclusion
Voir le sommaire complet

 Liens utiles

  • Publier un article
  • Envoyer cette page
  • Ecrire à l'auteur

  •  Mini-Chat

    Thienou (00h11): salut
    Thienou (00h13): Oula mon inscription date de 11 ans je me sent vieux :)
    neowolf25 (17h59): MMF2 en "pay what you want" jusqu'à demain sur
    neowolf25 (17h59): https://www.hu
    mblebundle.com/
    weekly

    Miuka (21h15): Coin coin de 2014
    Miuka (21h15): Des gens qui ont migré sur le forum Clickteam ou ailleurs ?
    Strike (09h45): Salut les vieux !
    Hikarion (12h46): Salut les djeunz
    Hikarion (13h38): A qui profite le scandale ?
    Hikarion (13h44): le chat irc est toujours actif ?

    Votre message



     Archives

     Dev4all Newsletter

    Restez à jour avec la newsletter mensuelle !

    Votre e-mail


    1800 abonnés

     Recommander Dev4all

    Recommandez Dev4all à un ami. Cela fera grandir notre communauté !

    E-mails de vos amis




    [ Accueil | S'inscrire | Mon Dev4all | Communauté | Téléchargements | Articles | Forums | Chat ]

    [ A propos de Dev4all | Aide | La charte Dev4all | Contact ]

    © 2000-2018 MTProd. Tous droits réservés.
    L'utilisation de Dev4all implique l'acceptation et le respect de la charte Dev4all.