Petit serpent non définitif

Contenu du snippet

Ce code implémente un petit jeu de snake. Je me suis inspiré d'un source que j'ai améliorée un peu. Je remercie l'auteur de cette source originelle et je m'excuse auprès de lui pour avoir oublié son nom. Toute la source est commentée afin de permettre des modifications assez faciles à celui que ça tenterai.
Voilà j'espère que cette source pourra aider quelques personnes tout comme la source originnelle a pu m'aider à comprendre ce langage.

Source / Exemple :


// ----------------------------------
// Liste des importations de fichiers
// ----------------------------------

import java.awt.Graphics;
import java.awt.Color;
import java.awt.event.*;
import java.awt.*;
import java.awt.Font;
import java.awt.Image;
import java.awt.image.*;
import java.applet.*;

// -----------------------------------
// Implémentation de la classe Terrain 
// -----------------------------------

class Terrain {

	static final char CADRE='C', VIDE ='V', APPAT='A', DROITE='D', 
	GAUCHE='G', HAUT='H', BAS='B', BONUS='S'; // Définition des constantes caractères.
	private char t[][]; // Matrice du terrain
	public int largeur,hauteur; // Dimensions du terrain
	public int TailleBloc = 10;	 // Dimension d'une case en pixel ( non utilisé finalement )
	private Graphics g; // la feuille de dessin de l'applet	

// Constructeur 
Terrain(int l, int h, int tc, int Bloc, int Lev, Graphics appletG){
	g = appletG;		
	largeur = l;
	hauteur = h;
	TailleBloc = tc; // le fait de la laisser permet de ne pas avoir à tout changer si qq
					 // désire améliorer le programme en permettant des zones plus grandes
	
	// Création de l'aire
	t = new char [l+1][h+1];
	
	// Initialisation ( cadre au bord et vide dedans )
	for (int i=0;i<=largeur;i++) 
		for (int j=0;j<=hauteur;j++) {
			if ((i==0) | (i==largeur) | (j==0) | (j==hauteur)) 
				t[i][j]= CADRE;
			else t[i][j]=VIDE;
		}
		
	// Ajout des cases en fonction du niveau choisi (Option)
	if (Lev == 1) {
		for (int i=3;i<=largeur-3;i++) {
			for (int j=3;j<=hauteur-3;j++) {
				if ((i == j)|(i == largeur-j)) {
					t[i][j]= CADRE;
					}
				}
			}	
		}
	if (Lev == 2) {
		for (int i=3;i<=largeur-3;i++) {
			for (int j=3;j<=hauteur-3;j++) {
				if ((i == 4)|(i == 8)|(i == 12)|(i == 16)|(i == 20)|
					(i == 24)|(i == 28)|(i == 32)|(i == 36)|(i == 40)|
					(i == 44)|(i == 48)|(i == 52)|(i == 56)|(i == 60)|
					(i == 64)) {
					t[i][j]= CADRE;
					}
				}
			}	
		}
	if (Lev == 3) {
		for (int i=3;i<=largeur-3;i++) {
			for (int j=3;j<=hauteur-3;j++) {
				if ((j == 4)|(j == 8)|(j == 12)|(j == 16)|(j == 20)|
					(j == 24)|(j == 28)|(j == 32)|(j == 36)|(j == 40)) {
					t[i][j]= CADRE;
					}
				}
			}	
		}
	if (Lev == 4) {
		for (int i=3;i<=largeur-3;i++) {
			for (int j=3;j<=hauteur-3;j++) {
				if ((i == 4)|(i == 8)|(i == 12)|(i == 16)|(i == 20)|
					(i == 24)|(i == 28)|(i == 32)|(i == 36)|(i == 40)|
					(i == 44)|(i == 48)|(i == 52)|(i == 56)|(i == 60)|
					(i == 64)) {
					if ((j == 4)|(j == 8)|(j == 12)|(j == 16)|(j == 20)|
						(j == 24)|(j == 28)|(j == 32)|(j == 36)|(j == 40)) {
							t[i][j]= CADRE;
						}
					}
				}
			}	
		}
	if (Lev == 5) {
		for (int i=3;i<=largeur-3;i++) {
			for (int j=3;j<=hauteur-3;j++) {
				if ((i == 4)|(i == 10)|(i == 16)|(i == 22)|(i == 28)|
					(i == 34)|(i == 40)|(i == 46)|(i == 52)|(i == 58)|
					(i == 64)|(j == 4)|(j == 10)|(j == 16)|(j == 22)|
					(j == 28)) {
					if ((i != 7)&(i != 13)&(i != 19)&(i != 25)&
						(i != 31)&(i != 37)&(i != 43)&(i != 49)&
						(i != 55)&(i!=61)
						&(j != 7)&(j != 13)&(j != 19)&(j != 25)) {					
						t[i][j]= CADRE;						
						}
					}
				}
			}	
		}
		
	// Ajout des murs aléatoirement si besoin est (Option)
	if (Bloc > 0) {
		for (int i=1; i<=Bloc; i++) {
			Point position;
			position = new Point(0,0);
			do {
				int A=(int)(Math.floor(Math.random()*(largeur-5))+3);
				int B=(int)(Math.floor(Math.random()*(hauteur-5))+3);
				position.deplacer(A, B);
				} while (contenuCase(position) != VIDE);
			t[position.x][position.y] = CADRE;
			}
		}
	}

// Donne la taille "habitable de la zone"
public int taille() { return ((largeur-1)*(hauteur-1));}

// Fonctions qui permettent la représentation du Serpent
// -----------------------------------------------------

// Dessine la queue du serpent
public void dessineQueue(int A, int B) {
	g.setColor(Color.black);
	A= A*TailleBloc;
	B = (36 - hauteur + B)*TailleBloc;
	g.fillRect(A, B, TailleBloc, TailleBloc);
	g.setColor(Color.green);
	g.fillOval(A+3,B+3,4,4);
	g.setColor(Color.red);
	g.fillOval(A+4,B+4,2,2);
	}

// Dessine le corps du serpent
public void GQueue(int A, int B)
{
	B = B + 36 - hauteur;
	g.setColor(Color.black);
	g.fillRect(A*TailleBloc,B*TailleBloc,TailleBloc,TailleBloc);
	g.setColor(Color.green);
	g.fillOval(A*TailleBloc+2,B*TailleBloc+2,TailleBloc-4,TailleBloc-4);
	g.setColor(Color.red);
	g.fillOval(A*TailleBloc+3,B*TailleBloc+3,4,4);
	}	 

// Dessine la tête du Serpent
public void DessineTete(int A, int B, char C, int I) {
	g.setColor(Color.black);
	A= A*TailleBloc;
	B = (36 - hauteur + B)*TailleBloc;
	g.fillRect(A,B, TailleBloc, TailleBloc);
	if (C == HAUT) {
		g.setColor(Color.green);
		if (I > 0) { g.setColor(Color.yellow); }
		g.drawLine(A+1, B+5, A+1, B+7);
		g.drawLine(A+2, B+2, A+2, B+8);
		g.drawLine(A+3, B+1, A+3, B+9);
		g.drawLine(A+4, B, A+4, B+9);
		g.drawLine(A+5, B, A+5, B+9);
		g.drawLine(A+6, B+1, A+6, B+9);
		g.drawLine(A+7, B+2, A+7, B+8);
		g.drawLine(A+8, B+5, A+8, B+7);	
		g.setColor(Color.black);
		if (I > 0) { g.setColor(Color.red); }
		g.drawLine(A+3, B+3, A+3, B+5);
		g.drawLine(A+6, B+3, A+6, B+5);
		}
	if (C == BAS) {
		g.setColor(Color.green);
		if (I > 0) { g.setColor(Color.yellow); }
		g.drawLine(A+1, B+4, A+1, B+2);
		g.drawLine(A+2, B+7, A+2, B+1);
		g.drawLine(A+3, B+8, A+3, B);
		g.drawLine(A+4, B+9, A+4, B);
		g.drawLine(A+5, B+9, A+5, B);
		g.drawLine(A+6, B+8, A+6, B);
		g.drawLine(A+7, B+7, A+7, B+1);
		g.drawLine(A+8, B+4, A+8, B+2);	
		g.setColor(Color.black);
		if (I > 0) { g.setColor(Color.red); }
		g.drawLine(A+3, B+4, A+3, B+6);
		g.drawLine(A+6, B+4, A+6, B+6);
		}
	if (C == GAUCHE) {
		g.setColor(Color.green);
		if (I > 0) { g.setColor(Color.yellow); }
		g.drawLine(A+5, B+1, A+7, B+1);
		g.drawLine(A+2, B+2, A+8, B+2);
		g.drawLine(A+1, B+3, A+9, B+3);
		g.drawLine(A, B+4, A+9, B+4);
		g.drawLine(A, B+5, A+9, B+5);
		g.drawLine(A+1, B+6, A+9, B+6);
		g.drawLine(A+2, B+7, A+8, B+7);
		g.drawLine(A+5, B+8, A+7, B+8);	
		g.setColor(Color.black);
		if (I > 0) { g.setColor(Color.red); }
		g.drawLine(A+3, B+3, A+5, B+3);
		g.drawLine(A+3, B+6, A+5, B+6);
		}
	if (C == DROITE) {
		g.setColor(Color.green);
		if (I > 0) { g.setColor(Color.yellow); }
		g.drawLine(A+2, B+1, A+4, B+1);
		g.drawLine(A+1, B+2, A+7, B+2);
		g.drawLine(A, B+3, A+8, B+3);
		g.drawLine(A, B+4, A+9, B+4);
		g.drawLine(A, B+5, A+9, B+5);
		g.drawLine(A, B+6, A+8, B+6);
		g.drawLine(A+1, B+7, A+7, B+7);
		g.drawLine(A+2, B+8, A+4, B+8);	
		g.setColor(Color.black);
		if (I > 0) { g.setColor(Color.red); }
		g.drawLine(A+4, B+3, A+6, B+3);
		g.drawLine(A+4, B+6, A+6, B+6);
		}
	}

//Renvoi la valeur de la case demandée
public char contenuCase (Point p) {
	return t[p.x][p.y];
	}
	

// Ensemble des fonctions d'affichage
// ----------------------------------

// Affichage de la vitesse de jeu
public void AfficheVitesse(int Vit, int Vit2) {
	Font t16G = new Font("TimesRoman",Font.BOLD,16);
	Font t14N = new Font("TimesRoman",Font.PLAIN,14);
	g.setColor(Color.white);
	g.fillRect(310, 370, 120, 30);
	g.setColor(Color.blue);
	g.setFont(t14N);
	g.drawString("Attente", 320, 390);
	g.setColor(Color.black);
	g.setFont(t16G);
	if (Vit2 != 0) {
		g.drawString("" + Vit2, 370, 390);
		}
	else { g.drawString("" + Vit + " Fix", 370, 390); }
	}
	
// Affichage secondaire du score
public void AfficheScore(int S) {	
	Font t16G = new Font("TimesRoman",Font.BOLD,16);
	Font t14N = new Font("TimesRoman",Font.PLAIN,14);
	g.setColor(Color.white);
	g.fillRect(440,370,100,30);
	g.setColor(Color.blue);
	g.setFont(t14N);
	g.drawString("Score ", 450, 390);
	g.setColor(Color.black);
	g.setFont(t16G);
	g.drawString("" + S, 495, 390);
	}

// Efface la zone d'affichage pour mise à jour
public void Effacer() {
	g.setColor(Color.black);
	g.fillRect(0,0,700,400);
	}	
	
// Si le joueur à pris un bonus de taille
public void AfficheGrandir(int Nb) {
	AfficheRien();
	Font t16G = new Font("TimesRoman",Font.BOLD,16);
	Font t14N = new Font("TimesRoman",Font.PLAIN,14);
	g.setColor(Color.blue);
	g.setFont(t14N);
	g.drawString("Dernier Bonus", 10, 390);
	g.setColor(Color.black);
	g.setFont(t16G);
	g.drawString("Taille + " + Nb, 100, 390);
	}
	
// Si le joueur a pris un bonus de vitesse
public void AfficheRalentir(int Nb) {
	Font t16G = new Font("TimesRoman",Font.BOLD,16);
	Font t14N = new Font("TimesRoman",Font.PLAIN,14);
	AfficheRien();
	g.setColor(Color.blue);
	g.setFont(t14N);
	g.drawString("Dernier Bonus", 10, 390);
	g.setFont(t16G);
	g.setColor(Color.black);
	g.drawString("Ralenti de " + Nb, 100, 390);
	}
	
// Si le joueur a pris un malus de vitesse
public void AfficheAccelerer(int Nb) {
	Font t16G = new Font("TimesRoman",Font.BOLD,16);
	Font t14N = new Font("TimesRoman",Font.PLAIN,14);
	AfficheRien();
	g.setColor(Color.blue);
	g.setFont(t14N);
	g.drawString("Dernier Bonus", 10, 390);
	g.setColor(Color.black);
	g.setFont(t16G);
	g.drawString("Accelere de " + Nb, 100, 390);
	}
	
// Si le bonus provoque une inversion des touches
public void AfficheInverse() {
    AfficheRien();
	Font t18G = new Font("TimesRoman",Font.BOLD,18);
	Font t14N = new Font("TimesRoman",Font.PLAIN,14);
	g.setColor(Color.blue);
	g.setFont(t14N);
	g.drawString("Dernier Bonus", 10, 390);
	g.setColor(Color.black);
	g.setFont(t18G);
	g.drawString("Touches Inversees", 100, 390);
	}

// Affiche le nombre de tours restants
public void ResteInverse(int Rest) {
	Font t18G = new Font("TimesRoman",Font.BOLD,18);
	Font t14N = new Font("TimesRoman",Font.PLAIN,14);
	if (Rest > 0) {
		g.setColor(Color.red);
		g.fillRect(540,370,120,30);
		g.setColor(Color.blue);
		g.setFont(t14N);
		g.drawString("INVERSEES", 550, 390);
		g.setColor(Color.black);
		g.setFont(t18G);
		g.drawString("" + Rest, 630, 390); 
		}
	else {
		g.setColor(Color.white);
		g.fillRect(540,370,120,30);
		}
	}
	
// Le dernier Bonus était un faux bonus
public void AfficheRien() {
	Font t14N = new Font("TimesRoman",Font.PLAIN,14);
	g.setColor(Color.white);
	g.fillRect(0, 370, 250, 30);
	g.setFont(t14N);
	g.setColor(Color.blue);
	g.drawString("Dernier Bonus", 10, 390);
	}
	
// Redessine l'aire de jeu	
public void redessine(){
	Point p = new Point(0,0);
	for (int i = 0; i <= largeur; i++) 
		for (int j = 0; j <= hauteur ; j++){
			p.deplacer(i,j);
			dessineCase(p);
		}
	}
	
// Dessine la case en fonction de son contenu	
public void dessineCase (Point p) {
	int PY = 36 - hauteur + p.y;
	switch (t[p.x][p.y]) {			    
		case APPAT: 
			g.setColor(Color.black);
			g.fillRect( p.x*TailleBloc, PY*TailleBloc,TailleBloc,TailleBloc);
			g.setColor(Color.red);
			g.drawLine( p.x*TailleBloc+2, PY*TailleBloc+2,p.x*TailleBloc+7, PY*TailleBloc+2);
			g.drawLine( p.x*TailleBloc+1, PY*TailleBloc+3,p.x*TailleBloc+8, PY*TailleBloc+3);
			g.drawLine( p.x*TailleBloc+0, PY*TailleBloc+4,p.x*TailleBloc+9, PY*TailleBloc+4);
			g.drawLine( p.x*TailleBloc+0, PY*TailleBloc+5,p.x*TailleBloc+9, PY*TailleBloc+5);
			g.drawLine( p.x*TailleBloc+0, PY*TailleBloc+6,p.x*TailleBloc+9, PY*TailleBloc+6);
			g.drawLine( p.x*TailleBloc+1, PY*TailleBloc+7,p.x*TailleBloc+8, PY*TailleBloc+7);
			g.drawLine( p.x*TailleBloc+1, PY*TailleBloc+8,p.x*TailleBloc+8, PY*TailleBloc+8);
			g.drawLine( p.x*TailleBloc+2, PY*TailleBloc+9,p.x*TailleBloc+3, PY*TailleBloc+9);
			g.drawLine( p.x*TailleBloc+6, PY*TailleBloc+9,p.x*TailleBloc+7, PY*TailleBloc+9);
			g.setColor(Color.green);
			g.drawLine( p.x*TailleBloc+5, PY*TailleBloc+1,p.x*TailleBloc+5, PY*TailleBloc+1);
			g.drawLine( p.x*TailleBloc+6, PY*TailleBloc+0,p.x*TailleBloc+6, PY*TailleBloc+0);
			break;
		case CADRE: 
			g.setColor(Color.black);
			g.fillRect( p.x*TailleBloc, PY*TailleBloc,TailleBloc,TailleBloc);
			g.setColor(Color.lightGray); 
			g.fillRect( p.x*TailleBloc, PY*TailleBloc, TailleBloc , TailleBloc);
			g.setColor(Color.white);
			g.drawLine( p.x*TailleBloc, PY*TailleBloc,p.x*TailleBloc, PY*TailleBloc+8);
			g.drawLine( p.x*TailleBloc, PY*TailleBloc,p.x*TailleBloc+8, PY*TailleBloc);
			g.setColor(Color.gray);
			g.drawLine( p.x*TailleBloc+9, PY*TailleBloc+9,p.x*TailleBloc+9, PY*TailleBloc);
			g.drawLine( p.x*TailleBloc+9, PY*TailleBloc+9,p.x*TailleBloc, PY*TailleBloc+9);
			break;
		case VIDE: 
			g.setColor(Color.black); 
			g.fillRect( p.x*TailleBloc, PY*TailleBloc, TailleBloc , TailleBloc);        
			break;
		case BONUS:
			g.setColor(Color.black);
			g.fillRect( p.x*TailleBloc, PY*TailleBloc,TailleBloc,TailleBloc);
			//g.setColor(Color.yellow);
			//g.fillOval(p.x*TailleBloc,PY*TailleBloc,TailleBloc,TailleBloc);
			g.setColor(Color.red);
			g.drawLine( p.x*TailleBloc+2, PY*TailleBloc+2,p.x*TailleBloc+7, PY*TailleBloc+2);
			g.drawLine( p.x*TailleBloc+1, PY*TailleBloc+3,p.x*TailleBloc+8, PY*TailleBloc+3);
			g.drawLine( p.x*TailleBloc+0, PY*TailleBloc+4,p.x*TailleBloc+9, PY*TailleBloc+4);
			g.drawLine( p.x*TailleBloc+0, PY*TailleBloc+5,p.x*TailleBloc+9, PY*TailleBloc+5);
			g.drawLine( p.x*TailleBloc+0, PY*TailleBloc+6,p.x*TailleBloc+9, PY*TailleBloc+6);
			g.drawLine( p.x*TailleBloc+1, PY*TailleBloc+7,p.x*TailleBloc+8, PY*TailleBloc+7);
			g.drawLine( p.x*TailleBloc+1, PY*TailleBloc+8,p.x*TailleBloc+8, PY*TailleBloc+8);
			g.drawLine( p.x*TailleBloc+2, PY*TailleBloc+9,p.x*TailleBloc+3, PY*TailleBloc+9);
			g.drawLine( p.x*TailleBloc+6, PY*TailleBloc+9,p.x*TailleBloc+7, PY*TailleBloc+9);
			g.setColor(Color.green);
			g.drawLine( p.x*TailleBloc+5, PY*TailleBloc+1,p.x*TailleBloc+5, PY*TailleBloc+1);
			g.drawLine( p.x*TailleBloc+6, PY*TailleBloc+0,p.x*TailleBloc+6, PY*TailleBloc+0);
			// 
			g.setColor(Color.yellow);
			g.drawLine(p.x*TailleBloc+3, PY*TailleBloc+2, p.x*TailleBloc+6, PY*TailleBloc+2);
			g.drawLine(p.x*TailleBloc+2, PY*TailleBloc+3, p.x*TailleBloc+3, PY*TailleBloc+3);
			g.drawLine(p.x*TailleBloc+6, PY*TailleBloc+2, p.x*TailleBloc+6, PY*TailleBloc+5);
			g.drawLine(p.x*TailleBloc+7, PY*TailleBloc+3, p.x*TailleBloc+7, PY*TailleBloc+4);
			g.drawLine(p.x*TailleBloc+4, PY*TailleBloc+6, p.x*TailleBloc+5, PY*TailleBloc+6);
			g.drawLine(p.x*TailleBloc+4, PY*TailleBloc+7, p.x*TailleBloc+5, PY*TailleBloc+7);
			g.drawLine(p.x*TailleBloc+4, PY*TailleBloc+9, p.x*TailleBloc+5, PY*TailleBloc+9);		
			break;
		default: 
			g.setColor(Color.black); 
			g.fillRect( p.x*TailleBloc, PY*TailleBloc, TailleBloc , TailleBloc);        
			break;
		}		
	}	

	
// Fonctions de modification de matrice
// -------------------------------------

// Modifie le point en changeant sa valeur
public void modifCase (Point p, char v) {
	t[p.x][p.y]=v;
	}	 

// Modifie le point et le réaffiche
public void majCase(Point p, char v) {
	modifCase(p, v);
	dessineCase(p);		
	}

}

