Lo

Grade : Expert
Inscrit le: 26 Dec 2007, 17:33
|
| Ecrit le: 27 Avril 2009, 17:23 Message non corrigé | |
|
Mdrr alexchef, tu sauras faire un beau projet une fois que j'aurais finsi mes tutos, avec totu les codes sources qui trainent sur mon ordi...
Mais tu vois tant que David ne revient pas ça va être difficile surtout que je ne peux pas valider mes tutos.
Sinon si tu veux des codes compliqués j'en ai un, un genre de démineur en java, je pense que j'ai déjà mis le code sur le fofo ou je ne sais pas encore, je le met en attendant.
Alors pour les Images il faut les mettre à la racine du dossier du projet créer un dossier img, ce dossier img contient trois sous dossier, bouton pour les images du petit soleil, cellules pour les images qui vont de 1 à 9 pour indiquer le nombres de bombes voisines et compteur pour les images pour le chronomètre mais aussi le compteur de bombes restantes pas encore détectées.
Je vous conseille de faire les images par vous même je ne suis pas doué pour ça.
Les sons se trouvent dans un dossier son, à côté du dossier img.
Il contient deux sont, un lorsque on découvre avec le clic gauche, un lorsque on tombe sur une bombes.
Les images à créer :
dans img/boubon :
bouton_cool.gif
bouton_mort.gif
bouton_ok.gif
bouton_surpris.gif
dans img/cellules
couverte.gif
explose.gif
detecte.gif
drapeau.gif
marque.gif
mine.gif
vide.gif
1.gif, 2.gif, ..., 8.gif
dans img/compteur
0.gif, 1.gif, ..., 9.gif
tiret.gif
vide.gif
Et dans le dossier son, vous télécharger deux fichiers .wav, un pour l'explosion, et un pour le dévouiement.
CLAP.wav
EXPLOSE.wav
Voici pour les ressources supplémentaires à mettre à la racine du projet.
Je suppose que tout le monde connait le principe du jeux, on a une grille de x*x cases, x bombes sont placées au hasard, le but est de toutes les trouver, chaque case indique lorsqu'on la découvre le nombre de bombes que contiennent ces cases voisines, si il n'y en a pas, ça se découvre jusqu'à ce que l'on rencontre une case qui a des bombes voisines.
Ainsi en réfléchissant on peut trouver sur quel cases il y a une bombe.
Les touches : clic gauche = découvrir la case.(Si y'a une bombe c'est perdu.)
Clic droit = placer/enlever un drapeau.
Clic sur le soleil = nouveau jeux.
On peut aussi utiliser des marques en cliquant deux fois sur la même case clic droit, mais il faut que ce soit activé dans le menu.
Le code maintenant, enfin il est assez long je le mettrai au fur et à mesure, je met déjà la classe principale :
le fichier Demineur.java
package demineur;
import java.awt.Point;
import java.awt.event.InputEvent;
import java.io.Serializable;
import javax.swing.JOptionPane;
/*Classe principale (réalisée par Laurent Duroisin le 01/07/08.
* Cette classe permet de gérer les principales fonctions du jeux.
*/
public class Demineur implements Serializable {
private Cellule[][] grille; //Grille de jeux.
public transient static final Niveau DEBUTANT = new Niveau (10, 10, 10);//Niveau existants.
public transient static final Niveau INTERMEDIAIRE = new Niveau (16, 16, 40);
public transient static final Niveau AVANCE = new Niveau (30, 16, 99);
private Niveau niveau; //Niveau actuel.
private int nbMineVoisine; //nombre de mines voisines à une case.
private boolean utiliserMarque; //Autorisation du marcage.
public transient static final int JOUE = 1; //Situations au niveau du jouers. (3 possibles)
public transient static final int PERD = 2;
public transient static final int GAGNE = 3;
private int cas; //Situation actuel du joueur.
private int nbMineRestante; //Nombre de mines non recouverte avec le drapeau.
private int nbMinesDetectees; //Nombre de mines détectées par le joueur.
private boolean partieSauvée; //Il y a t'il eu une partie sauvée précédement.
private int temps; //Temps actuel de la partie.
private transient ChronoThread ct; //Tâche gérant le chronomètre.
private transient DemFenetre fenetre; //Fin de la déclaration des variables.
public Demineur () {
niveau = INTERMEDIAIRE; //Niveau par défaut.
fenetre = new DemFenetre (this, "img");//Niveau par défaut = intermédiaire.
ct = new ChronoThread (fenetre);
nvJeux ();
}
public static void main (String[] args) {
Demineur demineur = null;
try { //On tente de récupérer une partie sauvée.
demineur = Fichiers.recuperer();
} catch (NullPointerException e) { //Si il y en a pas, on lance ue nouvelle partie.
try {
demineur = new Demineur (); //Essaye de lancer le jeux.
} catch (Exception erreur) {
erreur.printStackTrace();
}
}
if (demineur != null && demineur.isPartieSauvée()) {
//Si une partie a été sauvée, on demande au joueur s'il veut la continuer.
JOptionPane jop = new JOptionPane ();
int option = jop.showConfirmDialog(null, "Voulez vous continuer la partie sauvée ?", "Une partie a été sauvée.", JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);
if (option == JOptionPane.OK_OPTION) { //Si oui, on récupère la partie sauvée.
demineur.recuperer ();
}
else { //Sinon, on l'éfface et on recommence une nouvelle partie.
Fichiers.effacer();
try {
demineur = new Demineur (); //Essaye de lancer le jeux.
} catch (Exception e) {
e.printStackTrace();
}
}
}
else {
//Sinon, si aucune des options du dessus est vraie, on lance une nouvelel partie.
try {
demineur = new Demineur (); //Essaye de lancer le jeux.
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void nvJeux () {
nbMinesDetectees = 0; //On initialise les variables.
ct.setTemps (0);
utiliserMarque = false;
nbMineRestante = niveau.nbMine;
cas = JOUE;
grille = new Cellule[niveau.largeur][niveau.hauteur];
for (int x = 0; x < grille.length; x++) {
for (int y = 0; y < grille[0].length; y++) {
grille[x][y] = new Cellule ();
//Toutes les cellules sont créées avec leur état par défaut.
}
}
for (int i = 0; i < niveau.nbMine; i++) {
int x, y;
//Place des bombes sur certaines cellules aléatoirement.
do {
x = (int) (Math.random () * niveau.largeur);
y = (int) (Math.random () * niveau.hauteur);
} while (grille[x][y].mine);
//On recommence si il y a lieu pour pas avoir deux bombe au même endroit.
grille[x][y].mine = true;
}
fenetre.redimentionner();
fenetre.setNbMines(niveau.nbMine);
ct.reset ();
fenetre.setGrille(grille, niveau.largeur, niveau.hauteur);
fenetre.cherchBoutonIcone("Ok");
//Pour chaque case, on compte le nombre de mines voisines.
for (int x = 0; x < grille.length; x++) {
for (int y = 0; y < grille[0].length; y++) {
grille[x][y].nbMinesVoisines = getNbMineVoisine (x, y);
}
}//On agrandit la fenêtre si elle est trop petite.
if (fenetre.getWidth() < fenetre.minimumLargeur) {
fenetre.setSize (fenetre.minimumLargeur, fenetre.getHeight ());
}
}
public interface Action {
public void go (int x, int y);
//Méthode appelée pour se déplacer dans le tableau.
}
//Parcour le contour d'une case pour compter les mines voisines.
public void mineVoisine (int x, int y, Action action) {
for (int deltaX = -1; deltaX < 2; deltaX++ ) //Déplacements éffectuer autour d'une case pour compter le nombre de bombes voisines.
for (int deltaY = -1; deltaY < 2; deltaY++)
action.go (x + deltaX, y + deltaY);
}
//Compte le nombre de mines voisines.
public int getNbMineVoisine (int x, int y) {
nbMineVoisine = 0;
mineVoisine (x, y, new Action() { //On définit une nouvelle action. (classe anonyme)
public void go (int x, int y) { //Redéfinition de la méthode go.
if (x < 0 || y < 0)
return; //Si on sors de la grille.
else if (x >= grille.length || y >= grille[0].length)
return;
else if (x == 0 && y == 0)
return; //Si on est sur la case même.
else if (grille[x][y].mine)
nbMineVoisine++; //Si il y a une bombe sur une des cases voisines.
}
});
return nbMineVoisine;
}
public Niveau getNiveau () {
return this.niveau;
}
public void setNiveau (Niveau nvNiveau) {
niveau = nvNiveau;
}
//Méthode qui sera invoquée lors d'un clic sur une cellule.
public void cellClicked (Point p, int bouton) {
cellClicked (p, bouton, true);
}
public void cellClicked (Point p, int bouton, boolean repaint) {
if (cas == GAGNE | cas == PERD) {
//Rien si le joueur à gagné ou perdu.
} else {
//On démarre le chronomètre si ce n'est pas fait.
if (!ct.isRunning())
ct.start();
if (bouton == InputEvent.BUTTON1_MASK) {
//Si l'évènement est un clic gauche de souris.
if (grille[p.x][p.y].couverte == true) {
//On dévoile ce qu'il y a dans la cellule, si ce n'est pas fait.
decouvre (p, repaint, grille[p.x][p.y].couverte);
}
else {
repaint = false; //Sinon, affiche rien.
}
} else if (bouton == InputEvent.BUTTON3_MASK) {
//Si l'évènement et de type clic gauche.
if (grille[p.x][p.y].couverte == true) {
//Si la cellule est couverte.
if (grille[p.x][p.y].etat == Cellule.DRAPEAU) {
//Si il y a un drapeau, on l'enlève.
if (!utiliserMarque) {
//Si le marquage est accepté, on le met sinon on le met pas.
grille[p.x][p.y].etat = Cellule.RIEN;
//On affiche la cellule ave le drapeau.
fenetre.paintCell(grille[p.x][p.y],p.x, p.y, true);
}
else {
grille[p.x][p.y].etat = Cellule.MARQUE;
fenetre.paintCell(grille[p.x][p.y],p.x, p.y, true);
}
//Si il y avait une mine, c'est que le joueur l'avait trouvée.
if (grille[p.x][p.y].mine) {
nbMinesDetectees--;
grille[p.x][p.y].detecte = false;
}
//On augmente le compteur de mine de 1.
nbMineRestante++;
fenetre.setNbMines(nbMineRestante);
}
else if (grille[p.x][p.y].etat == Cellule.RIEN) {
//Sinon, si il y a rien sur la cellule, on met un drapeau.
grille[p.x][p.y].etat = Cellule.DRAPEAU;
//On diminue le ompteur de mine.
nbMineRestante--;
fenetre.setNbMines(nbMineRestante);
fenetre.paintCell(grille[p.x][p.y],p.x, p.y, true);
//Si il y a une mine sur la cellule, c'est que le joueur l'a trouvée.
if (grille[p.x][p.y].mine) {
nbMinesDetectees++;
grille[p.x][p.y].detecte = true;
}
}
//Si les marques sont autorisées, on l'enlève.
else if (grille[p.x][p.y].etat == Cellule.MARQUE){
grille[p.x][p.y].etat = Cellule.RIEN;
fenetre.paintCell(grille[p.x][p.y], p.x, p.y, true);
}
//Remet l'icône sur le bouton comme au début.
fenetre.cherchBoutonIcone("Ok");
}
}
if (cas == JOUE)
fenetre.cherchBoutonIcone("Ok");
//si le joueur a trouvé toutes les bombes, il a gagné.
if (nbMinesDetectees == niveau.nbMine) {
cas = GAGNE;
ct.arreter(); //on arrête le chronomètre.
fenetre.cherchBoutonIcone ("Cool");
}
}
}
//Méthode appelée lorsque l'on dévoile une cellule.
public void decouvre (Point p, boolean repaint, boolean couverte) {
if (couverte && (grille[p.x][p.y].etat == Cellule.RIEN | grille[p.x][p.y].etat == Cellule.MARQUE)) {
if (grille[p.x][p.y].mine) {
cas = PERD;
//Si il y a une bombe sur la cellule, c'est perdu.
ct.arreter();
grille[p.x][p.y].explose = true;
fenetre.cherchBoutonIcone ("Mort");
//on dévoile ou se trouvaient les bombes.
for (int x = 0; x < grille.length; x++) {
for (int y = 0; y < grille[0].length; y++) {
if (!grille[x][y].couverte || grille[x][y].mine) {
fenetre.paintCell (grille[x][y],x , y, false);
grille[p.x][p.y].couverte = false;
}
}
}
//Si il y a pas de mines, on dévoiles les cases voisines.
} else if (grille[p.x][p.y].nbMinesVoisines == 0) {
fenetre.paintCell(grille[p.x][p.y],p.x, p.y, false);
grille[p.x][p.y].couverte = false;
decouvreVoisines (p, false);
} else {
//Sinon, on la dévoile, et réaffiche s'il y a lieu.
if (repaint) {
fenetre.paintCell (grille[p.x][p.y],p.x, p.y, false);
grille[p.x][p.y].couverte = false;
}
}
}
}
public void decouvreVoisines (Point p, boolean couverte) {
//Dévoile toutes les cases voisines.
for (int deltax = -1; deltax < 2; deltax++) {
for (int deltay = -1; deltay < 2; deltay++) {
int x = p.x + deltax;
int y = p.y + deltay;
if (x == p.x && y == p.y) {
//Si on est sur la case même, on ne fait rien.
}
else if (x < 0 || y < 0) {
//Si on sors du tableau, on ne fait rien.
}
else if (x >= grille.length || y >= grille[0].length) {
}
else if (!grille[x][y].couverte) {
//Si la cellule est déjà dévoilée, pas la peine de la redévoiler.
}
else if (!grille[x][y].mine && grille[x][y].etat != Cellule.DRAPEAU && grille[x][y].nbMinesVoisines != 0) {
//Si il y a pas de mine, ni de drapeau, et es mines voisines sur la cellule, on la dévoile.
fenetre.paintCell (grille[x][y],x, y, false);
grille[x][y].couverte = false;
}
else if (!grille[x][y].mine && grille[x][y].nbMinesVoisines == 0){
//Sinon, s'il n'y a pas de mine voisines, on dévoilent les cellules voisines.
fenetre.paintCell (grille[x][y],x, y, false);
grille[x][y].couverte = false;
//On fait donc réappel à la même méthode.
decouvreVoisines (new Point (x, y), false);
}
}
}
}
public int getState () {
return cas;
}
//Sauvegarde une partie.
public void sauvegarder () {
temps = ct.getTemps();
partieSauvée = true;
Fichiers.sauvegarder(this);
}
public boolean isPartieSauvée () {
return partieSauvée;
}
//Récupère une partie sauvée.
public void recuperer () {
fenetre = new DemFenetre (this, "img");
fenetre.setGrille (grille, niveau.largeur, niveau.hauteur);
ct = new ChronoThread (fenetre);
ct.setTemps(temps);
fenetre.setNbMines(nbMineRestante);
fenetre.setTemps(temps);
}
//On quitte le jeux.
public void quitter () {
if (getState() == Demineur.JOUE) {
ct.arreter ();
JOptionPane jop = new JOptionPane ();
int option = jop.showConfirmDialog(fenetre, "Voulez vous enregistrer la partie ?", "Enregistrement de la partie", JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);
if (option == JOptionPane.OK_OPTION) {
sauvegarder ();
}
}
System.exit (0);
}
public ChronoThread getCt () {
return ct;
}
public void setMarque () {
if (utiliserMarque)
utiliserMarque = false;
else
utiliserMarque = true;
}
/*Classe interne qui servira pour gérer les défférents niveau de notre démineur.
* Il y a possibilité de changer de niveau au cours du jeux, et définir personnellement
* un niveau.
*/
public static class Niveau implements Serializable { //Définition d'un niveau.
private int largeur;
private int hauteur;
private int nbMine; //Fin de la déclaration des variables.
public Niveau (int largeur, int hauteur, int nbMine) {
this.largeur = largeur; //Crée un niveau de jeux.
this.hauteur = hauteur;
this.nbMine = nbMine;
}
public int getNbMine () {
return nbMine;
}
public int getLargeur () {
return largeur;
}
public int getHauteur () {
return hauteur;
}
}
/*Classe interne contenant toutes les situation possibles pour
* les ellules au cours d'une partie.
*/
public class Cellule implements Serializable { //Définition
private boolean couverte;
public static final int RIEN = 0; //3 états possibles pour une cellule couverte.
public static final int MARQUE = 1;
public static final int DRAPEAU = 2;
private boolean explose;
private boolean detecte;
private int etat; //Ett actuel de la cellule.
private int nbMinesVoisines;
private boolean mine; //Fin de la déclaration des variables.
public Cellule () {
reInit ();
}
public void reInit () { //Remet les valeurs par défaut.
couverte = true;
etat = RIEN;
explose = false;
mine = false;
detecte = false;
nbMinesVoisines = 0;
}
public int getEtat () {
return etat;
}
public boolean getMine () {
return mine;
}
public boolean getExplose () {
return explose;
}
public int getNbMinesVoisines () {
return nbMinesVoisines;
}
public boolean getDetecte () {
return detecte;
}
public boolean isCouverte () {
return couverte;
}
}
}
Ca c'est du code que j'aime :P
________ Parce qu'on ne peut s'exprimer que par nos créations. ^^
|
|