[Tutoriels XNA] – 2D – Gérer le clavier et la souris

Introduction

 

Dans ce nouveau chapitre sur le Framework XNA 3.1, nous allons apprendre à gérer le clavier et la souris. C’est une étape importante de notre apprentissage, car ce sont les seuls moyens d’interagir avec votre jeu.

 

Le clavier

 

Gérer le clavier en XNA est relativement simple. En effet, le Framework XNA 3.1 nous fournit tout le nécessaire pour l’utiliser. Nous aurons besoin des classes Keyboard et KeyboardState, ainsi que de l’énumération Keys. Keyboard nous servira à récupérer différentes informations sur le clavier de façons statiques. KeyboardState permettra d’avoir une image de l’état du clavier à un instant T, et Keys est l’énumération qui nous permettra de spécifier quelle touche gérer.

Récupérer les entrées utilisateurs est la première étape de notre « boucle infinie ». Nous allons donc effectuer cette étape dans la méthode Update de notre classe Game. Cette méthode se présente ainsi :

 

clip_image002

 

Vous allez supprimer les deux premières lignes de code de la méthode, qui nous sont inutiles pour l’instant. Nous devons avoir ceci désormais :

 

clip_image004

 

Attaquons le vif du problème maintenant. Pour commencer, déclarez un objet de type KeyboardState au niveau de notre classe Game :

 

clip_image006

 

Ensuite, au début de votre méthode Update, insérez cette ligne de code :

 

clip_image008

 

Explication : nous récupérons l’état du clavier à cet instant T à partir de la méthode statique GetState() de la classe Keyboard. Nous aurons ainsi une image des touches pressées à cet instant précis. Voici comment tester si une touche est pressée (exemple avec la lettre A) :

 

clip_image010

 

Insérez ces lignes de code juste après la récupération de l’état du clavier, dans la méthode Update. Vous pouvez procéder ainsi pour n’importe quelle touche.

 

La souris

 

Il n’est guère plus compliqué de gérer la souris en XNA. A la place des classes Keyboard et KeyboardState, nous avons les classes Mouse et MouseState, dont nous nous servirons de la même manière.

Déclarez un objet de type MouseState au niveau de votre classe :

 

clip_image012

 

Ensuite, dans la méthode Update, rajoutez cette ligne de code après la récupération de l’état du clavier :

 

clip_image014

 

Idem que pour le clavier, on récupère l’état de la souris à ce moment précis, qui nous permettra de garder une image des états des boutons de la souris, ainsi que de sa position. Pour tester si nous avons effectué un clic gauche avec la souris, voici comment nous procédons :

 

clip_image016

 

Vous pouvez procéder de la même manière pour les autres boutons de la souris.

Pour récupérer la position de notre souris, nous procédons comme ceci :

 

clip_image018

 

Pour placer la souris à une position précise, nous faisons comme cela :

 

clip_image020

 

Conclusion

 

Nous voici à la fin de ce nouveau chapitre. Même s’il semble court et relativement simple, il n’en reste pas moins très important, car les entrées utilisateurs sont à la base de toute interaction entre le joueur et l’environnement du jeu. Dans le prochain chapitre, nous allons utiliser ce que nous venons d’apprendre pour faire bouger des sprites à l’aide du clavier et de la souris !

XNA

[Tutoriels XNA] – 2D - Dessiner une image

Introduction

 

Dans ce nouveau chapitre, nous allons apprendre à afficher une image en 2D, étape indispensable à toute réalisation de jeux-vidéo.

 

Charger une image avec XNA 3.1

 

Pour afficher une image, nous avons besoin de deux classes différentes : SpriteBatch et Texture2D. Si vous vous souvenez bien, dans le chapitre précédent, nous avons pu apercevoir un objet de type SpriteBatch dans le code par défaut fournit par le Framework XNA 3.1. Il va servir à afficher une image à l’écran, en spécifiant la position, la partie de l’image à afficher, la taille, etc... Notre deuxième objet de type Texture2D va nous servir, lui, à charger notre image et pouvoir la garder en mémoire.