// ---------------------------------
// Implémentation de la Classe Point
// ---------------------------------

class Point {
	public int x, y; // Un point est défini par ses coordonnées
	
// Constructeur	
Point(int initx, int inity){
	x=initx;
	y=inity;
	}
	
// Deplace un point en chageant ses coordonnées
public void deplacer(int cx, int cy){
	x=cx;
	y=cy;
	}

// Deplace un point dans une direction définie
public void avance(char direction){
	switch (direction) {
		case Terrain.DROITE: 
			x++;
			break;
		case Terrain.GAUCHE: 
			x--;
			break;
		case Terrain.BAS:
			y++;
			break;
		case Terrain.HAUT:	 
			y--;
			break;
		}
	}
}

// -----------------------------------
// Implémentation de la classe Serpent
// -----------------------------------

class Serpent {
	String       msg; // Message donné suivant certaines conditions
	Point  pTete = new Point(2,2); // Position de la tete du Serpent
	Point  pQueue = new Point(2,2); // Position de la queue du serpent
	int          longueur = 1; // longueur du serpent
	Terrain      terrain; // le serpent est lié à une zone de jeu
	int        temps; // sert pour la vitesse en fonction de la prise des bonus
	char         directionTete = Terrain.DROITE; // direction du serpent
	char         directionQueue; // Vers ou la queue du serpent va aller
	int          grandir = 0; // croissance du serpent
	int          Inverse = 0; // touches inversées ou non

// Constructeur
Serpent (Terrain t, int Tp) {
	terrain=t;
	temps = Tp;
	terrain.majCase(pTete,directionTete);
	}	
	
// Renvoi la position en X de la tete du serpent	
public int SobtenirX() {
	return pTete.x;
	}
	
// Renvoi la position en Y de la queue du serpent
public int SobtenirY() {
	return pTete.y;
	}
	
// Appelle la fonction pour dessiner le corps du serpent de la classe terrain
public void DessineQueue() {
	terrain.GQueue(pTete.x, pTete.y);
	}			
	
// Fonction qui gère les mouvements du serpent
public boolean avance(){
	boolean fini=false;
	DessineQueue();
	terrain.modifCase(pTete,directionTete);
	// fait avancer la tete
	pTete.avance(directionTete);
	// et vérifie sue quoi elle tombe
	switch (terrain.contenuCase(pTete)) {
		case Terrain.CADRE: // sur le cadre
			msg = " Boum Cadre!";
			fini=true; 
			break;
		case Terrain.HAUT: // sur son corps
		case Terrain.BAS: 
		case Terrain.DROITE: 
		case Terrain.GAUCHE:
			msg = " Queue mordue!";
			fini=true; 
			break;
		case Terrain.APPAT: // sur un appat
			grandir+=1;
			break;
		case Terrain.BONUS: // sur un bonus
			int Haz = (int)Math.floor(Math.random()*14);
			if (Haz == 0) { 
				grandir+=2;
				terrain.AfficheGrandir(2);
				}
			if (Haz == 1) { 
				grandir+=4;
				terrain.AfficheGrandir(4);
				}
			if (Haz == 2) { 
				grandir+=6;
				terrain.AfficheGrandir(6);
				}
			if (Haz == 3) { 
				grandir+=8;
				terrain.AfficheGrandir(8);
				}
			if (Haz == 4) { 
				grandir+=10;
				terrain.AfficheGrandir(10);
				}
			if (Haz == 5) {
				temps+=10;
				grandir+=1;
				terrain.AfficheRalentir(10);
				}
			if (Haz == 6) {
				temps+=-10;
				grandir+=1;
				terrain.AfficheAccelerer(10);
				}			
			if (Haz == 7) { 
				Inverse += 10;
				grandir+=1; 
				terrain.AfficheInverse();
				}
			if (Haz == 8) { 
				grandir += 20; 
				terrain.AfficheGrandir(20);
				}
			if (Haz == 9) {
				temps+=20;
				grandir+=1;
				terrain.AfficheRalentir(20);
				}
			if (Haz == 10) {
				temps+=-20;
				grandir+=1;
				terrain.AfficheAccelerer(20);
				}
			if (Haz == 11) {
				temps+=25;
				grandir+=1;
				terrain.AfficheRalentir(25);
				}
			if (Haz == 12) {
				temps+=-25;
				grandir+=1;
				terrain.AfficheAccelerer(25);
				}
			if (Haz > 12) {
				terrain.AfficheRien();
				}
		}
	// on met tout cela à jour (tete)
	terrain.majCase(pTete,directionTete);
	terrain.DessineTete(pTete.x, pTete.y, directionTete, Inverse);
	// puis on gere la queue
	if  (grandir==0) {	// le serpent ne doit pas grandir
		// alors on deplace la queue
		directionQueue = terrain.contenuCase(pQueue);								  
		terrain.majCase(pQueue,Terrain.VIDE);
		pQueue.avance(directionQueue);
		if (longueur > 1) {terrain.dessineQueue(pQueue.x,pQueue.y);}
		} 
	else { 
		// le serpent doit grandir, donc la queue ne bouge pas
		if (longueur == 1) {terrain.dessineQueue(pQueue.x,pQueue.y);}
		grandir--; 
		longueur++;
		}
	return fini;
	}
	
// Renvoi la direction de la tete	
public char WhatDirection() {
	return directionTete;
	}
	
// fonction qui inverse la direction si le bonus est activé	
public void defDirection(char d){
	directionTete = d;
	if (Inverse != 0)
	    {
	    Inverse--;
	    if (WhatDirection() == 'H') { directionTete = 'B'; }
	    else {
			if (WhatDirection() == 'B') { directionTete = 'H'; }
	   		 }
		if (WhatDirection() == 'G') { directionTete = 'D'; }
	    else {
			if (WhatDirection() == 'D') { directionTete = 'G'; }
	   		}
		}
	}
	
}

