Exploration de XNA : s'amuser avec les gamepad | 4 vote(s)
Par Emmanuel Deloget, mercredi 2 janvier 2008 à 20:00 :: Exploration de XNA :: permalien #105
Tags: C#, game programming, xna
Nous continuons notre série sur XNA en parlant maintenant du GamePad, ce magnifique ustensile livré en standard avec la XBox 360 et vous permettant de contrôler celle-ci. Mais que les amateurs de jeu PC ne s'y trompent pas: grâce en est rendue à la politique commerciale de Microsoft, car le GamePad est aussi disponible pour PC.
[Télécharger Visual C# 2005 Express Edition] [Télécharger XNA Game Studio 2.0] [Télécharger le Service Pack 1 pour VC# 2005 EE] [TorqueX, de GarageGames.com] [XNA Resources] [Forum MSDN XNA Game Studio] [GameDev.Net - Plenty of 1s and 0s]
Bien, la souris, c'est marrant quelques minutes, mais ça ne marche pas lorsque le programme fonctionne sur une console XBox 360. Sur une console, le principal système permettant les entrées utilisateur reste le contrôleur de la XBox, le GamePad (ou pad). Et bien entendu, XNA propose les interfaces et types nécessaires à l'utilisation du GamePad - non seulement sur la console, mais aussi sur PC, grâce à la version Windows de ce contrôleur (disponible en version filaire et sans fil[1]).
On peut se poser la question de l'intérêt d'avoir un GamePad connecté à un PC Windows. Outre le fait que le contrôleur reste relativement simple d'utilisation, il permet aussi de tester la jouabilité de votre jeu XBox 360 sans avoir à télécharger celui-ci sur la console. Il en résulte un gain de temps non négligeable pendant le cycle de développement.
Mode immédiat, le retour...
Bien évidemment, et comme précisé dans l'article précédent, les acquisitions en provenance du GamePad sont immédiate - c'est à dire qu'on récupère l'état actuel du contrôleur, et non pas l'historique de ce qui s'est passé depuis la dernière lecture. Cela a son importance, notamment si votre jeu devient plus lent : dans ce cas, vous pouvez manquer des actions utilisateurs, donnant à celui-ci l'impression que votre jeu ne traite pas correctement ses décisions. Ce problème devient particulièrement important dès lors que vous souhaitez gérer des combinaisons de touches - par exemple pour déclencher les coups spéciaux dans un jeu de combat. Un joueur expérimenté peut effectuer des combinaisons de touches très rapidement - mais si vous perdez ne serait-ce qu'une seule touche intermédiaire, il est plus que probable que ce joueur aura alors à cœur de vous maudire sur trois générations.
Récupération de l'état courant du pad.
La classe Microsoft.Xna.Framework.Input.GamePad, qui permet de récupérer l'état d'un pad particulier, définit 3 méthodes statiques. Chacune d'entre elle prends en paramètre une énumération du type Microsoft.Xna.Framework.Input.PlayerIndex, qui peut prendre la valeur PlayerIndex.One, PlayerIndex.Two, PlayerIndex.Three ou PlayerIndex.Four. Le framework permet ainsi de gérer jusqu'à 4 GamePad en même temps.
GetCapabilities(PlayerIndex playerIndex)permet de récupérer une structure du typeGamePadCapabilities. L'instance récupérée peut être ensuite analysée pour déterminer les capacités du pad en question.SetVibration(PlayerIndex playerIndex, float leftMotor, float rightMotor)permet de changer la vitesse de rotation des deux moteurs du pad (si le pad le supporte) renvoie un booléen mis à true si la requète a été traitée correctement. Pour arrêter la rotation sur un des moteurs, il suffit d'appeler la fonction et de lui passer une vitesse nulle (0.0f) pour le moteur sélectionné. Attention : la vitesse de rotation d'un moteur ne change pas tant queSetVibration()n'est pas appelée de nouveau.- Enfin,
GetState()renvoie une structureGamePadStatequi contient l'état courant du GamePad. Cette fonction est surchargée et existe sous deux formes:GamePad.GetState(PlayerIndex, GamePadDeadZone)permet de récupérer l'état d'un GamePad en spécifiant la façon dont la zone morte (Dead Zone) doit être interprétée.GamePad.GetState(PlayerIndex)est la forme simple. Elle correspond à la fonction précédente appelée avecGamePadDeadZone.IndependentAxes.
Une zone morte ?
J'en entends déjà quelques un qui s'écrient : "ouh là là: qu'est-ce donc encore que cette histoire de Dead Zone ?".
Les GamePad et autres joystick sont des périphériques mécaniques et qui dit mécanique dit "avec une certaine précision". Lorsqu'on manipule la manette analogique, un signal électrique est généré et convertit en signal numérique afin d'être interprété par le système. Le problème est que le manque de précision mécanique mêlé aux autres caractéristiques mécaniques du périphérique font que lorsque la manette est au repos, un signal électrique peut être généré quand même, provoquant une série d'acquisition là ou le joueur s'attend à n'avoir aucune réaction du jeu. Afin de palier à ce problème, on définit une zone appelée zone morte : si la manette est dans cette zone morte, on écarte toutes les entrées qui pourrait être acquise.
Il y a deux sortes de zones mortes :
GamePadDeadZone.IndependentAxes: une croix qui couvre les axes du manche (|x| < Kx ou |y| < Ky). Des petits déplacement autour de x=0 ou y=0 n'auront pas d'effet. Ce type de paramétrage convient bien à un Shoot'em up, ou l'on doit différentier les positions sur le mode "je vais à droite ou je vais à gauche". Par contre, cela ne convient pas à un jeu ou l'on a besoin d'un contrôle un peu plus fin : la manette analogique est effectivement séparée en 4 quadrants séparés par une bande certes fine, mais présente. De fait, la distance du point courant par rapport au centre du pad n'a que peu d'intérêt puisque dès qu'on entre dans une de ces bandes, cette distance est faussée par le fait qu'on considère une des coordonnées comme étant nulle.GamePadDeadZone.Circularun disque autour de la position neutre (x² + y² < K²). Il faut alors s'éloigner suffisament de la position neutre pour voir le système réagir. Ce type d'interaction corresponds bien à un jeu de plateforme ou le moindre déplacement du pad doit être traduit par une déplacement du personnage à l'écran. On peut alors prends en compte non seulement la direction choisie par le joueur mais aussi la distance par rapport au centre du pad.
Il est bien évidemment possible de spécifier une zone morte inexistante (de manière à implémenter son propre traitement) en spécifiant GamePadDeadZone.None.
Mais, et cet état...
On y vient, on y vient.
La structure GamePadState renvoyée par GamePad.GetState() définit les propriétés suivantes :
GamePadState.IsConnected: ce booléen est à true si la manette correspondante est connectée au système. On peut ainsi vérifier la présence de manette en temps réel.GamePadState.Buttonsnous donne l'état des boutons (A, B, X, Y, Start, Back, les 2 bumpers (gauche et droit) et les deux sticks). Chacun de ces boutons peut être dans l'étatButtonState.PressedouButtonState.Released.GamePadState.DPadnous donne l'état des boutons unidirectionnels (le Directional Pad, ou DPad). Au plus 2 directions adjacentes parmi les quatre directions possibles peuvent être à l'étatButtonState.Pressed, les autres restant à l'étatButtonState.Released.GamePadState.Triggersrenseigne sur l'état des gachettes (triggers) droite (Triggers.Right) et gauche (Triggers.Left). Les triggers sont des variables flottantes codées de 0 à 1. 1 correspond au cas ou le trigger est totalement enfoncé.- Enfin,
GamePadState.ThumbSticksnous donne l'état des deux manches analogiques droit (GamePadState.ThumbSticks.Right) et gauche (GamePadState.ThumbSticks.Left). Cette information nous est donnée sous la forme d'une structureVector2. On peut donc récupérer les coordonnées X, Y et la distance par rapport à la position neutre de la manette de pouce.
Et ça s'utilise comment tout ça ?
Et bien, ça s'utilise très simplement - comme les autres entrées utilisateur, que ce soit le clavier ou la souris. Le principe consiste à vérifier l'état des pad dans la méthode Game1.Update() et d'effectuer les traitements basés sur l'état des boutons et autre manettes de pouce.
On verra dans les articles subséquents comment généraliser le système de capture d'entrée de manière à laisser l'utilisateur les personnaliser.
Conclusion
Cet article est court, mais bref[2]. A noter que le site XNA Creators Club offre en téléchargement des fichiers graphiques librement utilisables représentant les boutons des manettes XBox 360 ou la manette elle même. Le but est bien évidemment de vous en servir pour afficher les contrôles de votre jeu ou programme à l'écran, afin d'en faciliter la prise en main.
A bientôt !
Commentaires
Aucun commentaire pour le moment.
:: Fil rss des commentaires de ce billet ::
Ajouter un commentaire