Pacman : allons plus loin

gamejava

Précédemment, nous avions vu comment dessiner Pacman et le faire déplacer. Cette fois, nous allons essayer de le déplacer à l’aide des flèches du clavier !🙂

Voici le code :

package Pacman;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;

public class Jeu extends JFrame implements KeyListener{

	private int compteur ;

	/* PACMAN COLORS */
	Color couleur1, couleur2;

	/* COORDINATES */
	public int x=10;
	public int y=30;

	/* DEFAULT COORDINATES */
	public final int X_INIT=10;
	public final int Y_INIT=30;

	/* DIRECTION */
	/*H : 1 B : 2 D : 3 G : 4*/
	public int direction = 0, nb;

	public boolean test=false;

	/* LIMITS */
	public final int X_MIN = 10;
	public final int X_MAX = 440;
	public final int Y_MIN = 30;
	public final int Y_MAX = 440;

	public Jeu(String titre, int largeur,int hauteur,int posX,int posY) {
		super(titre);
		setSize( largeur, hauteur );
		setVisible( true );
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocation(posX,posY);
		couleur2 = Color.yellow;
		addKeyListener(this);
	}

	/* METHODS KEYLISTENER */
	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		switch (e.getKeyCode()){
			/* HAUT */
			case KeyEvent.VK_UP :
				//y=y-10;
				direction=1;
				System.out.println("HAUT");
				break;
			/* BAS */
			case KeyEvent.VK_DOWN :
				//ver = 3;
				//y=y+10;
				direction=2;
				System.out.println("BAS");
				break;
			/* DROIT */
			case KeyEvent.VK_RIGHT :
				//ver = 1;
				//x=x+10;
				direction=3;
				System.out.println("DROIT");
				break;
			/* GAUCHE */
			case KeyEvent.VK_LEFT :
				//ver = 4;
				//x=x-10;
				direction=4;
				System.out.println("GAUCHE");
				break;
			default :
				System.out.println(e.getKeyCode());

		}

	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

	/* METHOD ANIMATING PACMAN */
	public void animer (int nbr_mouvement){
		nb=nbr_mouvement;
		for (compteur=0; compteur<nb; compteur++) {
			this.repaint();
			try {
				Thread.sleep(100);//pause between each pics.
			}
			catch (InterruptedException e) {
				e.printStackTrace();
			}
			nb++; // INFINI

		}
	}
	/* DRAWING METHOD */
	public void paint (Graphics g){
		/* BACKGROUND */
		g.setColor( Color.white);
		g.fillRect(0,0,500,500);

		Graphics2D g2 = (Graphics2D)g;

		/* COLOR ALTERNING */
		if (compteur%2==0){
			couleur1 = Color.yellow;
		}else{
			couleur1 = Color.white;
		}
		/* DRAW PACMAN ACCORDING THE DIRECTION CHOSEN */
		if(direction==0){
			x=x+10;
			g.setFont(new Font("Serif",Font.ITALIC,50));
			g.setColor(Color.ORANGE);
			g.drawString("PACMAN",150,250);
			g.setFont(new Font("Serif",Font.ITALIC,20));
			g.drawString("by A.RAVAUX",150,270);
			g.setColor( couleur1);
			g.fillArc(x, y, 50, 50,0, 360);
			g.setColor( couleur2);
			g.fillArc(x,y, 50, 50, 30, 280);
			g.setColor(Color.DARK_GRAY);
			g.fillArc(x+25, y+5, 7,7,0, 360);
		}else if(direction==1){
			y=y-10;
			g.setColor( couleur1);
			g.fillArc(x, y, 50, 50,0, 360);
			g.setColor( couleur2);
			g.fillArc(x, y, 50, 50,135, 250);
			g.setColor(Color.DARK_GRAY);
			g.fillArc(x+10, y+20, 7,7,0, 360);

		}else if(direction==2){
			y=y+10;
			g.setColor( couleur1);
			g.fillArc(x, y, 50, 50,0, 360);
			g.setColor( couleur2);
			g.fillArc(x, y, 50, 50,240, -290);
			g.setColor(Color.DARK_GRAY);
			g.fillArc(x+10, y+20, 7,7,0, 360);
		}else if(direction==3){
			x=x+10;
			g.setColor( couleur1);
			g.fillArc(x, y, 50, 50,0, 360);
			g.setColor( couleur2);
			g.fillArc(x,y, 50, 50, 30, 280);
			g.setColor(Color.DARK_GRAY);
			g.fillArc(x+25, y+5, 7,7,0, 360);
		}else if(direction==4){
			x=x-10;
			g.setColor( couleur1);
			g.fillArc(x, y, 50, 50,0, 360);
			g.setColor( couleur2);
			g.fillArc(x, y, 50, 50,140, -280);
			g.setColor(Color.DARK_GRAY);
			g.fillArc(x+25, y+5, 7,7,0, 360);
		}
		if(x==X_MAX || y==Y_MAX || x<X_MIN || y<Y_MIN){
			g.setColor( Color.white);
			g.fillRect(0,0,500,500);
			g.setFont(new Font("Serif",Font.ITALIC,50));
			g.setColor(Color.ORANGE);
			g.drawString("PERDU !",160,250);
			System.out.println("PERDU");
			nb=0;
		}
	}
	public static void main(String[] args) {
		Jeu animation = new Jeu("Pacman", 500, 500,200,150);
		animation.animer(1);
	}
}