// ---------------------------------
// Implémentation de la classe Appat
// ---------------------------------

class Appat{
	private Point position = new Point(0,0); //Un appat est un point
	private int vieAppat; // Avec une durée de vie
	private Terrain terrain; // qui dépend d'un terrain
	
// constructeur		
Appat (Terrain t){
	terrain = t;
	}
	
// renvoi la position en X de l'appat
public int AobtenirX() {
	return position.x;
	}
	
// renvoi la position en Y de l'appat
public int AobtenirY() {
	return position.y;
	}
	
// tue l'appat
public void tuer(){
	vieAppat = 0;		
	}
	
// la vie de l'appat
public void vivre(int D){
	if (vieAppat > 0) // si il lui reste du temps à vivre, on lui diminue
		vieAppat--;	  
	if (vieAppat==0) { // sinon, on le deplace en lui mettant sa durée de vie à fond
		if (terrain.contenuCase(position)==Terrain.APPAT) 
			terrain.majCase(position,Terrain.VIDE);
		do {
			position.x=(int)Math.floor(Math.random()*(terrain.largeur));
			position.y=(int)Math.floor(Math.random()*(terrain.hauteur));
			} while (terrain.contenuCase(position) != Terrain.VIDE);
		vieAppat=D;
		terrain.majCase(position, Terrain.APPAT);
		}
	}
}