Pour commencer, déclarez au niveau de votre classe un objet de type Texture2D comme suit :

 

clip_image002[1]

 

Pour charger l’image, tout se passe dans la méthode LoadContent de votre classe Game. Mais avant de pouvoir la mettre en mémoire à l’aide de votre Texture2D, il faut ajouter l’image au projet. Dans l’explorateur de solutions de VS 2008, faites un clic droit sur Content, puis Add -> Exisiting Item :

 

clip_image004[1]

 

Sélectionnez ensuite une image que vous possédez dans l’explorateur Windows, puis cliquez sur Add. Retournons dans la méthode LoadContent. Pour charger votre image, c’est très simple. Il faut se servir du ContentManager. Celui-ci est déjà instancié dans votre classe Game. Pour l’appeler, il suffit d’accéder à la propriété Content de votre classe Game. Une fois ceci fait, nous allons utiliser la méthode Load de notre ContentManager, spécifier à la place du type générique (entre les chevrons) le type que l’on veut charger, puis passer en paramètre le nom de l’image que nous voulons charger (sans l’extension). Ce qui nous donne ceci :

 

clip_image006[1]

 

Bien sûr, à la place de « xna_logo » vous écrirez le nom de votre image.

Voilà pour cette première partie, vous avez chargez votre image ! Prochaine étape : l’affichage.

 

Afficher une image

 

