Newsletter Developpez.com

Inscrivez-vous gratuitement au Club pour recevoir
la newsletter hebdomadaire des développeurs et IT pro

Programmer un jeu avec MIDlet Pascal


précédentsommairesuivant

III. Le jeu

Le principe du jeu est bien simple, diriger Mario afin qu'il range des caisses à des emplacements bien précis dans un entrepôt. Nous utiliserons plus tard le terme emplacement cible pour décrire ces emplacements. Bien que simple comme principe, ce jeu peut vraiment donner des maux de tête pour qui veut résoudre des grilles difficiles.

Dans cette section, nous allons concevoir et programmer les méthodes qui nous permettront de voir le jeu sur l'écran de l'émulateur et de rendre le jeu fonctionnel. Vu que le jeu peut facilement être très dur à résoudre, nous fixerons un temps maximal pour la résolution d'une grille, au bout duquel la partie sera considérée comme perdue.

Nous allons utiliser une approche qui consiste à séparer le travail à faire en trois parties. Et chaque partie sera contenue dans une unité.

  • La première contiendra les données du programme : déclaration globale de types, de variables ainsi que des constantes.

  • La deuxième concerne tout ce qui touche à l'affichage du jeu sur l'écran.

  • La dernière contiendra le moteur du jeu. MIDlet Pascal impose qu'on utilise d'autres unités que dans la partie Implementation d'une unité. Ces contraintes nous obligeront à décrire la boucle principale du jeu dans cette unité afin de pouvoir utiliser les méthodes que nous allons définir.

III-A. Les données du programme

Nous avons précédemment convenu que nous assimilerions l'entrepôt à un labyrinthe, que nous allons représenter par une matrice. Chaque élément de la matrice contiendra un nombre qui représente le type d'élément qui se trouve à cet emplacement dans le labyrinthe. Les différents éléments que pourra contenir le labyrinthe sont : Mario, une caisse, une cible, une caisse bien placée, un mur ou le vide. En Pascal standard, nous aurions pu utiliser un type énuméré pour représenter les différents éléments de la grille (la matrice). Nous allons utiliser une astuce qui consiste à garder ces différentes valeurs dans les champs d'un type Record. Nous utiliserons aussi cette même approche pour représenter les différents sens de déplacements possible de Mario dans la grille.

Pour des raisons de performance, nous conserverons la position de Mario dans une variable globale et non dans la grille.

Voici le code de cette unité :

Header.mpsrc
CacherSélectionnez

III-B. La vue du programme

En séparant le programme en trois parties : données - vue - traitement, on peut se focaliser sur une partie sans connaître le détail des autres. Ainsi, la vue de notre jeu va uniquement concerner l'affichage du labyrinthe avec ses différents éléments : Mario, caisse, ... On affichera le Timer qui permet de limiter le temps de résolution.

Les données du labyrinthe se trouvent dans la variable globale header.Grille. Chaque élément de cette grille est de type Integer dont la valeur est identique à un champ de la variable header.sEntite. Souvenez-vous que la position de Mario est définie dans la variable header.MarioPos. Il sera donc affiché après l'affichage de la grille.

L'affichage du labyrinthe va se faire de la façon suivante : on parcourt la grille, pour un élément donné on détermine l'entité se trouvant à cette position puis on affiche l'image de cette entité.

 
Sélectionnez

	 if(header.grille[i, j]=sEntite.mur) then
     drawImage(imgMur, x+debutX, y+debutY) 
    else if (header.grille[i, j]=sEntite.caisse) then
     drawImage(imgCaisse,  x+debutX, y+debutY)
    else if (header.grille[i, j]=sEntite.OKCaisse) then
     drawImage(imgOKCaisse,  x+debutX, y+debutY)
    else if (header.grille[i, j]=sEntite.cible) then
     drawImage(imgCible,  x+debutX, y+debutY);

Pour le Timer, on affichera l'image centrée d'une horloge suivie du temps écoulé sous la forme mm :ss.

mario sokoban

Nous avons vu dans les précédents tutoriels que l'affichage à l'écran n'est mis à jour qu'après un appel de la méthode Repaint.

Voici le code de l'unité :

