Après un temps d’absence je vais essayer de me motiver à terminer ce didacticiel…
Cette partie est totalement subjective (je ne suis qu’un étudiant sans expérience pro dans le domaine du jeu vidéo donc ne prenez pas cet article comme un bout de science exacte) et vous donnera une structure possible pour votre code.
Objectifs :
Avoir une idée avant le développement de la structure de son code pour un jeu quelconque (testé pour de la 2D en tout cas).
Sommaire :
- Installation et découverte
- Hello World
- Affichage d’images, de sprites, de backgrounds
- Déplacements, collisions, rotations
- Entrées / sorties
- >>>>>Squelette générique d’un jeu 2D
Je ne suis pas très satisfait de cet article, aidez-moi à l’améliorer en m’indiquant ce qui cloche… J’ai un peu perdu la motivation d’écrire et c’est sans doute l’un des plus gros problèmes.

XNA : Squelette générique d’un jeu 2D
Votre code va comporter plusieurs grandes parties :
- Des états : en jeu, en pause, menu.
- Différents moteurs : jeu, physique, graphique, son.
- Des éléments instanciables pour ces moteurs : ennemis, joueurs.
- Du contenu pour le jeu : niveaux, scripts.
Chacune de ces parties correspond donc à une pièce maîtresse de votre code, et s’imbrique avec une ou plusieurs autres.
Une machine à état
Aussi complexe que puisse être un jeu vidéo, on peut résumer son fonctionnement à une machine à état très simple. Chaque état représente un « écran » à afficher au joueur, comme l’écran titre ou le jeu en lui-même.
Un exemple d’une énumération d’états pour un jeu :
1 2 3 4 5 6 7 8 9 10 11 12 | /// /// State of this program /// public enum GameState { Exit, //Exit program TitleScreen, //First screen OptionsScreen, //Options to configure the game LevelSelectionScreen, //Choose the level to play Game, //The game EndLevel //Win or lose } |
Bien sûr les états sont à adapter à chaque jeu. Il nous faut ensuite de stocker l’état du jeu dans une variable (qu’il faut penser à initialiser, par exemple à l’écran titre).
1 2 3 4 | /// /// Game state, or screen to display /// private GameState gameState; |
Ensuite il faut analyser cette variable dans les méthodes Update() et Draw() .
Une série de if/else ou un bon switch fera l’affaire. Selon l’état on va demander au programme d’afficher ce fond et ces éléments, ou de regarder les collisions sur la scène en cours, etc.
1 2 3 4 5 6 7 8 9 10 | public void Draw(...){ if(gameState == GameState.TitleScreen) { //Afficher écran titre //Afficher une animation d'intro } else if(gameState == GameState.Game) { //Afficher les backgrounds //Afficher le joueur, les ennemis, etc } } |
Notez que l’énumération n’est pas une manière très objet de programmer. Il est possible de faire mieux en définissant une classe abstraite GameState contenant des méthodes Update() / Draw() / etc et des sous-classes héritant de GameState que la classe principale Game se chargera d’appeler en temps et en heure.
Cela se traduit avec comme code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | private GameState gameState; private IngameState ingameState; private TitleScreenState tsState; public void Initialize(...) { ... ingameState = new IngameState (...); tsState = new TitleScreenState (...); gameState = tsState ; ... } public void Update(...) { ... gameState.Update(...) ... } public void Draw(...) { ... gameState.Draw(...) ... } |
Le principal problème de cette architecture vient du passage de paramètre entre vos états. Mais tout est modulable, à vous de ruser et de trouver ce qui convient le mieux à votre problème.
Moteurs de jeu
Les moteurs de jeux sont la base technique de votre application. C’est tout simplement ce qui va calculer le scrolling de vos décors ou le déplacement du joueur. C’est donc particulièrement vaste. Par défaut la classe Game est un moteur de tout et de rien. Si vous affichez avec Draw () vos éléments, que vous calculez vos collisions ou que vous lancer la lecture d’un son dans Update(), alors Game est à la fois moteur graphique / physique et son.
Selon la taille de votre jeu il peut être intelligent de découper ces tâches dans des classes distinctes. A l’inverse, un petit jeu sera beaucoup moins lisible avec un trop grand découpage en classe. Tout est à réfléchir.
On peut par exemple imaginer le moteur de son / musique, qui possède de nombreuses méthodes statiques pour lancer la lecture ou changer le volume.
Éléments instanciables
Le plus intéressant. Vous remarquerez vite que tout ce qui est à l’écran possède des propriétés communes : position dans le plan / l’espace, texture utilisée, points de vie restants, vecteur vitesse, etc. Il est intéressant de factoriser ces informations dans une super classe (une sorte d’Object mais pour votre jeu), classe qui pourra être utilisée dans les paramètres de vos méthodes / moteurs rendant ainsi tout cela très générique et simple à programmer.
Ici un objet Player, Enemy ou BackgroundElement posséde un attribut location, speed, hp et sprite grâce à l’héritage et des attributs propres. L’héritage est ici une technique particulièrement utile.
Contenu
Si votre jeu dépasse le simple stade du prototype, il est probable qu’il contienne plusieurs niveaux. La définition d’un niveau (d’une map) est spécifique à chaque jeu. Un niveau est parfois un tableau rempli de valeurs particulières comme pour le Sudoku, et parfois une structure de données complexes avec les textures pour l’affichage de la scène, le stockage des ennemis à afficher et à venir, les éventuels scripts à déclencher, etc.
Conclusion
Voici pour conclure le résumé en UML de cette partie :
Encore une fois c’est une possibilité qui doit être adaptée à chaque jeu. Cette partie étant très vague et très courte, postez vos questions ou vos demandes d’aides pour une architecture en commentaire pour qu’on en discute.