Voyons d’abord le système de coordonnées pour placer nos images à l’écran. En mathématiques au lycée, quand nous faisions un graphique, notre axe y était dirigé vers le haut, et notre axe x vers la droite. En XNA, l’axe y est dirigé vers le BAS, non vers le haut, et l’axe x vers la droite. Le centre de notre repère (c'est-à-dire le point de coordonnées 0 ;0) est le coin en haut à gauche de la fenêtre. La position d’une image correspond à la position de son coin supérieur gauche. Par exemple, si on veut placer une image à 100 pixels du haut de la fenêtre, et 100 pixels de la gauche de la fenêtre, on placera en fait le coin supérieur gauche de l’image à +100 pixels sur y (et non -100 pixels) et +100 pixels sur x.

 

clip_image008[1]

 

Pour afficher une image, c’est très simple. Nous allons utiliser notre objet de type SpriteBatch. Celui-ci est instancié par défaut dans votre code par le Framework, vous n’avez donc pas à le faire vous-même. Pour dessiner à l’écran, tout se passe dans la méthode Draw de la classe Game. Pour dessiner, il faut d’abord effacer tout ce qu’il y a à l’écran, puis dire à la carte graphique que vous voulez afficher telle image à tel endroit sur l’écran, etc… Voici l’exemple sur lequel nous allons travailler :

 

clip_image010[1]

 

La première ligne permet d’effacer note écran. L’objet GraphicsDevice utilisé ici est une propriété de la classe Game, qui contient diverses informations sur notre périphérique graphique. On appelle sa méthode Clear pour effacer l’écran avec la couleur passée en paramètre. Ensuite, on veut dire à la carte graphique qu’on veut afficher une image en 2D. Pour cela, on utilise notre objet spriteBatch. On indique à la carte graphique que nous voulons commencer à dessiner à l’aide de sa méthode Begin. Ensuite, on dessine notre image avec le spriteBatch et sa méthode Draw. Le premier paramètre de cette méthode est l’image que l’on veut afficher, le deuxième sa position, spécifiée à l’aide d’un objet de type Vector2, qui représente des coordonnées en 2 dimensions, et le dernier la couleur avec laquelle dessiner notre image. Une couleur blanche dessinera notre image telle qu’elle est, une autre couleur appliquera un filtre par-dessus. Enfin, nous indiquons que nous avons fini de dessiner avec la méthode End du spriteBatch. Voici ce que nous devons obtenir (vous aurez surement une image différente de la mienne) :

 

clip_image012[1]

 

Maintenant, je vais changer la couleur de filtre de la méthode Draw. Je vais mettre une couleur rouge.

 

clip_image014[1]

 

Comme vous le voyez, notre image est colorée en rouge cette fois ci.

 

Surcharges de la méthode SpriteBatch.Draw()

 

La méthode SpriteBatch.Draw que nous avons utilisé ci-dessus est présentée dans sa forme la plus basique. Il existe de nombreuses surcharges, qui permettent de pousser plus loin l’affichage de notre image. Voici un exemple :

 

clip_image016[1]

 

On passe toujours en premier paramètre notre image à dessiner, et la position en deuxième paramètre. Le troisième représente la zone de notre image que l’on veut dessiner. Laisser à null pour dessiner l’image entière, ou alors spécifiez à l’aide d’un objet de type Rectangle la zone à dessiner. Ici, je dessine à partir du point de coordonnées de l’image 0 ;0 sur une largeur de 120 pixels, et une hauteur de 120 pixels. Le quatrième paramètre est le filtre de couleur de notre image. Le cinquième paramètre permet de spécifier la rotation de notre image, en radians. Ici, la méthode statique ToRadians de la classe MathHelper est utilisée pour convertir facilement des degrés en radians. Nous tournons donc notre image de 10 degrés dans cet exemple. Le sixième paramètre représente à partir de quel point de l’image nous plaçons l’objet. Ici, nous spécifions 0 ;0, ce qui veut dire que nous dessinerons notre image en prenant comme référence son coin supérieur gauche. Le septième paramètre permet de spécifier l’échelle à laquelle on dessine l’image. Ici, nous dessinons l’image à l’échelle 1, c'est-à-dire en taille réelle. Une échelle de 0.5 aurait réduit la taille de l’image par deux. Le huitième paramètre permet de faire un flip à notre image (la retourner horizontalement ou verticalement, ou pas). Ici, nous la retournons verticalement. Le dernier et neuvième paramètre (ouf !) permet de spécifier dans quel ordre nous affichons les images, mais nous étudierons cela plus tard. Voici ce que me donne cette méthode :

 

clip_image018[1]

 

Nous avons bien une image tournée de 10 degrés, de laquelle on affiche seulement un rectangle de 120 pixels par 120 pixels à partir du pixel en haut à gauche de l’image, flippé verticalement.

 

Conclusion

 

Vous venez de découvrir la base de tout jeu vidéo, aussi bien en 2D, qu’en 3D (et oui, le menu et le HUD, c’est que de la 2D !!). Dans le prochain chapitre, nous allons apprendre à gérer le clavier et la souris pour pourvoir interagir avec notre jeu!

XNA

[Tutoriels XNA] – 2D – Introduction au XNA 3.1

18. February 2010 by Xavier.QUINCIEUX

Présentation du Framework XNA 3.1

 

Le Framework XNA est un ensemble d’outils créé et mis à disposition du grand public gratuitement par Microsoft dans le but de faciliter le développement de jeux-vidéos sur les plates-formes PC et Xbox 360. Techniquement, c’est une surcouche de DirectX. Il est ainsi plus aisé pour l’entreprise ou l’amateur l’utilisant de développer un jeu-vidéo, les nombreuses classes et structures, comme les matrices, les vecteurs, chargement de modèle 3d entre (beaucoup) autres, étant intégrées au Framework. Le travail est alors focalisé sur l’essentiel du jeu et le gain de temps est très appréciable.

 

Créer son premier projet avec le Framework XNA 3.1

 

Pour commencer, il faut installer Visual Studio 2008 Express (gratuite) ou alors toute autre version de Visual Studio 2008 pour ceux qui peuvent. Ensuite, il faut télécharger le XNA Game Studio 3.1 à cette adresse : http://www.microsoft.com/downloads/details.aspx?FamilyID=80782277-D584-42D2-8024-893FCD9D3E82&displaylang=en . XNA Game Studio contient toutes les bibliothèques que l’on va avoir besoin pour coder avec XNA, et une multitude d’outils que nous ne servirons pas dans ce tutoriel, sauf le Microsoft Cross-Platform Audio Creation Tool qui nous servira à intégrer du son dans nos jeux. Une fois Game Studio 3.1 installé, ouvrez Visual Studio 2008, cliquez sur le menu File => New => Project.

clip_image002

 

 

 

Une fois cela fait, dans la liste à gauche, sélectionnez XNA Game Studio 3.1, puis dans la partie de droite, cliquez sur Windows Game (3.1).

clip_image004

 

Choisissez un nom de projet (Chapitre1 par exemple), l’endroit ou vous voulez que votre projet soit enregistré, puis cliquez sur OK.

Présentation du projet de base

 

Nous voilà donc dans Visual Studio, au centre la zone où nous allons coder. Le fichier ouvert est l’onglet sélectionné juste au dessus. A droite se trouve l’explorateur de solution, qui contient les projets de la solution, et dans chaque projet les fichiers et dossiers correspondant. Par défaut, lorsqu’on ouvre un nouveau projet en XNA, c’est le fichier Game1.cs qui est ouvert. Nous devons nous retrouver avec cette vue :

clip_image006

Si nous sommes attentifs, nous remarquons que notre classe Game1 dérive de la classe Game, et hérite du coup de ses propriétés, comme la collection Components, la collection Services, le GraphicDevice et d’autres propriétés qui sont toutes aussi importantes les unes que les autres.

Si nous allons plus en profondeur dans le fichier, nous retrouvons deux champs, graphics de type GraphicsDeviceManager et spriteBatch de type SpriteBatch. Le premier nous servira à avoir accès à quelques propriétés de l’affichage, telles que la résolution de notre fenêtre (sa taille), activer la synchronisation verticale, l’anti aliasing, le plein écran, etc… tandis que le second nous permettra d’afficher des images ou du texte à l’écran, mais ceci fait l’objet d’un autre chapitre.

Encore un peu plus en profondeur dans le fichier et nous nous retrouvons face à pas moins de 6 ( !) méthodes. La première, Game1(), est en fait le constructeur de la classe Game1(). Nous y instancions notre champs graphics, et initialisons le dossier qui contiendra nos ressources, nous reviendrons dessus un peu plus tard. La deuxième est la méthode Initialize(). C’est ici que l’on récupèrera les services que nous aurons besoin, si nécessaire bien sûr, et qu’on chargera tout contenu qui n’est pas graphique, entendez par là autre que image et modèle 3D. Elle est appelée automatiquement juste après le constructeur. La troisième méthode se nomme LoadContent(). Comme son nom l’indique, c’est ici que vous chargerez le contenu de votre jeu, mais graphique cette fois ci. Elle est appelée elle aussi automatiquement après la méthode Initialize(). La quatrième méthode s’appelle UnloadContent(). Elle sert à décharger le contenu chargé précédemment afin de vider la mémoire et d’éviter ainsi des fuites de mémoire. Elle est appelée automatiquement par le Framework quand on ferme le jeu. La cinquième méthode est la méthode Update(). Pour ceux qui n’ont jamais codé de jeux-vidéos ou qui ne ce sont jamais intéressé au développement de jeux-vidéos, sachez que niveau code, un jeu, mis à part initialisation, chargement et déchargement de contenu, n’est ni plus ni moins qu’une boucle infinie, à laquelle on mettra fin lorsque l’on cliquera sur Quitter, par exemple. Cette boucle infinie se découpe en deux phases : la première phase met à jour l’état du clavier, de la souris ou tout autre périphérique d’entrée, l’état des objets à l’écran, c'est-à-dire la position, la vitesse, etc… teste les collisions, met à jour le son, et tout ce qui a besoin d’être mis à jour. La deuxième phase se charge d’actualiser l’affichage de l’écran. Le schéma ci-dessous montre ce principe :

clip_image008

 

Revenons à notre méthode Update(). Si vous avez bien compris le principe, vous aurez remarqué que cette méthode Update() correspond à la première phase de notre boucle infinie. C’est donc ici que nous mettrons le code pour la gestion des périphériques, du son, des personnages etc… La sixième et dernière méthode est la méthode Draw(). Comme son nom l’indique, la méthode Draw() sert à dessiner à l’écran, elle constitue la deuxième phase de notre boucle infinie.

Voici un résumé de notre classe Game1 :

 

    /// <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

 

            base.Update(gameTime);

        }

 

        /// <summary>

        /// This is called when the game should draw itself.

        /// </summary>

        /// <param name="gameTime">Provides a snapshot of timing values.</param>

        protected override void Draw(GameTime gameTime)

        {

            GraphicsDevice.Clear(Color.CornflowerBlue);

 

            // TODO: Add your drawing code here

 

            base.Draw(gameTime);

        }

    }

 

