Gestion du Touch WP7 sous XNA4

30. September 2010 by Florian.ROUSSELET

Le nouvel OS mobile de Microsoft, Windows Phone 7, nous permet via l’écran tactile capacitif de gérer plusieurs points d’appuis. Nous allons voir dans cet article comment gérer cet écran au sein d’ XNA 4 et en faire une utilisation basique de détection de position.

Nous allons avoir besoin des logiciels et SDK suivants :

XNA Game Studio 4

Visual Studio 2010 + Windows Phone Tools

Maintenant voyons la marche à suivre pour la gestion du Touch. Tout d’abord, nous devons nous assurer que le Touch est disponible pour « lire » nos entrées dans la boucle Update.

 

TouchPanelCapabilities touchCap = TouchPanel.GetCapabilities();

 

             if (touchCap.IsConnected)

             {..}

 

Et l’on récupère l’état actuel du périphérique.

TouchCollection touches = TouchPanel.GetState();

 

On obtient donc une collection de « touches » (Points de pression) qui contient pour chaque touche ses coordonnées ainsi que l’état. Concernant ces états, il y a 4 possibilités :

-Invalid : Problème de reconnaissance
-Moved : La position a été mise à jour ou la position ne change pas
-Pressed : Il s’agit d’une nouvelle position
-Released : La position n’existe plus

 

Passons maintenant à la partie détection d’un appui sur l’écran.

if (touches.Count >= 1)

{

touchposition = (touches[0].Position);

}

 

Ici, on test si il y a au moins un point de pression de répertorier. Nous utilisons touchposition, qui est un Vector2 pour récupérer les coordonnées X et Y du point de pression. Attention ici il s’agit du point 0, l’écran du Windows Phone 7 peut gérer jusqu’à 4 points de pression. Il faudra donc penser lors du développement à tester les 4 points de pression. Ici à cause de l’émulateur seul le clic de la souris permet de simuler un point de pression. (Le nombre de point de pression possibles peut être vérifié via touchCap.MaximumTouchCount) .

Maintenant que nous avons ce Vector2 touchposition, nous pouvons l’utiliser comme nous voulons et très simplement. Par exemple pour afficher les coordonnées du point de pression.

Dans la boucle Draw, nous allons donc écrire les coordonnées du point de pression.

spriteBatch.Begin();        

string positionX = string.Format("X : {0}", touchposition.X);

spriteBatch.DrawString(font1, positionX,new Vector2(50,380), Color.White);

string positionY = string.Format("Y : {0}", touchposition.Y);

spriteBatch.DrawString(font1, positionY,new Vector2(50,420), Color.White);

spriteBatch.End();

 

font1 est un SpriteFont que j’ai ajouté au projet, il correspond à la police Segoe UI Mono. Celle utilisée par défaut par Windows Phone 7.


 

Faisons un petit résumé du code, commençons par la boucle Update :

TouchPanelCapabilities touchCap = TouchPanel.GetCapabilities();

if (touchCap.IsConnected)

{

TouchCollection touches = TouchPanel.GetState();

if (touches.Count >= 1)

{

touchposition = (touches[0].Position);

}

}

 

Et la boucle Draw pour dessiner notre résultat :

GraphicsDevice.Clear(Color.Black);

spriteBatch.Begin();

string positionX = string.Format("X : {0}", touchposition.X);

spriteBatch.DrawString(font1, positionX,new Vector2(50,380), Color.White);

string positionY = string.Format("Y : {0}", touchposition.Y);

spriteBatch.DrawString(font1, positionY,new Vector2(50,420), Color.White);

spriteBatch.End();

 

Voyons maintenant en image ce que l’on vient de réaliser :

Premier screen : Lancement de l’application, pas d’appui coordonnées = 0
Second screen : Simulation d’un point de pression via un clic souris, mise à jour des coordonnées
Troisième screen : Autre clic, changement des coordonnées

Maintenant c’est à votre tour d’utiliser le Touch. A vos Visual Studio !

C#, Visual Studio 2010, Windows phone 7, XNA , , ,

Deployer et lancer un jeu XNA 4.0 sur émulateur WP7 sans visual studio.

8. June 2010 by Thomas.Trentin

 

Deployer et lancer un jeu XNA 4.0 sur émulateur WP7 sans visual studio.