affichage.mpsrc
CacherSélectionnez

III-C. Le moteur du jeu

Nous allons maintenant rendre le jeu jouable et interactif en développant les règles du jeu, en gérant les collisions et en développant la boucle principale du jeu.

Penchons-nous tout d'abord sur les règles du jeu :

  • Mario doit se déplacer dans le labyrinthe, et pousser des caisses
  • Mario ne peut pousser une caisse que si l'espace après elle est vide ou est un emplacement cible
  • Mario ne peut pas passer à travers un mur ou franchir les limites du labyrinthe
  • Le jeu est gagné si toutes les caisses se trouvent sur les objectifs
  • Nous ajoutons que la partie est perdue si le joueur décide d'abandonner la partie ou si le temps maximal de résolution est épuisé

Les règles ne sont pas très compliquées comme vous pouvez le voir. Mais nous allons être prudents pour ne pas oublier de détails.

  • Avant de pousser une caisse, on doit considérer deux choses; si la caisse est déjà sur un emplacement cible (une caisse bien placée), nous devons indiquer dans la grille que l'emplacement est un emplacement cible après avoir poussé la caisse. Si la position que doit occuper la caisse après le déplacement est un emplacement cible, nous devons indiquer dans la grille que cet emplacement contient une caisse bien placée
  • Avant de chercher à déplacer Mario, nous devons vérifier si le nouvel emplacement est vide ou est un emplacement cible. Un autre cas possible sera que cet emplacement contient une caisse que Mario peut pousser

La boucle principale du jeu se chargera de contrôler la pression des touches du clavier. Selon la touche appuyée, on décidera s'il faut chercher à déplacer Mario selon la direction voulue ou abandonner la partie. On vérifiera à chaque fois si le temps limite n'est pas épuisé ou si la partie n'a pas encore été gagnée.

Voici le code résumant tous ces discours :

jeu.mpsrc
CacherSélectionnez

III-D. Autres unités et assemblage du programme

III-D-1. Autre Unité

Vous vous souvenez sans doute que je vous avais demandé demander de télécharger deux types de fichiers : les images et les grilles du Mario Sokoban. On a déjà utilisé une partie des images pour l'affichage du jeu. Mais je ne vous ai pas encore dit à quoi vont nous servir ces grilles et comment les utiliser.

Ces grilles contiennent en fait la position des différents objets ou entités que contient le labyrinthe. Dans les codes que je vous ai donnés, on a supposé que la grille a déjà été initialisée avec les différentes entités au départ. Nous allons maintenant voir comment initialiser la grille du jeu.

Nous utilisons un format spécial pour enregistrer les données du labyrinthe. Regardons un exemple :

 
Sélectionnez
0022222222
0020333332
0020555032
002020003222
002020105302
002020005002
002025552002
002000000002
002222222222
</end>

Chaque chiffre représente une entité (caisse, Mario, ...). Ce sont en fait ces mêmes chiffres que nous avions utilisés pour définir les constantes définissant ces entités dans les données du programme.

 
Sélectionnez
sEntite.vide         := 0;
 sEntite.mario     := 1;
 sEntite.mur        := 2;
 sEntite.cible       := 3;
 sEntite.caisse     := 5;
 sEntite.okCaisse := 6;
 

La position des chiffres est la même que pour les éléments de la matrice. Nous allons donc créer une nouvelle unité où nous mettrons les traitements permettant de charger une grille ainsi d'autres procédures permettant la gestion du Timer et la libération du buffer du clavier.

misc.mpsc
CacherSélectionnez

III-D-2. Assemblage du programme

Nous venons de terminer la partie la plus importante du projet. Il ne nous reste qu'à écrire le programme principal, compiler puis exécuter le projet.

sokoban.mpsrc
Sélectionnez
program sokoban;
 
 uses jeu, header, affichage, misc;
 
 var etat : integer;
 
begin	
  misc.chargerGrille('grille1');
  etat:=jeu.jouer;
end.
	 

Nous verrons dans la prochaine section comment ajouter des menus et un écran d'accueil à notre programme.

Vous pouvez télécharger la version actuelle du projet : sokoban.zip.


précédentsommairesuivant

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2010 Kpizingui Darryl. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.