Après une longue explication, et si on lançait le projet pour voir ?

 

 

Maintenant que vous connaissez tout de cette classe de base indispensable pour notre jeu, peut-être aimeriez-vous commencer par coder le prochain Call of Duty ? Bon, vous n’en êtes pas encore là, mais au moins appuyer sur la touche F5 dans Visual Studio (ou menu Debug => Start Debugging) pour voir ce qu’il se passe. Et… une belle fenêtre en 800x600 à fond bleu s’affiche. Ceci constituera notre fenêtre de base pour la suite.

clip_image010

Conclusion

 

Nous voici à la fin de votre première entrée dans le monde du XNA. Vous commencez à découvrir (un tout petit peu) tout ce que le Framework fait à votre place. En effet, vous n’avez même pas écrit une ligne de code, et une fenêtre s’affiche déjà. Aussi, le Framework a créé à votre place la boucle infinie, et tout ce qu’il faut pour charger du contenu. Tout a été pensé pour simplifier la vie du développeur, et vous n’en avez qu’un tout petit avant-goût.

 

 

XNA , ,

[Tutoriels XNA] - Sommaire

18. February 2010 by Xavier.QUINCIEUX

 

Bonjour à tous! Bienvenue sur ce nouveau tutoriel entièrement consacré au développement de jeux-vidéos avec le Framework XNA 3.1. Vous pourrez y trouver aussi bien des articles sur la 2D que sur la 3D. Ci-dessous se trouve un aperçu de ce qui vous attend:

 

 