1 . Pré-requis:

 

XNA Game Studio 4.0.

CTP April Refresh (Visual Studio 2010 Express For Windows Phone) .

 

Ce tutorial a pour but de vous montrer comment déployer un programme XNA 4.0 sur l'émulateur Windows Phone 7 de microsoft (fournit avec la April Refresh), sans avoir nécessairement le code sous la main.

Ceci peut ête très pratique notament afin de faire tester votre application à une personne tierce sans lui livrer votre code.

 

2 . Deploiement :

 

Créez votre projet XNA 4.0 et compilez le.

Pour une question de simplicité, les fichiers récupérés seront tous mis dans un dossier commun.

Allez dans le dossier de sortie de compilation (dans mon cas bin\Windows Phone\Debug) et récupérez le « .xap » généré, qui est l’archive contenant votre jeu.

Dans mon cas, il s’agit de « XnaGraphicsDemo.xap ».

 

Récupérez aussi le GameThumbNail.PNG.

Allez ensuite dans le dossier : \obj\Windows Phone\Debug et récupérez le fichier « XapCacheFile.xml ».

Il contient les informations sur les ressources et les fichiers de votre application, contenus dans le xap.

 

Enfin, allez dans le dossier properties et ouvrez le fichier AssemblyInfo.cs :

Il faut récupérer la valeur notée sur cette ligne :

Dans notre cas, la valeur à noter est donc : "ba971892-de57-4fa4-b7e6-65d9d6da5af7".

Cela correspond à l’ID de l’application, et est indispensable afin de l’utiliser sur Windows Phone (aussi bien pour le déploiement que pour l’installation).

Vous devez maintenant avoir un dossier contenant tous les fichiers demandés jusqu’ici, ce qui doit ressembler à ceci :

 

Ouvrez maintenant une invite de commande.

Faite glisser le fichier « wp.exe », qui est dans le dossier C:\Program Files (x86)\Microsoft XNA\XNA Game Studio\v4.0\Tools (chemin dépendant de l’installation sur votre machine).

Cela devrait ressembler à ceci :

Tappez maintenant  « install », qui permet de déployer votre application sur l’émulateur, puis faite glisser dans l’invite de commande le fichier « xap », coller le GUID copié précédemment, et enfin faites glisser le fichier thumbail et le fichier xml.

Terminez la commande avec l’instruction « /clean ».

Apuyez sur entrée : l’émulateur se lance et installe votre application automatiquement.

Lorsque le lancement de l’émulateur et l’installation de votre application est terminée, vous devez maintenant avoir l’écran d’accueil d’affiché sur votre émulateur :

 

Vous n’avez plus qu’à taper dans votre invite de commande la ligne comportant le « launch » : (en remplaçant bien sûr la  valeur après le launch par le GUID de VOTRE application) : 

 

Voici le résultat :

C#, Visual Studio 2010, Windows phone 7, WPF, XNA ,

XNA - Une classe Sprite pour faciliter le développement

Introduction

Bonjour,

Au cours de cet article, nous allons simplement faire une classe qui nous permettra de créer et d'utiliser des sprites sans encombrer notre classe Game1. Comme vous l'avez vu dans le chapitre d'initiation à XNA, plusieures méthodes sont redondantes :

  • LoadContent() : pour obtenir une texture
  • Update(GameTime gameTime) {} : Permet de donner un mouvement, ou d'animer vos sprites
  • Draw(GameTime gameTime) {} : Affiche les sprites

Ainsi, pour éviter d'avoir à tout redéfinir à chaque fois, on commence par créer une nouvelle classe : Sprite.cs

 

Création de la classe Sprite

Pour commencer, il faut garder à l'esprit qu'un sprite est determiné par une position et une texture.

 

N'oubliez pas d'ajouter également les directives using correspondantes :

 

Ensuite, nous créeons le premier constructeur :

 

 

Celui ci est très simple car on determine uniquement la position sous forme de vecteur, mais on pourra, par la suite, en faire de plus complets, prenant en compte une échelle pour le redimensionnement, ou encore une teinte.

 

Maintenant, nous allons utiliser la méthode permettant de charger la texture, provenant d'une image.

 

 

Pensez aussi à ajouter la directive afin de pouvoir utiliser le Content Manager :

 

Definissons le mouvement dans Update :