Commentons un peu ce code.
Tout d’abord, notre objectif principal est d’ajouter la possibilité de faire bouger le pacman avec les touches du clavier. Je vais donc faire appel à une interface très particulière qui écoute le clavier, c’est à dire qui va regarder sur quelles touches vous appuyez. Ainsi, par la suite, nous pourrons lancer des actions selon la touche appuyée. On implémente cette interface :

public class Jeu extends JFrame implements KeyListener{

Et on ajoute ces méthodes liées à cette interface :

	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

J’ai ajouté des variables globales :

	private int compteur ;

	/* PACMAN COLORS */
	Color couleur1, couleur2;

	/* COORDINATES */
	public int x=10;
	public int y=30;

	/* DEFAULT COORDINATES */
	public final int X_INIT=10;
	public final int Y_INIT=30;

	/* DIRECTION */
	/*H : 1 B : 2 D : 3 G : 4*/
	public int direction = 0, nb;

	public boolean test=false;

	/* LIMITS */
	public final int X_MIN = 10;
	public final int X_MAX = 440;
	public final int Y_MIN = 30;
	public final int Y_MAX = 440;

Nous pouvons déjà deviner le rôle de certaines de ces variables. Le x et y sont bien entendu les coordonnées de pacman. couleur1 et couleur2 sont les couleurs du pacman, couleur2 est une couleur qui ne changera jamais, et qui est jaune.

Si vous avez lu l’article précédent sur pacman, vous avez pu reconnaître certaines parties du code très semblables. Entre autres le constructeur :

	public Jeu(String titre, int largeur,int hauteur,int posX,int posY) {
		super(titre);
		setSize( largeur, hauteur );
		setVisible( true );
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocation(posX,posY);
		couleur2 = Color.yellow;
		addKeyListener(this);
	}

Comme je vous le disais auparavant couleur2 est la couleur jaune. Le petite différence avec le constructeur de l’article précédent est qu’on a rajouté ceci : addKeyListener(this), c’est l’écoute du clavier.

Vous reconnaîtrez aussi la méthode animer(int nbr_mouvement) qui nous permettra d’animer Pacman :