La 2D avec XNA 3.1

     I. Introduction / Créer son premier projet avec XNA 3.1

     II. Dessiner une image

     III. Gérer le clavier et la souris

     IV. Transformer ses sprites

     V. Animer ses images

     VI. Moduler son code

     VII. Dessiner avec des Pixels Shader

     VIII. Gérer les collisions partie 1 : Broad Phase

     IX. Gérer les collisions partie 2 : Narrow phase

     X. Premier jeu 2D : un pong

     XI. Intégrer une gravité

     XII. Deuxième jeu 2D : super-mario like

 

 

La 3D avec XNA 3.1

     I. Introduction

     II. Les primitives

     III. La caméra

     IV. Dessiner un modèle 3D

     V. Transformer ses modèles

     VI. Dessiner avec ses propres Effects

     VII. Gérer les collisions

     VIII. TP : gestion d’une height map + collision

     IX. Caméra type Third-Person Shooter (troisième personne)

     X. Premier jeu en 3D : un jeu d’avion

     XI. Caméra type First-Person Shooter (première personne)

     XII. Deuxième jeu en 3D : un petit FPS

 

Annexes

     I. Les vecteurs

     II. Les matrices

 

 

Je rédigerai les articles le plus régulièrement possible.

 

 

Bonne lecture à tous !

xna_logo

XNA , , ,