Puis il ne nous reste plus qu'à afficher le sprite grâce à la méthode Draw :

 

Comme vous pouvez le voir, on utilise la texture, la position et également une couleur. La couleur spécifiée correspond à la modulation. Le fait de choisir la couleur blanche équivaut à ne pas utiliser la modulation.

 

Voila, donc, à l'heure actuelle la classe n'est pas très complète mais peut déjà être utilisée.

Utilisation de la classe

Pour la suite nous utiliserons une image d'un personnage de type stickman :

 

Il suffit d'ajouter l'image dans la Content Manager :

Et éventuellement, changer le texte dans le champ "Asset Name" pour pour l'utiliser.

 

Ensuite, il faut déclarer un objet stickman de type Sprite dans la classe Game1 :

Puis initialiser la variable dans la méthode prévue à cette effet : Initialize.

 

 

Ensuite, il faut donc utiliser la méthode LoadContent pour charger l'image choisie.

 

La chaine de caractère "stickman" correspond au champs "Asset Name" du Content Manager.

 

Utilisons la méthode Update pour donner les coordonnées du vecteur pour le mouvement :

 

Et pour finir, il ne reste plus qu'à utiliser stickman.Draw pour dessiner cet objet :

 

 

Voila donc pour résumer, une fois la classe Sprite créee, en seulement 3 lignes, nous pouvons afficher implémenter et afficher notre sprite qui se déplace horizontalement.

 

 

Aller plus loin

Certes, à l'heure actuelle, le personnage ne fait pas grand chose. Mais à partir de cette base, nous pouvons par exemple créer une classe héritée de Sprite qui aura des caractéristiques en plus, des evènements supplémentaires dans Update(GameTime gameTime), ou alors une gestion de collisons que n'aurais pas forcément tous les sprites.

Par exemple, nous pouvoir ajouter un getter et un setter de la variable position qui nous permettra de vérifier la position du sprites et de la modifier.

 

Conclusion

Au cours de cet article, vous avez vu comment créer et utiliser la classe Sprite.

Retrouver le code complet de ces deux classes à ces adresses :

 

XNA

Farseer Physics avec XNA et Silverlight

9. April 2010 by Quentin.SALLAT

Introduction

On constate ces dernières années, un regain d’importance pour le game design et l’originalité d’un jeu, au détriment de la qualité graphique. Le succès des jeux sur wii, ces casual games, en est la preuve. Mais ces jeux incluent bien souvent un élément important : le moteur physique. De nombreux jeux sont même uniquement basés sur ce genre d’interactions.

Avec l’utilisation croissante de technologies telles que XNA ou Silverlight, il est important de comprendre l’intérêt de ces moteurs physiques, et comment les utiliser. Une série d'articles va donc être consacrée à une présentation de l’un de ces moteurs Farseer physics, qui fonctionne avec ces deux technologies.

I)Introduction aux moteurs physiques et Farseer


1)Qu’est-ce qu’un moteur physique ?

Commençons par la base : Qu’est-ce qu’un moteur physique finalement ? Il s’agit d’un ensemble de fonctionnalités, classes et objets, qui permettent l’instauration de la gravité (et de ce que cela engendre), dans un espace. Imaginons que dans votre jeu, vous avez un personnage qui peut sauter. Concrètement, le moteur physique s’occupera tout seul d’appliquer une force à votre personnage, qui le fera d’abord monter, puis descendre. Finalement, les moteurs physiques aident grandement à reproduire les lois physiques de notre monde.

2) Qu’est-ce que Farseer Physics ?

Farseer Physics est un moteur physique open-source. Il est disponible pour Silverlight, XNA, WPF, mais dispose aussi de classes indépendantes de toute plateforme. Vous pouvez télécharger le contenu qui vous intéresse sur http://farseerphysics.codeplex.com. De nombreux exemples sont également disponibles.

3)Quelques exemples

NinjaBall, un petit jeu fait en Silverlight avec Farseer Physics.
NinjaBall, un petit jeu fait en Silverlight avec Farseer Physics.

Phun, un formidable simulateur physique.
Phun, un formidable simulateur physique.

 

 

II)Farseer Physics avec XNA


1)Intégrer Farseer Physics à votre projet

