Tutorial

 

Voici la marche à suivre pour écrire un jeu.

 

Les éléments du décor doivent être créés avec un logiciel adéquat. Il est préférable de faire du .gif car il est possible d'utiliser la couleur transparente. Les animations des personnages doivent être découpées par "action". Par exemple un fichier "hero-left.gif" qui contiendra l'ensemble du mouvement "déplacement vers la gauche". Dans notre exemple on a deux planche de dessin pour notre héros. Une pour chaque déplacement.

 

Les sprites doivent être créés et compile. Pour cela il suffit de dériver la classe Sprite et de redéfinir quelques méthodes.

Tout d'abord draw() doit être refaite pour donner de l'apparence. L'affichage peut être fait  avec un ImageDisplayer. Il suffit juste d'appeler ImageDisplayer.displayNextImage en lui passant  la référence du contexe graphique, la position sur l'écran (récupérable à partir de Sprite. getPosUnderScreen()), et le numéro de l'action qu'on est en train de réaliser.

Le numéro de l'action qu'on est en train de réaliser peut être récupéré à partir de la redéfinition de move(). Voici un exemple:

            public void move(int dx, int dy) throws CollisionException{

                        super.move(dx, dy);

                        if(dx>0) lastAction=0;

                        if(dx<0) lastAction=1;

                        if(dx==0) lastAction=-1;

            }

 

La variable lastAction est un indicateur qui doit être défini dans la nouvelle classe.  Ici le –1 indique que le personnage est au repos(on affiche donc le première image de la série courante).

 

On peut éventuellement redéfinir la méthode Sprite.life(). Cela permet de donner du mouvement au sprite. Par exemple un bonus n'en aurait peut être pas besoin. Mais un monstre doit donner une impression de vie. La redéfinition permet de donner un caractère particulier à donner à chaque objet. La définition de base soumet l'objet à la gravité(caractéristique commune pour tout les objets).  Voici un code tiré de notre exemple:

            public void life(){

                        int pas=2;

                        super.life();

                        try{

                                   if(direction==false)

                                               move(pas, 0);

                                   else

                                               move(-pas,0);

                        }

                        catch(MapCollisionException e){direction=!direction;}

                        catch(CollisionException e){}

            }

Ce code permet de faire avancer le personnage jusqu'à qu'il heurte un mur, pour ensuite faire demi-tour.

 

 

Ensuite il faut redéfinir la méthode Sprite. MoveListener(). Cette méthode permet de gérer les interactions avec les autre personnages (et d'une manière générale avec les autres sprites).

 

            public void moveListener(CollisionEvent event){

                        if(event.getSource() instanceof HerosSprite){

                                   System.out.println("Hero die !!");

                                   ((HerosSprite )event.getSource()).destroy();

                        }else if(event.getSource() instanceof MissileSprite){

                                   System.out.println("I die !!");

                                   destroy();

 

                                   // On signale au missile qu'il peut se détruire(cf code de missile)

                                   ((MissileSprite)(event.getSource())).moveListener(null);

                        }

            }

Ce code est bien adapté pour un monstre: s'il se fait toucher par le héros, ce dernier meurt, sinon s'il se fait toucher par un missile, le missile et le monstre disparaissent.

 

Dans le constructeurs du nouveau Sprite, on peut indiquer s'il est soumis a l'action gravitationnelle, et éventuellement lui spécifier sa taille s'il on choisit de l'afficher sans ImageDisplayer.

IMPERATIF: il faut toujours qu'il y ait un constructeur par défaut (l'éditeur de niveau demande une instance du Sprite à partir du constructeur par défaut).

 

Il faut ensuite redéfinir la méthode Sprite.init(). Cette méthode permet d'initialiser la partie graphique. Elle a pour mission d'initialiser l'ImageDisplayer. Par exemple:

public void init(){

                        imageDisplayer = new ImageDisplayer();

 

                        addLineOfImage("walk-right.gif",15,0);

                        addLineOfImage("walk-left.gif",15,0);

            }

 

Voilà pour les Sprites.

 

Ensuite vient la définition du décor. Pour cela il suffit d'utiliser l'éditeur.


Un élément est défini par sa représentation graphique, tandis qu'un monstre par sa classe Java.

 

 

 


Ensuite vient la définition du jeu proprement dit.

Le jeu doit dériver de la classe GameRoot.  Comme toujours il faut redéfinir des méthodes.

La méthode GameRoot.initGame() permet de d'initialiser le jeu.  Le mieux est de présenter un exemple de code:

            public void initGame(){

1                      map=Map.load("test.map");

2                      testSprite=new TestSprite();

3                      testSprite.setPos(100, 50);

4                      addSprite(testSprite);

5                      testSprite.setMap(map);

 

6                      SpriteGroup spriteGroup=SpriteGroup.load("test.spr");

7                      addGroup(spriteGroup, map);

 

8                      testSprite.addEnemi(spriteGroup);

9                      spriteGroup.addEnemi(testSprite);

 

10                    map.setViewPortSize(10, 10);

11                    setAutoFire(false);

            }

 

La ligne 1 permet de charge un décor. Au cours du jeu on peut évidemment changer de décor, il suffit de ne pas oublier de signaler a tous les sprites qu'ils vont agir dans un nouveau environnement.

A la Ligne 2 on crée notre héros, et on lui attribue une position (3). On indique au jeu du nouveau sprite à gérer (4), et on indique à notre héros dans quel environnement il va évoluer (5).

On va utiliser un groupe de sprites crée par l'éditeur (EditMap). A notre héros on lui indique le groupe qui est ennemie.  On fait de même pour le groupe de Sprite.

Ensuite en 10 on indique à la map qu'elle est la portion visible  à l'écran.

Et  pour finir on indique s'il y a un autofire défini.

 

Ensuite il faut définir  les méthodes qui seront appelées quand certaines touches du clavier seront appelées (action(Left|Right|Up|Down|Fire1|Fire2)). Les méthodes actionFire1 correspond à la touche 'A' et actionFire2 pour la touche 'Z'.