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>
25 mai 2007 à 00:22
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.