La première étape dans l’utilisation du moteur Farseer, est son intégration au sein du projet.  Dans un premier temps, téléchargez-le sur le site de Farseer Physics sur Codeplex. Ajoutez ensuite le projet Farseer Physics pour XNA à votre solution. Ajoutez ensuite les assemblies suivants pour utilisez les classes du moteur :

using FarseerGames.FarseerPhysics;

using FarseerGames.FarseerPhysics.Collisions;

using FarseerGames.FarseerPhysics.Dynamics;

using FarseerGames.FarseerPhysics.Factories;

Vous voilà prét à découvrir les lois de la physique !

2)Ajouter la Gravité

Une fois le projet prêt, il vous faudra tout d’abord ajouter l’élément essentiel à votre projet : le PhysicsSimulator, qui aura pour rôle de gérer toute la physique de votre environnement. L’objet dispose de deux constructeurs. L’un ne prend aucun paramètre, l’autre accepte un vecteur de gravité.

PhysicsSimulator simulator = new PhysicsSimulator(new Vector2(0, 750));

Dans cet exemple, on créé un simulateur physique avec une force de gravité de 0 en X, et de 750 en Y. Cela correspond environ à une gravité normale. Maintenant que la gravité est integrée au système, il va falloir insérer des éléments qui y sont soumis.

3)Ajouter des corps

Tout objet a intégré à l’environnement physique est appelé un corps. Ceux-ci sont composés de Body et de Geom Le Body correspond  à la position et les caractéristiques physiques du corps. Le Geom, lui, détermine la forme de celui-ci, et permet de gérer les collisions. Pour créer un Body, il vous faudra utiliser un objet statique nommé BodyFactory. La méthode de création prend pour argument  la largeur du corps, la hauteur, la masse, et éventuellement le PhysicsSimulator.

body = BodyFactory.Instance.CreateRectangleBody(width, height, 1);

Nous allons utiliser la même méthode ensuite pour la géométrie. La méthode de construction prend en paramètre un corps auquel  la géométrie est attachée, ainsi qu’une largeur et une hauteur. 7 autres constructeurs sont disponibles pour gérer les différentes situations.

geom = GeomFactory.Instance.CreateRectangleGeom(body, width, height);

Ensuite, il vous faudra ajouter tout simplement ces objets au simulateur physique.

simulator.Add(body);

simulator.Add(geom);

Et voilà, vos objets physiques sont integrés au simulateur. Mais comment visualiser ces objets ? Pourquoi ne pas afficher une image qui changera de position avec le corps ?

Texture2D texture;

Body body;

Geom geom;

protected override void LoadContent()

{

PhysicsSimulator simulator = new PhysicsSimulator(new Vector2(0, 750));

texture = Content.Load<Texture2D>(@"gfx/img");

body = BodyFactory.Instance.CreateRectangleBody(100, 100, 1);

geom = GeomFactory.Instance.CreateRectangleGeom(body, width, height);

simulator.Add(body);

simulator.Add(geom);

}

protected override void Update(GameTime gameTime)

{

simulator.Update(gameTime.ElapsedGameTime.Milliseconds * .001f);

base.Update(gameTime);

}

protected override void Draw(GameTime gameTime)

{

GraphicsDevice.Clear(Color.CornflowerBlue);

spriteBatch.Begin();

spriteBatch.Draw(texture, new Rectangle(body.Position.X, body.Position.Y, 100, 100)

,Color.White);

spriteBatch.End();

base.Draw(gameTime);

}

Et voilà, ce code vous permettra de suivre “en direct”, la chute d’un objet soumis aux lois de la gravité. Vous pouvez vous amuser à changer les valeurs des différents éléments.

Et que faire si vous voulez rendre votre objet statique, indispensable pour faire un plateformer. Il vous suffit de mettre à true l’attribut IsStatic.

4)Gestion des collisions

Une fois vos corps créés, vous voudrez peut-être les faire interagir entre eux. La gestion des collisions avec Farseer Physics se fait très simplement. Il vous suffira d’ajouter un élément de type CollisionEventHandler sur l’événement OnCollision de votre Geom.

geom.OnCollision += new CollisionEventHandler(CollisionOccursPlay1);

La méthode recevra trois arguments : les deux corps qui sont entrés en collision, et un objet de type ContactList, qui contient, comme son nom l’indique, les points de contact. A vous ensuite de gérer les collisions comme vous le souhaitez !