// ---------------------------------
// Implémentation de la classe Bonus
// ---------------------------------

class Bonus{
	private Point position = new Point(0,0); //Un bonus est un point
	private int vieBonus = 0; // Avec une duree de vie
	private Terrain terrain; // qui appartient à un terrain
	
// constructeur
Bonus (Terrain t){
	terrain = t;
	}
	
// renvoi la position en X du bonus
public int BobtenirX() {
	return position.x;
	}
	
// renvoi la position en Y du bonus
public int BobtenirY() {
	return position.y;
	}
	
// Permet de tuer un bonus ( cela ne sert pas pour le moment )
public void tuer(){
	vieBonus = 0;		
	}
	
// c'est la vie d'un bonus
public void vivre(int D){
	if (vieBonus > 0) // si elle vit encore, on la diminue
		vieBonus--;	  
	if (vieBonus==0) { // sinon on la deplace et lui redonne toute sa vie
		if (terrain.contenuCase(position)==Terrain.BONUS) 
			terrain.majCase(position,Terrain.VIDE);
		do {
			position.x=(int)Math.floor(Math.random()*(terrain.largeur));
			position.y=(int)Math.floor(Math.random()*(terrain.hauteur));
			} while (terrain.contenuCase(position) != Terrain.VIDE);
		vieBonus=D;
		terrain.majCase(position, Terrain.BONUS);
		}
	}
}

