Exercice12_TetrisRetourTélécharger Jeu celebre de Tetris compil.bat mkdir bin del /f /s /q bin\*.class javac -d bin -classpath "." fr/cnam/tetris/Tetris.java pause fr cnam grille GrilleControlesInt.java package fr.cnam.grille; /** Interface utilisée par le constructeur de GrilleIHM permettant de traiter les clics sur les boutons de GrilleIHM */ public interface GrilleControlesInt { /** Méthode appelée quand on clique sur un des boutons de GrilleIHM. @param numBouton numéro du bouton utilisé (les boutons commence à 1) @param ihm l'instance de la GrilleIHM. Permet d'utiliser les méthodes publiques de GrilleIHM dans l'action. */ public void action(int numBouton,GrilleIHM ihm); } GrilleIHM.java package fr.cnam.grille; import java.awt.*; import java.awt.event.*; import java.util.*; import fr.cnam.tore.*; /** Classe de définition d'une grille IHM avec laquelle il est possible :<br> - de colorer ou effacer une case de la grille<br> - de realiser une action sur chacun des 10 boutons qui se trouvent à cote de la grille<br> - de nommer les boutons<br> */ public class GrilleIHM { private final static int MAX_CONTROLES = 10; private final static int NB_MAX_MARQUE = 10; private Panel _panel; private Canvas _canvas; private Button _controles[]; private GrilleControlesInt _anyActions; private int _nbX; private int _nbY; private int _tailleCase; private int _grille[][]; private int _width; private int _height; private Color[] _couleurs; // ====================================================================== /** Constructeur de la grille.<br> L'objet créé doit ensuite être insérer dans une objet swing comme par exemple un Frame d'une fenêtre principale.<br> La méthode getPanel() retourne le Panel de la GrilleIHM.<br> @param nbX nombre colonne de la grille @param nbY nombre de ligne de la grille @param tailleCase la taille en pixel des cases de la grille */ public GrilleIHM(int nbX, int nbY, int tailleCase) { // Creation du panel principal _panel = new Panel(); // Caractéristiques de la grille _tailleCase = tailleCase; _nbX = nbX; _nbY = nbY; _width = _nbX * _tailleCase; _height = _nbY * _tailleCase; _couleurs = new Color[NB_MAX_MARQUE]; _couleurs[0] = Color.black; _couleurs[1] = Color.cyan; _couleurs[2] = Color.blue; _couleurs[3] = Color.gray; _couleurs[4] = Color.green; _couleurs[5] = Color.magenta; _couleurs[6] = Color.orange; _couleurs[7] = new Color(165,42,42); // brown; _couleurs[8] = Color.red; _couleurs[9] = Color.pink; // Creation du canvas _canvas = new GrilleCanvas(this); _canvas.resize(_width+5,_height+5); // Initialisation du tableau de la grille _grille = new int[_nbX][_nbY]; razGrille(); // Initialisation des boutons d'actions _anyActions = null; _controles = new Button[MAX_CONTROLES]; // Creation du panel des zones de saisie et des boutons Panel controle = new Panel(new GridLayout(MAX_CONTROLES,1)); for(int i=0;i<MAX_CONTROLES;i++) { int num = i+1; _controles[i] = new Button("Action "+num); _controles[i].setSize(100,20); _controles[i].addActionListener( new ControleAction(num,this)); controle.add(_controles[i]); _controles[i].setLabel("Bouton " + i); } // On ajoute les 2 éléments dans l'IHM // _panel.add(controle); _panel.add(_canvas); } // ====================================================================== /** Initialise l'acteur qui est un objet qui implémente l'interface GrilleControlesInt */ public void setActeur(GrilleControlesInt acteur) { _anyActions = acteur; } // ====================================================================== /** Retourne le panel contenant la GrilleIHM @return le panel */ public Panel getPanel() { return(_panel); } // ====================================================================== /** Efface le contenu de la grille<br> (La valeur 0 est mise dans chaque case) */ public void razGrille() { for(int i=0;i<_nbX;i++) { for(int j=0;j<_nbY;j++) { _grille[i][j]=0; } } } // ====================================================================== /** Efface le contenu de la grille<br> (La valeur 0 est mise dans chaque case) */ public void effacerGrille() { razGrille(); afficherGrille(); } // ====================================================================== /** Affecte à une case de la grille la marque (couleur) @param marque une valeur de 1 à 10 (couleur) ou 0 (case vide) @param x coordonnée en x de la case @param y coordonnée en y de la case */ public void setMarque(int marque,int x,int y) { _grille[x][y] = marque; marquer(marque,x,y); } // ====================================================================== /** Retourne la marque de la case @param x coordonnée en x de la case @param y coordonnée en y de la case @return la valeur de la case (de 0 à 10) */ public int getMarque(int x,int y) { return(_grille[x][y]); } // ====================================================================== /** Teste si la case est libre (différente de 0) @param x coordonnée en x de la case @param y coordonnée en y de la case @return true si la case est libre sinon false */ public boolean siCaseLibre(int x,int y) { return( getMarque(x,y)==0 ); } // ====================================================================== /** Retourne le nombre de colonne de la grille @return le nombre de colonne */ public int getNbX() { return(_nbX); } // ====================================================================== /** Retourne le nombre de ligne de la grille @return le nombre de ligne */ public int getNbY() { return(_nbY); } // ====================================================================== /** Retourne le nombre max de couleur géré par GrilleIHM @return nombre max */ public int getNbMaxMarqueur() { return(NB_MAX_MARQUE); } // ====================================================================== /** Permet de changer le nom d'un bouton de l'IHM. @param num numéro du bouton (de 1 à 10) @param nom du bouton */ public void setNomBouton(int num,String nom) { _controles[num-1].setLabel(nom); } // ====================================================================== // Affichage de la grille // private void afficherGrille() { Graphics g = _canvas.getGraphics(); // On efface toute la grille g.clearRect(0,0,_width,_height); // Tracer des lignes verticales for(int i=0;i<_nbX+1;i++) { Point p1= new Point( (_width/_nbX)*i,0); Point p2= new Point( (_width/_nbX)*i,_height); g.drawLine(p1.x,p1.y,p2.x,p2.y); } // Tracer des lignes horizontales for(int i=0;i<_nbY+1;i++) { Point p1= new Point( 0, (_height/_nbY)*i); Point p2= new Point( _width, (_height/_nbY)*i); g.drawLine(p1.x,p1.y,p2.x,p2.y); } // Tracer des éléments for(int i=0;i<_nbX;i++) { for(int j=0;j<_nbY;j++) { marquer(_grille[i][j],i,j); } } } // ====================================================================== // Tracer d'un élément dans la grille // private void marquer(int marque,int x,int y) { Graphics g = _canvas.getGraphics(); int niX1 = x*(_width/_nbX); int niX2 = (x+1)*(_width/_nbX); int niY1 = y*(_height/_nbY); int niY2 = (y+1)*(_height/_nbY); g.clearRect(niX1+1,niY1+1,niX2-niX1-1,niY2-niY1-1); if (marque >0) { g.setColor(_couleurs[marque-1]); //g.fillRect(niX1+2,niY1+2,niX2-niX1-4,niY2-niY1-4); g.fillRect(niX1+1,niY1+1,niX2-niX1-1,niY2-niY1-1); } } /** Methode static qui permet de creer une GrilleIHM incluse dans un Frame @param nbX nombre de colonnes de la grille @param nbY nombre de lignes de la grille @param tailleCase taille de chaque case en pixel @param posX position en X dans l'ecran du frame @param posY position en Y dans l'ecran du frame */ static public GrilleIHM creerGrilleIhmDansFrame(int nbX, int nbY, int tailleCase, int posX, int posY ) { // On crée la fenêtre Frame fen = new Frame(); // On y ajoute la grille GrilleIHM grilleihm = new GrilleIHM(nbX,nbY,tailleCase); // Panel in Frame fen.add(grilleihm.getPanel()); // Pour fermer la fenetre GrilleWindowAdapter a = new GrilleWindowAdapter(); fen.addWindowListener((WindowListener)a); // On affiche la fenetre fen.setLocation(posX,posY); fen.setSize(300+nbX*tailleCase,250+nbY*tailleCase); fen.show(); return(grilleihm); } // ====================================================================== /** Méthode de test de la classe. Ce programme crée une grille et crée un thread qui déplace une case. Les boutons permettent de tester le comportement du déplacement */ public static void main(String... args) { GrilleIHM grilleihm = creerGrilleIhmDansFrame(20,30,15,50,50); Test t = new Test(grilleihm); grilleihm.setActeur(t); // On met des couleurs à certaines case grilleihm.setMarque(1,0,0); // Couleur 1 en case (0,0) grilleihm.setMarque(2,0,1); // Couleur 1 en case (0,1) grilleihm.setMarque(3,0,2); // Couleur 1 en case (0,2) grilleihm.setMarque(4,0,3); // Couleur 1 en case (0,3) grilleihm.setMarque(5,0,4); // Couleur 1 en case (0,4) grilleihm.setMarque(6,0,5); // Couleur 1 en case (0,5) grilleihm.setMarque(7,0,6); // Couleur 1 en case (0,6) grilleihm.setMarque(8,0,7); // Couleur 1 en case (0,7) grilleihm.setMarque(9,0,8); // Couleur 1 en case (0,8) // Démarrage du test t.start(); } // =============================================================== // Inner classe interne de definition du callback sur les boutons // =============================================================== // Pour récupérer les actions de click sur les boutons class ControleAction implements ActionListener { int _type; // numero bouton GrilleIHM _grille; // La grille IHM // Constructeur afin de designer le type d'action public ControleAction(int type, GrilleIHM grille) { _type=type; _grille=grille; } // Traitement des actions public void actionPerformed(ActionEvent e) { if (_anyActions!=null) { _anyActions.action(_type,_grille); } } } // =============================================================== // Classe interne de definition de la surcharge de paint du canvas // =============================================================== class GrilleCanvas extends Canvas { GrilleIHM _g; public GrilleCanvas(GrilleIHM g) { _g = g; } public void paint(Graphics g) { _g.afficherGrille(); } } } // Fin de GrilleIHM // =============================================================== // Classe interne de fermeture de la fenetre // =============================================================== // L'adaptateur d'une window // class GrilleWindowAdapter extends WindowAdapter { // On ne s'interesse que a l'action de fermeture de // la fenetre public void windowClosing(WindowEvent e) { System.exit(0); } } // =============================================================== /** Classe utilisée pour tester la classe Tore et la grille */ class Test extends Thread implements GrilleControlesInt { private GrilleIHM grille; private int mode; public Test(GrilleIHM g) { grille = g; mode=1; } public void run() { Random rdm = new Random(); Tore espace = new Tore(grille.getNbX(),grille.getNbY()); // grille.setNomBouton(1,"Dep aleat"); grille.setNomBouton(2,"Pos aleat"); grille.setNomBouton(3,"Vers le coin\n (0,0)"); // int x=grille.getNbX()/2; int y=grille.getNbY()/2; grille.setMarque(1,x,y); while(true) { if (mode==1) { int sensX = rdm.nextInt(3)-1; int sensY = rdm.nextInt(3)-1; Point p = espace.deplacer(x,y,sensX,sensY); grille.setMarque(0,x,y); x = (int)p.x; y = (int)p.y; grille.setMarque(1,x,y); } if (mode==2) { grille.setMarque(0,x,y); x = rdm.nextInt(grille.getNbX()); y = rdm.nextInt(grille.getNbY()); grille.setMarque(1,x,y); try{Thread.sleep(1000);}catch(Exception ex){}; } if (mode==3) { Point sens = espace.sensTore(new Point(x,y),new Point(0,0)); Point p = espace.deplacer(x,y,sens.x,sens.y); grille.setMarque(0,x,y); x = (int)p.x; y = (int)p.y; grille.setMarque(1,x,y); } try{Thread.sleep(200);}catch(Exception ex){}; } } public void action(int num,GrilleIHM grille) { mode = num; } } tetris DeplacerForme.java package fr.cnam.tetris; import fr.cnam.grille.*; public class DeplacerForme extends Thread { private int posXCurrent; private int posYCurrent; private Tetris tetris; private boolean finDuJeu; private boolean finDeplacement; private FormeTetris fc; private GrilleIHM grille; private int tempo; public DeplacerForme(Tetris tetris) { this.tetris = tetris; this.fc = null; this.grille = tetris.getGrilleIhm(); this.tempo = tetris.getTempo(); } public void abandonner() { finDeplacement=true; finDuJeu=true; } public void aGauche() { if (fc==null) return; if (posXCurrent>-5) { fc.desafficher(grille,posXCurrent,posYCurrent); if (fc.siAffichable(grille,posXCurrent-1,posYCurrent)) { posXCurrent--; fc.afficher(grille,posXCurrent,posYCurrent); } else fc.afficher(grille,posXCurrent,posYCurrent); } } public void aDroite() { if (fc==null) return; if (posXCurrent<tetris.getNbColonne()-1) { fc.desafficher(grille,posXCurrent,posYCurrent); if (fc.siAffichable(grille,posXCurrent+1,posYCurrent)) { posXCurrent++; fc.afficher(grille,posXCurrent,posYCurrent); } else fc.afficher(grille,posXCurrent,posYCurrent); } } public void tourner() { if (fc==null) return; fc.desafficher(grille,posXCurrent,posYCurrent); fc.nextPixmap(); if (fc.siAffichable(grille,posXCurrent,posYCurrent)) fc.afficher(grille,posXCurrent,posYCurrent); else { fc.previousPixmap(); fc.afficher(grille,posXCurrent,posYCurrent); } } public void descendre() { if (fc==null) return; if (posYCurrent<tetris.getNbLigne()-1) { fc.desafficher(grille,posXCurrent,posYCurrent); if (fc.siAffichable(grille,posXCurrent,posYCurrent+1)) { posYCurrent++; fc.afficher(grille,posXCurrent,posYCurrent); } else fc.afficher(grille,posXCurrent,posYCurrent); } } public void tomber() { if (fc==null) return; tempo=10; } public void run() { try{ finDuJeu = false; posXCurrent = tetris.getNbColonne()/2-2; posYCurrent = 0; while (! finDuJeu) { fc = tetris.getFactoryFormes().getFormeAleatoire(); if (fc.siAffichable(grille,posXCurrent,posYCurrent)) { finDeplacement = false; tempo = tetris.getTempo(); while (! finDeplacement) { fc.afficher(grille,posXCurrent,posYCurrent); try{Thread.sleep(tempo);}catch(Exception ex){}; fc.desafficher(grille,posXCurrent,posYCurrent); if (fc.siAffichable(grille,posXCurrent,posYCurrent+1)) posYCurrent++; else { fc.afficher(tetris.getGrilleIhm(),posXCurrent,posYCurrent); finDeplacement=true; posXCurrent = tetris.getNbColonne()/2-2; posYCurrent = 0; } } } else { finDuJeu=true; fc=null; } } } catch(Exception ex) { ex.printStackTrace(); } } } FactoryFormesTetris.java package fr.cnam.tetris; import java.util.*; public class FactoryFormesTetris { private ArrayList<FormeTetris> formes; private Random rnd; public FactoryFormesTetris() { formes = new ArrayList<FormeTetris>(); rnd = new Random(); } public FormeTetris getFormeAleatoire() { int index = rnd.nextInt(formes.size()); return formes.get(index); } // index d'une forme public void addForme(int index,int taille,String pixmapStr) { int[][] pixmap = new int[taille][taille]; int x=0; int y=0; for(int i=0;i<pixmapStr.length();i++) { if ( (i!=0) && (i%taille==0)) {x=0;y++;} pixmap[x][y] = Integer.parseInt(""+pixmapStr.charAt(i)); x++; } formes.get(index).addPixmap(pixmap); } public int creerForme(int couleur) { FormeTetrisImpl forme = new FormeTetrisImpl(couleur); formes.add(forme); return formes.size()-1; } public ArrayList<FormeTetris> getFormes() { return formes; } } FormeTetris.java package fr.cnam.tetris; import fr.cnam.grille.*; public interface FormeTetris { public void addPixmap(int[][] pixmap); public int getCouleur(); public int getNbPixmap(); public int[][] getPixmap(int index); public void initCurrent(); public void nextPixmap(); public void previousPixmap(); public void afficher(GrilleIHM grille,int posX,int posY); public void desafficher(GrilleIHM grille,int posX,int posY); public boolean siAffichable(GrilleIHM grille,int posX,int posY); } FormeTetrisImpl.java package fr.cnam.tetris; import java.util.*; import fr.cnam.grille.*; public class FormeTetrisImpl implements FormeTetris { private int couleur; private ArrayList<int[][]> pixmaps; private int current; public FormeTetrisImpl(int couleur) { this.couleur = couleur; pixmaps = new ArrayList<int[][]>(); current=0; } // ========= implementation de l'interface FormeTetris ======= public void addPixmap(int[][] pixmap) { current=0; pixmaps.add(pixmap); } public int getCouleur() {return couleur;} public int getNbPixmap() {return pixmaps.size();} public int[][] getPixmap(int index) { return pixmaps.get(index);} public void initCurrent() {current=0;} public void nextPixmap() { current = (current + 1 ) % pixmaps.size(); } public void previousPixmap() { if (current==0) current = pixmaps.size()-1; else current--; } public void afficher(GrilleIHM grille,int posX,int posY) { int[][] pixmap = pixmaps.get(current); for(int x=0;x<pixmap[0].length;x++) for(int y=0;y<pixmap.length;y++) { try{ if (pixmap[x][y]==1) grille.setMarque(couleur,x+posX,y+posY); }catch(Exception ex){} //On peut deborder } } public void desafficher(GrilleIHM grille,int posX,int posY) { int[][] pixmap = pixmaps.get(current); for(int x=0;x<pixmap[0].length;x++) for(int y=0;y<pixmap.length;y++) { try{ if (pixmap[x][y]==1) grille.setMarque(0,x+posX,y+posY); }catch(Exception ex){} //On peut deborder } } public boolean siAffichable(GrilleIHM grille,int posX,int posY) { int[][] pixmap = pixmaps.get(current); for(int x=0;x<pixmap[0].length;x++) for(int y=0;y<pixmap.length;y++) { try{ if ( (pixmap[x][y]==1) && (grille.getMarque(x+posX,y+posY)!=0) ) return false; }catch(Exception ex){if(pixmap[x][y]==1) return false;} //On peut deborder } return true; } } Tetris.java package fr.cnam.tetris; import java.util.*; import java.awt.*; import java.awt.event.*; import fr.cnam.tetris.*; import fr.cnam.grille.*; public class Tetris implements GrilleControlesInt { private FactoryFormesTetris factoryFormes; private int nbLigne; private int nbColonne; private GrilleIHM grille; private DeplacerForme deplacement; private int tempo; public Tetris(int nbColonne,int nbLigne) { this.nbLigne = nbLigne; this.nbColonne = nbColonne; this.tempo = 500; factoryFormes = new FactoryFormesTetris(); int index; index = factoryFormes.creerForme(9); factoryFormes.addForme(index,5,"0000000100001000010001100"); factoryFormes.addForme(index,5,"0000010000111100000000000"); factoryFormes.addForme(index,5,"0011000100001000010000000"); factoryFormes.addForme(index,5,"0000000000011110000100000"); index = factoryFormes.creerForme(8); factoryFormes.addForme(index,5,"0000000100001000010000110"); factoryFormes.addForme(index,5,"0000000000111101000000000"); factoryFormes.addForme(index,5,"0110000100001000010000000"); factoryFormes.addForme(index,5,"0000000001011110000000000"); index = factoryFormes.creerForme(2); factoryFormes.addForme(index,5,"0010000100001000010000100"); factoryFormes.addForme(index,5,"0000000000111110000000000"); factoryFormes.addForme(index,5,"0010000100001000010000100"); factoryFormes.addForme(index,5,"0000000000111110000000000"); index = factoryFormes.creerForme(7); factoryFormes.addForme(index,5,"0000000000011100001000000"); factoryFormes.addForme(index,5,"0000000100001000110000000"); factoryFormes.addForme(index,5,"0000001000011100000000000"); factoryFormes.addForme(index,5,"0000000110001000010000000"); index = factoryFormes.creerForme(5); factoryFormes.addForme(index,5,"0000000000011100010000000"); factoryFormes.addForme(index,5,"0000000100011000010000000"); factoryFormes.addForme(index,5,"0000000100011100000000000"); factoryFormes.addForme(index,5,"0000000100001100010000000"); index = factoryFormes.creerForme(6); factoryFormes.addForme(index,5,"0000000010011100000000000"); factoryFormes.addForme(index,5,"0000000100001000011000000"); factoryFormes.addForme(index,5,"0000000000011100100000000"); factoryFormes.addForme(index,5,"0000001100001000010000000"); index = factoryFormes.creerForme(3); factoryFormes.addForme(index,5,"0000010000111110000100000"); factoryFormes.addForme(index,5,"0011000100001000010001100"); factoryFormes.addForme(index,5,"0000010000111110000100000"); factoryFormes.addForme(index,5,"0011000100001000010001100"); grille = GrilleIHM.creerGrilleIhmDansFrame(nbColonne,nbLigne,10,50,50); grille.setNomBouton(1,"START"); grille.setNomBouton(2,"GAUCHE"); grille.setNomBouton(3,"DROITE"); grille.setNomBouton(4,"TOURNER"); grille.setNomBouton(5,"DESCENDRE"); grille.setNomBouton(6,"TOMBER"); // L'acteur des boutons de la grille est le jeu de tetris grille.setActeur(this); deplacement = new DeplacerForme(this); } public int getNbLigne(){return nbLigne;} public int getNbColonne(){return nbColonne;} public GrilleIHM getGrilleIhm(){return grille;} public int getTempo(){return tempo;} public FactoryFormesTetris getFactoryFormes() { return factoryFormes; } public void action(int numBouton,GrilleIHM ihm) { if (numBouton==1) { deplacement.abandonner(); try{Thread.sleep(1000);}catch(Exception ex){}; grille.effacerGrille(); deplacement = new DeplacerForme(this); deplacement.start(); } if (numBouton==2) deplacement.aGauche(); if (numBouton==3) deplacement.aDroite(); if (numBouton==4) deplacement.tourner(); if (numBouton==5) deplacement.descendre(); if (numBouton==6) deplacement.tomber(); } public static void main(String... args) { Tetris jeu = new Tetris(20,30); } } tore run.bat cd bin java -classpath "." fr.cnam.tetris.Tetris pause