Vous êtes à présent parés pour gérer la gravité dans votre jeu !

 

III)Farseer Physics avec Silverlight

 

1)Intégrer Farseer Physics à votre projet Silverlight

L’intégration de Farseer en Silverlight se fait de la même manière qu’en XNA si vous souhaitez utiliser le moteur physique dans votre code behind. Cependant, il est possible, comme nous allons le voir, d’utiliser Farseer sans une seule ligne de code, en usant de behaviors dans Expression Blend.

2)Utiliser Farseer avec les behaviors

Si vous êtes un utilisateur de Expression Blend, vous savez certainement ce qu’est un behavior. C’est une extension à des contrôles existants, pour l’ajout d’effets par exemple, et cela, sans ligne de code. Il vous faudra, pour utiliser ceux de Farseer, intégrer la bonne dll au projet.

Commencez par convertir votre LayoutRoot en Canvas. Cela est une pratique courante dans la programmation de jeux, et vous sera très utile plus tard. Dessinez ensuite une ellipse.

Le début d'un nouveau jeu?
Le début d'un nouveau jeu?

Une fois cela fait, vous avez les bases du prochain jeu Silverlight de l’année !

Faites glisser depuis votre liste de behaviors, le PhysicsControllerBehavior, sur votre Canvas. Vous pourrez y modifier divers paramètres dans la fenêtre de propriété, comme la gravité. Je vous conseille de cocher la case « MousePickEnabled », pour pouvoir diriger votre balle comme vous le souhaitez. Ajoutez ensuite le behavior « PhysicsObjectBehavior », le plus utile de tous. C’est en effet lui qui va déterminer si un objet réagit à la physique ou non. Encore une fois, il est possible de gérer divers propriétés, comme la masse, le moment d’inertie etc. Compilez, exécutez, et admirez le travail. Votre balle tombe, et est déplaçable avec la souris.

Vous pouvez vous amuser à rajouter quelques éléments, et modifier leurs propriétés physiques.

Mais comment faire si l’on souhaite gérer des événements physiques ? C’est possible soit en code-behind, soit directement dans Blend, et oui ! Nous allons par exemple, appliquer une force à notre balle, à chaque fois que la touche espace est relâchée. Glissez donc le behavior « PhysicsApplyForceBehavior » dessus. Dans la fenêtre des propriétés, il vous sera proposé de rajouter un EventTrigger pour déclencher l’application de la force. Cliquez sur « New ». Vous verrez apparaître une liste d’événements.

De nombreux Triggerrs sont disponibles
De nombreux Triggerrs sont disponibles

Nous allons donc rajouter un trigger de type « KeyTrigger ». Il vous faudra ensuite mettre le Parent de l’événement, typiquement, il s’agit de votre LayoutRoot. La petite icône de cible vous permettra de cibler directement votre Canvas. Réglez ensuite le type d’événement associé (KeyUp ou keyDown ici), la force à appliquer, et la touche qui déclenchera l’événement, avec éventuellement une touche supplémentaire (comme Alt, Shift etc.).

Vous pouvez tester maintenant, et votre balle réagit aux événements ! Attention cependant, vérifiez bien que votre Canvas a le focus, sinon les entrées clavier ne seront pas prises en compte. Et voilà le résultat :

Une expérience physique originale et ludique.
Une expérience physique originale et ludique.

Il est possible de gérer de nombreuses choses en mixant les behaviors et du code behind. Vous pourrez trouver beaucoup d’informations et de tutoriaux sur la page Codeplex de Farseer, y compris une vidéo sur le mélange entre les behaviors et du traitement en C#.

3)Utiliser Farseer dans votre code behind

Utiliser Farseer se fait presque de la même manière qu’en XNA. Votre code sera donc facilement portable de l’un à l’autre. Vous pouvez initialiser le moteur physique comme en XNA. Le seul changement concerne la gestion du temps pour mettre à jour le moteur. En effet, en XNA, la boucle de jeu, et donc le temps, sont gérés automatiquement, ce qui n’est pas le cas de base en Silverlight.

Le plus simple est certainement de faire un storyboard, et de lui mettre la durée que vous souhaitez. Mais il est aussi possible de réaliser une boucle automatiquement grâce à l’objet CompositiionTarget, qui vous permettra de réaliser des boucles de jeu, de sorte que votre application ait bien 60 FPS (frames par seconde). Vous pouvez associer une méthode à son événement Rendering, pour ainsi avoir une boucle de jeu prête !