// -------------------------------
// Classe Principale du JeuSerpent
// -------------------------------

public class JeuSerpent extends java.applet.Applet	 
		implements Runnable, KeyListener, ItemListener, ActionListener{
Thread runner; // tache qui permet notamment le sleep
Terrain t;     // le terrain de jeu
Serpent s;	   // le serpent
Image IFin;    // image de fin
//AudioClip Avaler;  // les bruitages du jeu sont en commentaires car nous n'avons pas
//AudioClip Detruit; // d'enceintes
//AudioClip Music;
int TailleBloc = 10;
int VitesseGlobale = 150;  // Vitesses de base
int vitesse = 150; // Les deux vitesses servent à gérer la vitesse variable et fixe (option)
int hauteur = 19; // Options de base du jeu
int largeur = 39;
int nbpommes = 10;
int nbbonus = 0;
int duree = 150;
int bonus = 0;
int modif = 0;
int VitesseBloquee;
int MurMob = 0;
int Reste; // Nb de pommes qu'il reste à manger avant la fin
int Level = 0; 
int Victory = 0; // Si la victoire est enfin votre !
int DirectionChanged = 0; // pour les changement de direction trop rapides qui tuaient
int Arret = 0; // Gestion du stop() du thread qui affichait des exceptions !
Choice AireLong; // Les menus pour les Options
Choice AireHaut;
Choice Vitesse;
Choice NbPommes;
Choice Ttl;
Choice Bonus;
Choice Modif;
Choice Mur;
Choice Niveau;
Button Lancer; // Bouton de lancement de partie.
Appat Pom[]; // Tableau d'appats
Bonus Bon[]; // Tableau de bonus

// Fonction d'initialisation de l'applet
public void init() {
	this.addKeyListener(this); // Lancement du keylistener sur l'applet
	//Avaler=getAudioClip(getCodeBase(),"gulp.wav");
	//Detruit=getAudioClip(getCodeBase(),"explos.wav");
	//Music=getAudioClip(getCodeBase(),"muse.wav");
		// Menu pour la longueur de la zone de jeu
		AireLong = new Choice();
		AireLong.addItem("10 Long");
		AireLong.addItem("11 Long");
		AireLong.addItem("12 Long");
		AireLong.addItem("13 Long");
		AireLong.addItem("14 Long");
		AireLong.addItem("15 Long");
		AireLong.addItem("16 Long");
		AireLong.addItem("17 Long");
		AireLong.addItem("18 Long");
		AireLong.addItem("19 Long");
        AireLong.addItem("20 Long");
		AireLong.addItem("21 Long");
		AireLong.addItem("22 Long");
		AireLong.addItem("23 Long");
		AireLong.addItem("24 Long");
		AireLong.addItem("25 Long");
		AireLong.addItem("26 Long");
		AireLong.addItem("27 Long");
		AireLong.addItem("28 Long");
		AireLong.addItem("29 Long");
		AireLong.addItem("30 Long");
		AireLong.addItem("31 Long");
		AireLong.addItem("32 Long");
		AireLong.addItem("33 Long");
		AireLong.addItem("34 Long");
		AireLong.addItem("35 Long");
		AireLong.addItem("36 Long");
		AireLong.addItem("37 Long");
		AireLong.addItem("38 Long");
		AireLong.addItem("39 Long");
		AireLong.addItem("40 Long");
		AireLong.addItem("41 Long");
		AireLong.addItem("42 Long");
		AireLong.addItem("43 Long");
		AireLong.addItem("44 Long");
		AireLong.addItem("45 Long");
		AireLong.addItem("46 Long");
		AireLong.addItem("47 Long");
		AireLong.addItem("48 Long");
		AireLong.addItem("49 Long");
		AireLong.addItem("50 Long");
		AireLong.addItem("51 Long");
		AireLong.addItem("52 Long");
		AireLong.addItem("53 Long");
		AireLong.addItem("54 Long");
		AireLong.addItem("55 Long");
		AireLong.addItem("56 Long");
		AireLong.addItem("57 Long");
		AireLong.addItem("58 Long");
		AireLong.addItem("59 Long");
		AireLong.addItem("60 Long");
		AireLong.addItem("61 Long");
		AireLong.addItem("62 Long");
		AireLong.addItem("63 Long");
		AireLong.addItem("64 Long");
		AireLong.addItem("65 Long");
		AireLong.addItem("66 Long");
		AireLong.addItem("67 Long");
		AireLong.addItem("68 Long");
		AireLong.addItem("69 Long");
		add(AireLong);	
		AireLong.select("40 Long");
		AireLong.addItemListener(this);	

		// menu pour la hauteur de l'aire de jeu
		AireHaut = new Choice();
		AireHaut.addItem("10 Haut");
		AireHaut.addItem("11 Haut");
		AireHaut.addItem("12 Haut");
		AireHaut.addItem("13 Haut");
		AireHaut.addItem("14 Haut");
		AireHaut.addItem("15 Haut");
		AireHaut.addItem("16 Haut");
		AireHaut.addItem("17 Haut");
		AireHaut.addItem("18 Haut");
		AireHaut.addItem("19 Haut");
        AireHaut.addItem("20 Haut");
		AireHaut.addItem("21 Haut");
		AireHaut.addItem("22 Haut");
		AireHaut.addItem("23 Haut");
		AireHaut.addItem("24 Haut");
		AireHaut.addItem("25 Haut");
		AireHaut.addItem("26 Haut");
		AireHaut.addItem("27 Haut");
		AireHaut.addItem("28 Haut");
		AireHaut.addItem("29 Haut");
		AireHaut.addItem("30 Haut");
		add(AireHaut);	
		AireHaut.select("20 Haut");
		AireHaut.addItemListener(this);
		
		// menu pour le temps de pause du jeu
		Vitesse = new Choice();
		Vitesse.addItem("Timer Tres Court");
		Vitesse.addItem("Timer Court");
		Vitesse.addItem("Timer Normal");
		Vitesse.addItem("Timer Long");
		Vitesse.addItem("Timer Tres Long");		
		add(Vitesse);	
		Vitesse.select("Timer Normal");
		Vitesse.addItemListener(this);

		// menu pour le nombre de pommes
		NbPommes = new Choice();
		NbPommes.addItem("1 Pommes");
		NbPommes.addItem("2 Pommes");
		NbPommes.addItem("3 Pommes");
		NbPommes.addItem("4 Pommes");
		NbPommes.addItem("5 Pommes");
		NbPommes.addItem("6 Pommes");
		NbPommes.addItem("7 Pommes");
		NbPommes.addItem("8 Pommes");
		NbPommes.addItem("9 Pommes");
		NbPommes.addItem("10 Pommes");
		NbPommes.addItem("11 Pommes");
		NbPommes.addItem("12 Pommes");
		NbPommes.addItem("13 Pommes");
		NbPommes.addItem("14 Pommes");
		NbPommes.addItem("15 Pommes");
		NbPommes.addItem("16 Pommes");
		NbPommes.addItem("17 Pommes");
		NbPommes.addItem("18 Pommes");
		NbPommes.addItem("19 Pommes");
		NbPommes.addItem("20 Pommes");
		NbPommes.addItem("21 Pommes");
		NbPommes.addItem("22 Pommes");
		NbPommes.addItem("23 Pommes");
		NbPommes.addItem("24 Pommes");
		NbPommes.addItem("25 Pommes");
		add(NbPommes);	
		NbPommes.select("10 Pommes");
		NbPommes.addItemListener(this);	
		
		// menu pour la duree de vie des appats
		Ttl = new Choice();
		Ttl.addItem("Vie Tres Courte");
		Ttl.addItem("Vie Courte");
		Ttl.addItem("Vie Normale");
		Ttl.addItem("Vie Longue");
		Ttl.addItem("Vie Tres Longue");		
		add(Ttl);	
		Ttl.select("Vie Normale");
		Ttl.addItemListener(this);
	
		// menu : avec ou sans bonus
		Bonus = new Choice();
		Bonus.addItem("Bonus Non");
		Bonus.addItem("Bonus Oui");		
		add(Bonus);	
		Bonus.select("Bonus Non");
		Bonus.addItemListener(this);

		// menu : vitesse fixe ou non
		Modif = new Choice();
		Modif.addItem("Vitesse Fixe");
		Modif.addItem("Vitesse Variable");		
		add(Modif);	
		Modif.select("Vitesse Fixe");
		Modif.addItemListener(this);

		// nombre de murs au hasard (marche avec l'option terrain random)
		Mur = new Choice();
		Mur.addItem("Mur 0");
		Mur.addItem("Mur 1");	
		Mur.addItem("Mur 2");
		Mur.addItem("Mur 3");
		Mur.addItem("Mur 4");
		Mur.addItem("Mur 5");
		Mur.addItem("Mur 6");
		Mur.addItem("Mur 7");
		Mur.addItem("Mur 8");
		Mur.addItem("Mur 9");
		Mur.addItem("Mur 10");
		Mur.addItem("Mur 11");
		Mur.addItem("Mur 12");
		Mur.addItem("Mur 13");
		Mur.addItem("Mur 14");
		Mur.addItem("Mur 15");
		Mur.addItem("Mur 16");
		Mur.addItem("Mur 17");
		Mur.addItem("Mur 18");
		Mur.addItem("Mur 19");
		Mur.addItem("Mur 20");	
		Mur.addItem("Mur 21");
		Mur.addItem("Mur 22");
		Mur.addItem("Mur 23");
		Mur.addItem("Mur 24");
		Mur.addItem("Mur 25");
		add(Mur);	
		Mur.select("Mur 0");
		Mur.addItemListener(this);

		// choix du terrain de jeu
		Niveau = new Choice();
		Niveau.addItem("Basique");
		Niveau.addItem("Etoile");
		Niveau.addItem("Vertical");
		Niveau.addItem("Horizontal");
		Niveau.addItem("Damier");
		Niveau.addItem("Cible");
		Niveau.addItem("Random");			
		add(Niveau);	
		Niveau.select("Basique");
		Niveau.addItemListener(this);

		// bouton de lancement
		add(Lancer = new Button ("Start Game"));
		Lancer.addActionListener(this);

		// chargement de l'image de fin
		IFin = getImage(getCodeBase(),"fin.gif");

	// Création des entités de jeu et inialisation certains parametre de classe
	t = new Terrain(largeur,hauteur,TailleBloc,MurMob,Level,this.getGraphics());
	s = new Serpent (t,vitesse);
	Pom = new Appat[30];
	Bon = new Bonus[30];
	for (int I=1;I<=nbpommes;I++) {
		Pom[I] = new Appat(t);
		}
	VitesseGlobale = s.temps;
	VitesseBloquee = s.temps;
	}

// Se declenche quand on clique sur le bouton "Start"
public void actionPerformed(ActionEvent e) {
	Victory = 0; // la partie se lance donc victoire est nulle
	if (Arret == 0) { stop(); } // si le jeu n'était pas arrêté, on le fait
	Arret = 0;
	int VitesseV = (Vitesse.getSelectedIndex()+1)*50; // on réinitialise la vitesse
	vitesse = VitesseV; // cela évite un bug
	// on recrée toutes les entités
	t = new Terrain(largeur,hauteur,TailleBloc,MurMob,Level,this.getGraphics());
	s = new Serpent (t,vitesse);
	Pom = new Appat[30];
	for (int I=1;I<=nbpommes;I++) {
		Pom[I] = new Appat(t);
		}
	if (bonus == 1) {
		nbbonus = (int)(((nbpommes-1)/5)+1);
		for (int I=1;I<=nbbonus;I++) {
			Bon[I] = new Bonus (t);
			}
		}
	VitesseGlobale = s.temps;
	VitesseBloquee = s.temps;
	// on redessine la fenetre
	repaint();
	// on lance la tache
	start();		
	}

// Si on touche aux menus déroulants pour changer les options de jeu
public void itemStateChanged(ItemEvent e)  {
	// Récupération des valeurs des champs
	int AireLongV = AireLong.getSelectedIndex()+10 ;
	int AireHautV = AireHaut.getSelectedIndex()+10 ;
	int VitesseV = (Vitesse.getSelectedIndex()+1)*50;
	int NbPommesV = NbPommes.getSelectedIndex()+1;
	int TtlV = (Ttl.getSelectedIndex()+1)*50;
	int BonusV = Bonus.getSelectedIndex();
	int ModifV = Modif.getSelectedIndex();
	int MurV = Mur.getSelectedIndex();
	int NiveauV = Niveau.getSelectedIndex();
	//On les met dans les valeurs des constantes
	Level = NiveauV;
	VitesseGlobale = VitesseV; 
	vitesse = VitesseV;		
	hauteur = AireHautV;
	largeur = AireLongV;
	nbpommes = NbPommesV;
	duree = TtlV;
	bonus = BonusV;
	modif = ModifV;
	MurMob = MurV;
	Victory = 0;
	// On n'autorise les murs aléatoires que dans le niveau correspondant
	if (Level != 6) { MurMob = 0; }
	if (Arret == 0) {stop();}
	// On indique que le jeu est arrété
	Arret = 1;
	}

// Lancement d'un thread
public void start() {
	if (runner == null); {
		runner = new Thread(this);
		runner.start();
		}
	}

// Arret d'un thread
public void stop() {
	if (runner != null); {
		runner.stop();
		runner = null;
		}
	}
	
// fonction qui tourne quand le thread est actif
public void run() {
	// Reclame le focus sur la fenetre de jeu
	this.requestFocus();
	while (true) {
		Reste = t.taille()/2 - s.longueur - MurMob;
		// si reste est négatif alors le joueur a gagné
		if (Reste < 0) {
			//Music.play();	
			Victory = 1;
			repaint();
			stop();
			}
		// anvance le serpent et si retourne alors c que le serpent est salement mort
		if (s.avance()) {
			//Detruit.play();
			this.showStatus(s.msg+" ---   MaDe By StOrM   ---   Score = "+s.longueur+" --- Victoire était dans "+Reste+" Pomme(s)");
			stop();
			}
		// Si la direction a été modifiée ce tour ci
		DirectionChanged = 0;	
		VitesseGlobale = s.temps;
		// On fait vivre les pommes	
		for (int I=1;I<=nbpommes;I++) {
			Pom[I].vivre(duree);
			// Si le serpent est sur une pomme alors on tue la pomme
			if (Pom[I].AobtenirX() == s.SobtenirX())
				if (Pom[I].AobtenirY() == s.SobtenirY()) {
					//Avaler.play();
					Pom[I].tuer();
					}
			}
		// si oui, on fait vivre les bonus
		if (bonus == 1) {
			int nbbonus = (int)(((nbpommes-1)/5)+1);
			for (int I=1;I<=nbbonus;I++) {				
				Bon[I].vivre(500);
				}
			}
		// on temporise
		try {Thread.sleep(vitesse);}
		catch (InterruptedException e) { }
		// Affiche les informations dans la barre de status
		showStatus("MaDe By StOrM   ---   Score = "+s.longueur+" --- Victoire dans "+Reste+" Pomme(s)");
		// on modifie la vitesse actuelle en fonction des besoins et options
		if (modif == 0) {
			vitesse = VitesseBloquee;
			}
		else {
			vitesse = (int)(VitesseGlobale - ((s.longueur)/3));
			}
		// en dessous de 20 c'est souvent injouable donc on limite
		if (vitesse < 20) {
			vitesse = 20;
			}
		// on affiche les variables à l'écran
		if (modif == 1) {
			t.AfficheVitesse(VitesseGlobale,vitesse);
			}
		else {
			t.AfficheVitesse(VitesseBloquee,0);
			}
		t.AfficheScore(s.longueur);
		t.ResteInverse(s.Inverse);
		}
	}
	
// Fonction qui permet de dessiner
public void paint(Graphics g) {
	if (Victory == 0) {t.redessine(); }
	if (Victory == 1) {
		g.drawImage(IFin,0,0,700,400,this);
		}
	}
	
// Gestion des évènements claviers si pressé
public void keyPressed(KeyEvent e) {
	int key = e.getKeyCode();
	if (DirectionChanged == 0) {		
		switch (key) {
			case KeyEvent.VK_DOWN:
				if ((s.WhatDirection() != 'H')&&(s.WhatDirection() != 'B')){
					s.defDirection(Terrain.BAS);
					DirectionChanged = 1;}
				break;
			case KeyEvent.VK_UP:
				if ((s.WhatDirection() != 'B')&&(s.WhatDirection() != 'H')){
					s.defDirection(Terrain.HAUT); 
					DirectionChanged = 1;}
				break;
			case KeyEvent.VK_LEFT:
				if ((s.WhatDirection() != 'D')&&(s.WhatDirection() != 'G')){
					s.defDirection(Terrain.GAUCHE);
					DirectionChanged = 1;} 
				break;
			case KeyEvent.VK_RIGHT:
				if ((s.WhatDirection() != 'G')&&(s.WhatDirection() != 'D')){
					s.defDirection(Terrain.DROITE); 
					DirectionChanged = 1;}
				break;
			}
		}
	}
	
// Autres évènements clavier dont nous ne nous servons pas 
public void keyTyped(KeyEvent e) {}	 
public void keyReleased(KeyEvent e) {}	                
}

Conclusion :


Ceci est une version non définitive et je compte la finir dans le courant de cet été (si je ne change pas d'avis) ...
Si vous avez des questions, n'hésitez pas à me les faire parvenir b_jaubert@hotmail.com (attention cependant, je n'ai pas un accès internet permanent l'été et je mettrai peut etre du temps à vous répondre.
Sinon, l'applet est faite pour etre executée avec cette page html :

<html>
<head></head><body>
<applet code="JeuSerpent.class" width="700" height="400">
</applet></body>
</html>

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.