	public void animer (int nbr_mouvement){
		nb=nbr_mouvement;
		for (compteur=0; compteur<nb; compteur++) {
			this.repaint();
			try {
				Thread.sleep(100);//pause between each pics.
			}
			catch (InterruptedException e) {
				e.printStackTrace();
			}
			nb++; // INFINI

		}
	}

La méthode animer() appelle la méthode repaint() qui redessine par desssus tout Pacman. A l’aide d’une boucle for, tant que le compteur est inférieur à nb , j’appelle donc repaint(). Seulement voilà, j’incrémente nb. Ainsi ma boucle est infinie et ne s’arrête jamais !! Enfin presque…Nous verrons ça plus loin.
Si vous êtes un lecteur aguerri et que vous avez pris le soin de lire l’article précédent, vous avez dû remarquer que ma façon de dessiner à l’infini la méthode repaint() est très différente. En effet, j’avais mis une condition if au lieu d’incrémenter :

		//on relance la méthode pour obtenir une boucle infinie !
		if(compteur==nbr_mouvement){
			compteur=0;
			x1=0;
			animer(48);
		}

Pas de panique, les deux méthodes sont bonnes, mais si j’ai choisi de créer une variable globale appelée nb qui reprend dans un premier temps la valeur passée en paramètre puis ensuite s’incrémente à l’infinie, c’est qu’il y a une bonne raison, et vous allez comprendre ça en lisant la suite de l’article😀

Gérons maintenant les touches et le dessin du pacman selon la touche choisie.

Nous avions tout à l’heure parlé de l’implémentation de de l’écoute du clavier (keylistener) : implements KeyListener, maintenant occupons nous des méthodes liées à cette écoute :

/* METHODS KEYLISTENER */
    @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub
        switch (e.getKeyCode()){
            /* HAUT */
            case KeyEvent.VK_UP :
                //y=y-10;
                direction=1;
                System.out.println("HAUT");
                break;
            /* BAS */
            case KeyEvent.VK_DOWN :
                //ver = 3;
                //y=y+10;
                direction=2;
                System.out.println("BAS");
                break;
            /* DROIT */
            case KeyEvent.VK_RIGHT :
                //ver = 1;
                //x=x+10;
                direction=3;
                System.out.println("DROIT");
                break;
            /* GAUCHE */
            case KeyEvent.VK_LEFT :
                //ver = 4;
                //x=x-10;
                direction=4;
                System.out.println("GAUCHE");
                break;
            default :
                System.out.println(e.getKeyCode());
 
        }
 
    }
 
    @Override
    public void keyReleased(KeyEvent arg0) {
        // TODO Auto-generated method stub
 
    }
 
    @Override
    public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub
 
    }

Lorsqu’on appuie sur une touche il y a trois évènements détectable : la touche est pressée, relachée et tapée.
La méthode keyPressed(KeyEvent e) gère les actions liée à la touche pressée, keyReleased(KeyEvent arg0) la touche relachée, et ,enfin, keyTyped(KeyEvent arg0) la touche tapée. L’utilité de distinguer ces trois évènements ? Imaginons que vous souhaitez détecter que votre utilisateur a bien touché la touche Shift/Majuscule avant d’appuyer sur la touche J…Ben c’est là qu’on va se servir de ces méthodes (en jouant avec un boolean par exemple).
Bon nous ce qui nous intéresse c’est keyPressed. On va retourner une valeur (direction) qui permettra ensuite de définir la forme du pacman.

En effet, dans la fonction paint on dessine le pacman selon la valeur direction, c’est-à-dire, si on va vers le bas, on dessine pas de la même façon notre pacman (la bouche vers le bas par exemple).

Dernier point, et ensuite je vous laisse vous amuser avec le code pour découvrir par vous même le dessin avec Swing.
Si le pacman touche les bords, nb prend la valeur 0 afin de sortir de notre boucle for (compteur=0; compteur<nb; compteur++) (de la méthode animer). En sortant de la boucle on arrête de redessiner.🙂

        if(x==X_MAX || y==Y_MAX || x<X_MIN || y<Y_MIN){
            g.setColor( Color.white);
            g.fillRect(0,0,500,500);
            g.setFont(new Font("Serif",Font.ITALIC,50));
            g.setColor(Color.ORANGE);
            g.drawString("PERDU !",160,250);
            System.out.println("PERDU");
            nb=0;
        }

Voilà, voilà, à vos claviers !

BONUS

Télécharger le jeu (format .jar)😀

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s