Conclusion

Vous savez à présent comment gérer la physique dans vos jeux, que ce soit avec XNA et Silverlight. Le moteur Farseer n’est certainement pas le plus complet des moteurs physiques, mais il a l’avantage d’être compatible avec .NET, et d’être simple d’utilisation. Un monde plein de gravité et de moments d’inertie vous attend désormais !

C#, XNA, Silverlight

La Gestion du Frame rate et de la vitesse d’animation en XNA

9. April 2010 by Thomas.Prost

xna_logo 

Frame quoi ?

Avant de parler de Frame rate, il est important d’expliquer ce qu’est une frame en développement de jeux vidéo, que ce soit en XNA ou autre. Par défaut, XNA va effacer l’écran et redessiner la scène grâce à sa fonction Draw. Chaque scène appelée par cette méthode est nommée Frame. L’exemple le plus parlant, lorsque l’on évoque les frames, est celui des bandes dessinées. Chaque case représente une frame. La vitesse où vont s’enchainer les scènes va représenter le frame rate ou images par seconde dans la langue de Molière. Toutes les 16 Millisecondes, l’animation est rafraichie ce qui équivaut à 60 images / secondes. Pour les écrans d’ordinateurs, les cadences les plus souvent employées sont de 30, 60 et 100 images par secondes.

A noter que les frames rate à la télévision sont différents en fonction des normes utilisées. La norme européenne PAL (secam pour la France) réglemente la cadence à 25 fps (frame per seconde) alors qu’aux États-Unis et au Japon (norme NTSC), elle est de 30 fps.

Maintenant que nous avons vu ce qu’était le frame rate, vous allez peut être vous demander à quoi cela pourrait servir de le changer si il est adapté. J’aurai tendance à vous dire que vous avez raison mais il arrive que dans certains projets l’on veuille adapter la cadence d’affichage à son jeu pour un effet plus rapide ou plus lent par exemple.

Imaginons que vous vouliez afficher une sphère qui tourne (par exemple la terre), la vitesse de rotation ne vous ira peut-être pas avec le Framerate par défaut, il est donc intéressant de pouvoir le changer.

 

La Classe Game a une propriété appelée TargetElapsedTime qui définit combien de temps il faut attendre entre les appelles de la méthode Update. En grande partie, cette méthode représente le temps entre chaque scène à dessiner. Par défaut, la valeur est de 1/60 de seconde, c'est-à-dire 60 images par seconde.

Voyons donc comment changer le frame rate en XNA, insérez la ligne suivante au niveau du constructeur de la classe Game1 :

TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 50);

La classe TimeSpan peut prendre jusqu’à cinq paramètres : jours, heures, minutes, secondes et millisecondes. Dans notre exemple, nous souhaitons donc appeler la fonction Update toutes les 50 millisecondes ce qui correspond à 20 images par secondes. Avec un frame rate bas, l’animation sera beaucoup moins rapide et fluide mais avoir un frame rate trop important pourra avoir des conséquences néfaste sur les performances du jeu puisqu’il deviendra gourmant en ressources pour votre processeur.

 

Heureusement, il est possible de savoir si votre jeu souffre de performances trop élevées par rapport à l’ordinateur sur lequel il tourne. L’objet GameTime, qui est passé en paramètre aux fonctions Draw et Update, a une propriété IsRunningSlowly. Si cette valeur est à true, cela veut dire que XNA n’arrive pas à suivre le Framerate que vous lui avez donné.

 

La vitesse d’animation

Changer le frame rate c’est bien, mais comment faire lorsque l’on souhaite changer la vitesse d’affichage de certains éléments et non de la scène entière ?

Reprenons l’exemple d’un jeu faisans tourner une sphère et, pour rajouter un peu de piment à ce jeu pourtant révolutionnaire, nous pourrions afficher, par exemple, un petit personnage qui marche (vraiment révolutionnaire). Avoir un Framerate unique pour toute la scène peut alors devenir problématique et changer la vitesse d’animation de chaque objet peut être plus adapté.

Nous allons donc changer la vitesse d’animation et ainsi pouvoir l’adapter à chaque objet de la scène. Supprimez d’abord la ligne précédente qui permettait de changer le frame rate.

