Tutoriel XNA 2 : Gérer les contrôles utilisateurs

xna_logo

Dans ce nouveau tutoriel, nous allons voir comment gérer les contrôles utilisateur sur Xbox360 et PC (les touches du clavier et les boutons de la manette).

Si vous êtes débutant ou que vous faites vos premiers pas sur Visual Studio ou XNA, je vous invite à suivre le premier tutoriel de notre série, à l’adresse suivante :

http://www.ghaundan.fr/2011/04/tutoriel-xna-1-afficher-une-image/

Sinon, bon courage ! N’hésitez pas à poster un commentaire pour toute suggestion ou question vis à vis du tutoriel.

Tout d’abord, un petit rappel : notre programme XNA est comme une énorme boucle while, qui va se répéter tout au long de la vie de notre application. Tous les événements devront donc êtres testés à chaque itération. Si vous avez encore un peu de mal avec ce principe, direction le tutoriel numéro 1. (Voir lien dans l’en-tête de l’article)

 

Première étape : Définition des différents outils disponibles

Il existe deux classes disponible dans XNA pour gérer les actions des utilisateurs :

  • Une pour le clavier, KeyboardState
  • Une pour les manettes, GamePadState

1. La classe KeyboardState

Qu’est-ce que la classe KeyboardState ? C’est une classe qui va donner une représentation du clavier. Heureusement pour nous, l’objet qui correspond à cette classe est géré directement par notre programme et accessible via :

Keyboard.GetState()

Cette méthode renvoi un objet de type KeyboardState.

 

Pour tester si une touche est appuyée, une méthode est prévue dans notre objet de type KeyboardState :

Keyboard.GetState().IsKeyDown(Keys aKey)

La méthode isKeyDown() prend en argument un enum contenu dans Keys et accessible via celui ci, et va retourner un booléen. Ainsi pour tester si la touche espace est appuyée, je vais utiliser :

Keyboard.GetState().IsKeyDown(Keys.Space)

Cette instruction me retournera true si la touche est appuyée, et false si elle n’est pas appuyée.

Fonctionnant de la même manière, la méthode IsKeyUp() est également disponible dans la classe KeyboardState. (Elle va tester si au contraire la touche est relevée)

2. La classe GamePadState

Cette classe fonctionne de la même façon que la classe KeyboardState à une nuance près : chaque manette est gérée indépendament. En effet si sur un PC un seul clavier et une seule souris peuvent être branchés, sur la Xbox360 nous pouvons mettre 4 manette. Il faut donc demander à XNA de nous fournir l’état d’une manette particulière.

Pour obtenir le GamePadState de la manette 1, nous utiliserons :

GamePad.GetState(PlayerIndex.One)

PlayerIndex est un enum qui contient les indices des joueurs 1, 2, 3 et 4. Il suffit de passer en paramètre à la méthode GetState de GamePad le PlayerIndex du joueur souhaité pour obtenir l’état de sa manette.

Pour tester si le bouton A est appuyé, nous allons utiliser :

GamePad.GetState().IsButtonDown(Buttons.A)

Buttons est un enum qui contient toutes les touches de la manette.

Pour effectuer des contrôles sur la position du stick, c’est un peu plus compliqué, mais rien d’effrayant. Nous pouvons accéder à la position de chaque stick de la manette via :

GamePad.GetState(PlayerIndex.One).ThumbSticks.Left

Ceci nous retournera un objet de type Vector2, représentant la position du stick sur un axe X/Y.

Représentation de l'axe X et Y sur un stick d'une manette Xbox360

 

 

Qu’est ce que la classe Vector2 ? La classe Vector2 va nous permettre de stocker une information spatiale sur un plan 2D. Le Vector2 contient deux propriétés pour se situer: X et Y, accessibles de cette manière :

Vector2 monVecteur = new Vector2(12, 7);
monVecteur.X; // valeur de X du vecteur, ici 12
monVecteur.Y; // valeur de Y du vecteur, ici 7

Nous pouvons donc acceder aux valeurs de X et Y d’un des deux sticks en utilisant :

GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.X;
GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.Y;

Deuxième Etape : Ecriture du code dans la méthode Update

Il faut à présent tester ce que nous avons appris en direct dans notre application. Pour cela nous allons placer notre code dans la méthode Update de notre programme XNA. Pour tester les entrées utilisateur, nous allons faire changer de couleur la fenêtre XNA par défaut lorsque l’utilisateur appuie sur la touche espace.

Je vous rappelle que la couleur de fond de l’application XNA par défaut est un bleu clair, Color.CornflowerBlue. Le fond est définit dans la méthode Draw() :

GraphicsDevice.Clear(Color.CornflowerBlue);

Nous allons changer le fond en rose fuchsia lorsque l’utilisateur appuie sur Espace. Nous pouvons définir ce magnifique rose via Color.Fuchsia. Il va donc falloir définir une variable qui va prendre soit la valeur du bleu par défaut, soit la valeur du rose si une touche est appuyée.

 

1. La méthode Draw

Nous allons sortir la valeur du paramètre passé en argument à la méthode Clear() du GraphicsDevice en dehors de la méthode Draw(), afin qu’elle puisse changer sans que nous ayons à écrire de condition dans notre méthode Draw. En effet, il faut alléger le plus possible notre code dans cette méthode car elle doit servir uniquement à dessiner.

Nous allons donc définir une variable de type Color en dehors de notre méthode Draw() et lui donner comme valeur par défaut le bleu ciel:

Color backgroundColor = Color.CornflowerBlue;

Maintenant, dans notre méthode Draw(), nous allons passer la couleur que nous venons de définir en argument à Clear()

 

GraphicsDevice.Clear(this.backgroundColor);

Et voici le code de base modifié :

Color backgroundColor = Color.CornflowerBlue;
protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(this.backgroundColor);
    // TODO: Add your drawing code here
    base.Draw(gameTime);
}

 

 

2. La méthode Update

Nous allons maintenant modifier notre variable backgroundColor en fonction de la touche appuyée par l’utilisateur. Si la touche espace est enfoncée, nous passons la variable backgroundColor au rose Fuchsia, sinon nous la remettons au bleu ciel.

if (Keyboard.GetState().IsKeyDown(Keys.Space))
{
    this.backgroundColor = Color.Fuchsia;
}
else
{
    this.backgroundColor = Color.CornflowerBlue;
}

Et voilà, rien de plus simple ! Voici le code complet de la méthode Update() :

protected override void Update(GameTime gameTime)
{
    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit();

    // TODO: Add your update logic here
    if (Keyboard.GetState().IsKeyDown(Keys.Space))
    {
        this.backgroundColor = Color.Fuchsia;
    }
    else
    {
        this.backgroundColor = Color.CornflowerBlue;
    }
    base.Update(gameTime);
}

Et le code complet de notre fichier Game1.cs :

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace WindowsGame1
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>

        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here
            if (Keyboard.GetState().IsKeyDown(Keys.Space))
            {
                this.backgroundColor = Color.Fuchsia;
            }
            else
            {
                this.backgroundColor = Color.CornflowerBlue;
            }
            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        Color backgroundColor = Color.CornflowerBlue;
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(this.backgroundColor);

            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }
}

Maintenant vous pouvez tester votre application en appuyant sur la touche F5, et lorsque vous appuierez sur la touche espace, vous obtiendrez le résultat suivant :

Un magnifique rose

Dans le prochain tutoriel, nous verrons comment afficher du texte à l’écran en utilisant n’importe quelle font.

 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>