Déclarez ensuite deux variables, une première permettra de savoir depuis quand la dernière frame a été chargée, la deuxième va permettre de définir le frame rate en millisecondes.

 

int tpsDerniereFrame = 0;
int milliParFrame = 50;

 

Maintenant, dans la méthode Update, avant les instructions qui permettent de mettre à jour les différentes instructions du jeu comme la position des objets, les scores, etc., insérez ceci :

protected override void Update(GameTime gameTime)
        {
         
                 tpsDerniereFrame += gameTime.ElapsedGameTime.Milliseconds;
                 if(tpsDerniereFrame > milliParFrame)
                       {
                           tpsDerniereFrame -= milliParFrame;

                        

 

La propriété gameTime.ElapsedGameTime permet de savoir depuis combien de temps la dernière frame s’est chargée.

On test ensuite si cette variable est supérieure au frame rate que l’on a fixé au début et alors on y soustrait la valeur de milliParFrame

Vous pouvez compiler et tester votre nouveau frame rate sur, par exemple, plusieurs images qui se succèdent, changer la cadence et ainsi voir les conséquences d’un frame rate plus ou moins haut.

 

Affichage du Framerate dans son jeu

 

Nous allons maintenant créer une classe très simple qui va permettre d’afficher le Framerate dans la scène de votre jeu vidéo. Commencez par faire un clic droit sur Content, puis ajouter et nouvel objet. Dans la fenêtre qui vient de s’ouvrir, choisissez Sprite Font puis renommez-le en maPolice.spriteFont par exemple. Cela va permettre de rajouter du texte dans notre scène. Ensuite, Rajoutez au début de votre classe Game1 :

SpriteFont font;

 

Ajoutez ensuite, au niveau de la classe LoadContent

 

protected override void LoadContent()
      {
          font = Content.Load<SpriteFont>("maPolice");

      }

 

Une fois ceci fait, créez la classe EcrireTexte :

 

private void EcrireTexte()
       {
           spriteBatch.DrawString(font, “Framerate : “ + milliParFrame.ToString(), new Vector2(100, 100), Color.Black);
       }
 

Dans cette classe, nous appelons la fonction spriteBatch.DrawString qui va permettre d’afficher le framerate dans notre cas. On lui passe en paramètre la police, le texte à afficher, l’emplacement grâce à un vecteur et pour finir la couleur.

Pour finir, appelez la fonction EcrireTexte que vous venez de créer dans la classe Draw().


protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.White);
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.FrontToBack, SaveStateMode.None);
            DrawText();
            spriteBatch.End();
            base.Draw(gameTime);
        }

 

 

Bibliographie :

Article très intéressant sur le Framerate : http://www.nofrag.com/2003/nov/24/8629/

C#, XNA , , , , , , , ,

[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 , , ,

Développement XNA pour la Xbox et le PC

17. July 2009 by Leonard.LABAT

« Développement XNA pour la Xbox et le PC » : c’est le nom du premier livre en français qui a pour thème XNA et qui est disponible dès aujourd’hui en librairie et depuis quelques jours à de nombreux endroits sur la toile. Un grand merci à l’éditeur, Eyrolles, qui m’a aidé à la réalisation de ce projet.

Tout au long de ses 340 pages, que vous soyez un développeur C# expérimenté ou un débutant, le livre vous accompagnera dans la découverte des nombreuses facettes d’XNA.

Au sommaire :

  • Débuter en C#
  • Prise en main de XNA
  • Afficher et animer des images : les sprites
  • Interactions avec le joueur
  • Cas pratiques : programmer en Pong
  • Enrichir les sprites : textures, défilement, transformation, animation
  • La sonorisation
  • Exceptions et gestion des fichiers : sauvegarder et charger un niveau
  • Pathfinding : programmer les déplacements des personnages
  • Collisions et physique : créer un simulateur de vaisseau spatial
  • Le mode multijoueur
  • Les bases de la programmation 3D
  • Améliorer le rendu avec le High Level Shader Langage
  • Visual C# Express 2008
  • Les bienfaits de la documentation


Le livre sur lesite de l’éditeur :

http://www.eyrolles.com/Accueil/Livre/9782212124583

 

LABAT Léonard 

XNA, Livre , , , , , , ,