diff --git a/app/bin/main/TetrisMusic.mp3 b/app/bin/main/TetrisMusic.mp3 deleted file mode 100644 index 6000053..0000000 Binary files a/app/bin/main/TetrisMusic.mp3 and /dev/null differ diff --git a/app/bin/main/TetrisMusic.wav b/app/bin/main/TetrisMusic.wav new file mode 100644 index 0000000..2753ff2 Binary files /dev/null and b/app/bin/main/TetrisMusic.wav differ diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2a8d63b..4e42499 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -23,9 +23,6 @@ dependencies { // This dependency is used by the application. implementation(libs.guava) - - // JLayer pour lire les fichiers MP3 - implementation("javazoom:jlayer:1.0.1") } // Apply a specific Java toolchain to ease working on different environments. diff --git a/app/src/main/java/org/App.java b/app/src/main/java/org/App.java index 00dada3..6f11107 100644 --- a/app/src/main/java/org/App.java +++ b/app/src/main/java/org/App.java @@ -1,6 +1,3 @@ -/* - * This source file was generated by the Gradle 'init' task - */ package org; import org.Controllers.IO; @@ -31,15 +28,13 @@ public class App { IO io = new IO(jeu); vueTetris.addKeyListener(io); - new TetrisBandeauControleur(vueTetris.getVueBandeauControle(), musique, grille, jeu);// Création d'un controleur de - // bandeau avec la musique - // instanciée - } + new TetrisBandeauControleur(vueTetris.getVueBandeauControle(), musique, grille, jeu);// Création d'un + // controleur de + // bandeau avec la + // musique + // instanciée + } - // TODO: RESTE A IMPLEMENTER - // - rotation - // - score - // - lignes - // - menu pour fin de partie - // ext possible: conserver un historique de score dans un fichier txt ? + // TODO: RESTE A IMPLEMENTER + // ext possible: conserver un historique de score dans un fichier txt ? } \ No newline at end of file diff --git a/app/src/main/java/org/Controllers/IO.java b/app/src/main/java/org/Controllers/IO.java index 56682a1..7296e5d 100644 --- a/app/src/main/java/org/Controllers/IO.java +++ b/app/src/main/java/org/Controllers/IO.java @@ -5,6 +5,7 @@ import java.awt.event.KeyListener; import org.Models.Direction; import org.Models.Jeu; +import org.Models.Orientation; public class IO implements KeyListener { @@ -35,6 +36,15 @@ public class IO implements KeyListener { case KeyEvent.VK_SPACE: jeu.getGrille().deplacerPiece(Direction.TOUTENBAS); + break; + + case KeyEvent.VK_R: + jeu.getGrille().tournerPiece(Orientation.SENSHORAIRE); + break; + + case KeyEvent.VK_E: + jeu.getGrille().tournerPiece(Orientation.SENSANTIHORAIRE); + break; default: break; diff --git a/app/src/main/java/org/Controllers/TetrisBandeauControleur.java b/app/src/main/java/org/Controllers/TetrisBandeauControleur.java index 7f3f384..201ab3a 100644 --- a/app/src/main/java/org/Controllers/TetrisBandeauControleur.java +++ b/app/src/main/java/org/Controllers/TetrisBandeauControleur.java @@ -23,16 +23,16 @@ public class TetrisBandeauControleur { this.grille = grille; this.jeu = jeu; // action play/pause - //Listener pour le bouton play/pause + // Listener pour le bouton play/pause this.vueControle.getPauseButton().addActionListener(e -> switchPlayPause()); - //Listener pour le bouton quitter + // Listener pour le bouton quitter this.vueControle.getQuitterButton().addActionListener(e -> { System.out.println("Fermeture de l'application..."); System.exit(0); }); - //Listener pour le bouton aide + // Listener pour le bouton aide this.vueControle.getAideButton().addActionListener(e -> afficherAide()); - //Listener pour le bouton recommencer + // Listener pour le bouton recommencer this.vueControle.getRelancerButton().addActionListener(e -> { jeu.reinitialiserPartie(); vueControle.getPauseButton().setText("PAUSE"); @@ -47,6 +47,7 @@ public class TetrisBandeauControleur { } partieEnPause = !partieEnPause; grille.setEnPause(partieEnPause); + grille.setEnPause(partieEnPause); musique.basculePlayPause(); vueControle.getPauseButton().setText(partieEnPause ? "PLAY" : "PAUSE"); System.out.println(partieEnPause ? "Partie en pause" : "Partie en cours"); @@ -70,7 +71,7 @@ public class TetrisBandeauControleur { if (!grille.estEnPause()) { grille.setEnPause(true); musique.basculePlayPause(); - JOptionPane.showMessageDialog(vueControle,messageAide, "Aide", JOptionPane.INFORMATION_MESSAGE); + JOptionPane.showMessageDialog(vueControle, messageAide, "Aide", JOptionPane.INFORMATION_MESSAGE); grille.setEnPause(false); musique.basculePlayPause(); } diff --git a/app/src/main/java/org/Models/GridLayoutCarre.java b/app/src/main/java/org/Models/GridLayoutCarre.java index 7f6338a..5a49e65 100644 --- a/app/src/main/java/org/Models/GridLayoutCarre.java +++ b/app/src/main/java/org/Models/GridLayoutCarre.java @@ -5,6 +5,7 @@ import java.awt.*; public class GridLayoutCarre implements LayoutManager { private int lignes; private int colonnes; + public GridLayoutCarre(int lignes, int colonnes) { this.lignes = lignes; this.colonnes = colonnes; @@ -33,7 +34,7 @@ public class GridLayoutCarre implements LayoutManager { public void layoutContainer(Container parent) { int largeur = parent.getWidth(); int hauteur = parent.getHeight(); - int tailleCase= Math.min(largeur / colonnes, hauteur / lignes); + int tailleCase = Math.min(largeur / colonnes, hauteur / lignes); int offSetX = (largeur - tailleCase * colonnes) / 2; int offSetY = (hauteur - tailleCase * lignes) / 2; int index = 0; diff --git a/app/src/main/java/org/Models/Grille.java b/app/src/main/java/org/Models/Grille.java index b4e914a..07754e5 100644 --- a/app/src/main/java/org/Models/Grille.java +++ b/app/src/main/java/org/Models/Grille.java @@ -1,6 +1,10 @@ package org.Models; +/** + * Uniquement afin de se servir d'une paire de coordonées. + */ import java.awt.Point; + import java.util.ArrayList; import java.util.List; import java.util.Observable; @@ -189,20 +193,8 @@ public class Grille extends Observable { // TODO: ?? implements Runnable { break; } - for (Point caseColoree : motif) { - int newX = caseColoree.x + deltaX; - int newY = caseColoree.y + deltaY; - - if (newX < 0 || newX >= nbColonnes || newY < 0 || newY >= nbLignes) { - return false; - } - - if (grille[newY][newX]) { - return false; - } - } - - return true; + List nouvellePosition = calculerNouvellePosition(motif, deltaX, deltaY); + return positionValide(nouvellePosition); } public boolean[][] getGrille() { @@ -234,23 +226,6 @@ public class Grille extends Observable { // TODO: ?? implements Runnable { return enPause; } - // public void verifierEtSupprimerLignesSiBesoin() { - - // for (int i = nbLignes - 1; i > 0; i--) { - // boolean ligneSupprimable = true; - - // for (int j = 0; j < nbColonnes; j++) { - // if (!this.grille[i][j]) { - // ligneSupprimable = false; - // } - // } - - // if (ligneSupprimable) { - // supprimerLigne(i); - // } - // } - // } - public void verifierEtSupprimerLignesSiBesoin() { int tmpNbLignesSupprimees = 0; System.out.println("Debut uppression d'une ligne......"); @@ -271,7 +246,7 @@ public class Grille extends Observable { // TODO: ?? implements Runnable { tmpNbLignesSupprimees++; } } - System.out.println(tmpNbLignesSupprimees+ " Lignes supprimées"); + System.out.println(tmpNbLignesSupprimees + " Lignes supprimées"); switch (tmpNbLignesSupprimees) { case 1: score += 100; @@ -290,6 +265,22 @@ public class Grille extends Observable { // TODO: ?? implements Runnable { } } + public int getScore() { + return score; + } + + public void setScore(int score) { + this.score = score; + } + + public int getNbLignesSupprimees() { + return nbLignesSupprimees; + } + + public void setNbLignesSupprimees(int nbLignesSupprimees) { + this.nbLignesSupprimees = nbLignesSupprimees; + } + // // TODO : EUHHHHHHHHHH JE CROIS PAS que ça marche comme ça c'est pas en mode // gravité récursive, c'est juste tout descend de n lignes cassées // // dès qu'on a fixe la pièce courante on verifie le nombre de lignes a @@ -347,18 +338,79 @@ public class Grille extends Observable { // TODO: ?? implements Runnable { } } - public int getScore(){ - return score; - } - public void setScore(int score) { - this.score = score; + public void tournerPiece(Orientation orientation) { + if (peuxTournerPiece(orientation)) { + boolean[][] motif = pieceCourante.getMotif(); + boolean[][] nouveauMotif; + + if (orientation == Orientation.SENSHORAIRE) { + nouveauMotif = PieceCourante.rotationHoraire(motif); + } else { + nouveauMotif = PieceCourante.rotationAntiHoraire(motif); + } + + pieceCourante.setMotif(nouveauMotif); + + setChanged(); + notifyObservers(); + } } - public int getNbLignesSupprimees() { - return nbLignesSupprimees; + public boolean peuxTournerPiece(Orientation orientation) { + List positionApresRotation = calculerPositionApresRotation(orientation); + return positionValide(positionApresRotation); } - public void setNbLignesSupprimees(int nbLignesSupprimees) { - this.nbLignesSupprimees = nbLignesSupprimees; + + private List calculerPositionApresRotation(Orientation orientation) { + List nouvellePosition = new ArrayList<>(); + boolean[][] motifActuel = pieceCourante.getMotif(); + boolean[][] motifTourne; + + boolean[][] motifCopie = new boolean[motifActuel.length][motifActuel[0].length]; + for (int i = 0; i < motifActuel.length; i++) { + for (int j = 0; j < motifActuel[i].length; j++) { + motifCopie[i][j] = motifActuel[i][j]; + } + } + + if (orientation == Orientation.SENSHORAIRE) { + motifTourne = PieceCourante.rotationHoraire(motifCopie); + } else { + motifTourne = PieceCourante.rotationAntiHoraire(motifCopie); + } + + for (int i = 0; i < motifTourne.length; i++) { + for (int j = 0; j < motifTourne[i].length; j++) { + if (motifTourne[i][j]) { + nouvellePosition.add(new Point(pieceCouranteX + j, pieceCouranteY + i)); + } + } + } + + return nouvellePosition; + } + + public boolean positionValide(List points) { + for (Point point : points) { + if (point.x < 0 || point.x >= nbColonnes || point.y < 0 || point.y >= nbLignes) { + return false; + } + + if (grille[point.y][point.x]) { + return false; + } + } + return true; + } + + private List calculerNouvellePosition(List points, int deltaX, int deltaY) { + List nouvellePosPoints = new ArrayList<>(); + + for (Point point : points) { + nouvellePosPoints.add(new Point(point.x + deltaX, point.y + deltaY)); + } + + return nouvellePosPoints; } public void reinitialiserGrille() { @@ -371,4 +423,5 @@ public class Grille extends Observable { // TODO: ?? implements Runnable { setChanged(); notifyObservers(); } + } \ No newline at end of file diff --git a/app/src/main/java/org/Models/Jeu.java b/app/src/main/java/org/Models/Jeu.java index eda8c0d..5672d8f 100644 --- a/app/src/main/java/org/Models/Jeu.java +++ b/app/src/main/java/org/Models/Jeu.java @@ -1,9 +1,16 @@ package org.Models; +/** + * Uniquement afin de se servir d'une paire de coordonées. + */ import java.awt.Point; + import java.util.Observable; import java.util.Random; +import java.util.Random; +import org.Models.Pieces.PieceI; +import org.Models.Pieces.PieceJ; import org.Models.Pieces.PieceI; import org.Models.Pieces.PieceJ; import org.Models.Pieces.PieceL; @@ -29,10 +36,13 @@ public class Jeu extends Observable implements Runnable { System.err.println("init jeu"); this.grille = grille; this.musique = musique; + this.musique = musique; + System.err.println("init nouvelle piece courante"); System.err.println("init nouvelle piece courante"); this.grille.setPieceCourante(getNouvellePiece()); System.err.println("init nouvelle piece suivante"); + System.err.println("init nouvelle piece suivante"); this.pieceSuivante = getNouvellePiece(); this.ordonnanceur = new Ordonnanceur(this, 1000); @@ -101,7 +111,7 @@ public class Jeu extends Observable implements Runnable { public boolean estFinPartie() { for (Point caseColoree : this.grille.motifPieceCouranteColoriee()) { if (this.grille.getCase(caseColoree.y, caseColoree.x)) { - VueGameOver gameOver = new VueGameOver(grille.getScore(),e -> System.exit(0),()->{ + VueGameOver gameOver = new VueGameOver(grille.getScore(), e -> System.exit(0), () -> { System.out.println("\"rejouer\"clique"); reinitialiserPartie(); }); @@ -123,12 +133,12 @@ public class Jeu extends Observable implements Runnable { notifyObservers(); } - public void reinitialiserPartie(){ + public void reinitialiserPartie() { this.grille.initGrille(); this.grille.setPieceCourante(getNouvellePiece()); this.grille.setScore(0); this.grille.setNbLignesSupprimees(0); - this.pieceSuivante= getNouvellePiece(); + this.pieceSuivante = getNouvellePiece(); this.jeuEnCours = true; this.ordonnanceur = new Ordonnanceur(this, 1000); this.ordonnanceur.start(); @@ -136,14 +146,14 @@ public class Jeu extends Observable implements Runnable { notifyObservers(); } - public void pauseJeu(){ + public void pauseJeu() { grille.setEnPause(true); if (musique != null) { musique.basculePlayPause(); } } - public void reprendreJeu(){ + public void reprendreJeu() { grille.setEnPause(false); if (musique != null) { musique.basculePlayPause(); diff --git a/app/src/main/java/org/Models/Musique.java b/app/src/main/java/org/Models/Musique.java index be62585..dcacbe4 100644 --- a/app/src/main/java/org/Models/Musique.java +++ b/app/src/main/java/org/Models/Musique.java @@ -1,53 +1,94 @@ package org.Models; -import javazoom.jl.player.Player; - -import java.io.BufferedInputStream; +import java.io.IOException; import java.io.InputStream; -public class Musique extends Thread { - private Player player; - private volatile boolean stop = false; - private volatile boolean enPause = false; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.LineEvent; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.UnsupportedAudioFileException; - public void run() { +/** + * Classe Musique n'étant pas purement données métier, donc n'aurait normalement + * sa place dans le package Models. Il faudrait l'externaliser. Par manque de + * temps, suite à notre discussion, nous avons décidé de laisser la musique ici. + */ +public class Musique { + private Clip clip; + private long clipPositionPause = 0; + private boolean estEnPause = false; + private boolean estArrete = false; + private boolean estInitialise = false; + + public Musique() { + initialiserClip(); + } + + private void initialiserClip() { try { - while (!stop) { - if (!enPause) { - try (InputStream musique = getClass().getResourceAsStream("/TetrisMusic.mp3")) { - if (musique == null) { - System.err.println("Erreur : le fichier musique.mp3 est introuvable."); - return; - } - BufferedInputStream buffer = new BufferedInputStream(musique); - this.player = new Player(buffer); - System.out.println("Lecture de la musique..."); - player.play(); - } catch (Exception e) { - System.err.println("Erreur lors de la lecture de la musique : " + e.getMessage()); - } - } else { - Thread.sleep(1000); // Attendre 1 seconde avant de vérifier à nouveau - } + InputStream audioSrc = getClass().getResourceAsStream("/TetrisMusic.wav"); + if (audioSrc == null) { + System.err.println("Erreur : le fichier TetrisMusic.wav est introuvable."); + return; } - } catch (InterruptedException e) { - System.err.println("Musique interrompue : " + e.getMessage()); + + AudioInputStream audioStream = AudioSystem.getAudioInputStream(audioSrc); + clip = AudioSystem.getClip(); + clip.open(audioStream); + estInitialise = true; + + clip.addLineListener(event -> { + if (event.getType() == LineEvent.Type.STOP && !estEnPause && !estArrete) { + clip.setFramePosition(0); + clip.start(); + } + }); + + System.out.println("Clip audio initialisé avec succès."); + } catch (UnsupportedAudioFileException e) { + System.err.println("Format audio non supporté : " + e.getMessage()); + } catch (LineUnavailableException e) { + System.err.println("Ligne audio indisponible : " + e.getMessage()); + } catch (IOException e) { + System.err.println("Erreur d'E/S lors de la lecture audio : " + e.getMessage()); + } + } + + public void start() { + if (estInitialise && !estArrete) { + clip.setFramePosition(0); + clip.start(); + estEnPause = false; + System.out.println("Lecture de la musique..."); } System.out.println("Fin du thread de musique."); } + public void basculePlayPause() { - enPause = !enPause; - if (enPause && player != null) { - System.out.println("Musique en pause."); - player.close(); + if (!estInitialise || estArrete) + return; + + estEnPause = !estEnPause; + + if (estEnPause) { + clipPositionPause = clip.getMicrosecondPosition(); + clip.stop(); + System.out.println("Musique en pause à la position " + clipPositionPause + " µs"); + } else { + clip.setMicrosecondPosition(clipPositionPause); + clip.start(); + System.out.println("Musique reprise à la position " + clipPositionPause + " µs"); } } public void arreterMusique() { - System.out.println("Arrêt de la musique."); - stop = true; - if (player != null) { - player.close(); + if (estInitialise) { + estArrete = true; + clip.stop(); + clip.close(); + System.out.println("Arrêt de la musique."); } } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/Models/Orientation.java b/app/src/main/java/org/Models/Orientation.java new file mode 100644 index 0000000..9f4cfe3 --- /dev/null +++ b/app/src/main/java/org/Models/Orientation.java @@ -0,0 +1,6 @@ +package org.Models; + +public enum Orientation { + SENSHORAIRE, + SENSANTIHORAIRE, +} diff --git a/app/src/main/java/org/Models/PieceCourante.java b/app/src/main/java/org/Models/PieceCourante.java index 7de48c5..0fd132d 100644 --- a/app/src/main/java/org/Models/PieceCourante.java +++ b/app/src/main/java/org/Models/PieceCourante.java @@ -2,4 +2,32 @@ package org.Models; public interface PieceCourante { abstract public boolean[][] getMotif(); + + abstract public void setMotif(boolean[][] motif); + + static boolean[][] rotationHoraire(boolean[][] motif) { + int taille = motif.length; + boolean[][] resultat = new boolean[taille][taille]; + + for (int i = 0; i < taille; i++) { + for (int j = 0; j < taille; j++) { + resultat[j][taille - 1 - i] = motif[i][j]; + } + } + + return resultat; + } + + static boolean[][] rotationAntiHoraire(boolean[][] motif) { + int taille = motif.length; + boolean[][] resultat = new boolean[taille][taille]; + + for (int i = 0; i < taille; i++) { + for (int j = 0; j < taille; j++) { + resultat[taille - 1 - j][i] = motif[i][j]; + } + } + + return resultat; + } } diff --git a/app/src/main/java/org/Models/Pieces/PieceI.java b/app/src/main/java/org/Models/Pieces/PieceI.java index fb50b1f..a985797 100644 --- a/app/src/main/java/org/Models/Pieces/PieceI.java +++ b/app/src/main/java/org/Models/Pieces/PieceI.java @@ -4,7 +4,7 @@ import org.Models.PieceCourante; public class PieceI implements PieceCourante { -private boolean[][] motif = new boolean[4][4]; + private boolean[][] motif = new boolean[4][4]; public PieceI() { motif[0][1] = true; @@ -17,4 +17,9 @@ private boolean[][] motif = new boolean[4][4]; public boolean[][] getMotif() { return motif; } + + @Override + public void setMotif(boolean[][] motif) { + this.motif = motif; + } } diff --git a/app/src/main/java/org/Models/Pieces/PieceJ.java b/app/src/main/java/org/Models/Pieces/PieceJ.java index 07bcdae..11aaea2 100644 --- a/app/src/main/java/org/Models/Pieces/PieceJ.java +++ b/app/src/main/java/org/Models/Pieces/PieceJ.java @@ -4,16 +4,22 @@ import org.Models.PieceCourante; public class PieceJ implements PieceCourante { -private boolean[][] motif = new boolean[3][3]; + private boolean[][] motif = new boolean[3][3]; public PieceJ() { - motif[0][2] = true; - motif[1][2] = true; - motif[2][2] = true; + motif[0][1] = true; + motif[1][1] = true; motif[2][1] = true; + motif[2][0] = true; } + @Override public boolean[][] getMotif() { return motif; } + + @Override + public void setMotif(boolean[][] motif) { + this.motif = motif; + } } diff --git a/app/src/main/java/org/Models/Pieces/PieceL.java b/app/src/main/java/org/Models/Pieces/PieceL.java index 4a3ebf3..e426937 100644 --- a/app/src/main/java/org/Models/Pieces/PieceL.java +++ b/app/src/main/java/org/Models/Pieces/PieceL.java @@ -4,17 +4,22 @@ import org.Models.PieceCourante; public class PieceL implements PieceCourante { -private boolean[][] motif = new boolean[3][3]; + private boolean[][] motif = new boolean[3][3]; - public PieceL(){ - motif[0][0] = true; - motif[1][0] = true; - motif[2][0] = true; + public PieceL() { + motif[0][1] = true; + motif[1][1] = true; motif[2][1] = true; + motif[2][2] = true; } @Override public boolean[][] getMotif() { return motif; } + + @Override + public void setMotif(boolean[][] motif) { + this.motif = motif; + } } diff --git a/app/src/main/java/org/Models/Pieces/PieceO.java b/app/src/main/java/org/Models/Pieces/PieceO.java index 68e5357..140e378 100644 --- a/app/src/main/java/org/Models/Pieces/PieceO.java +++ b/app/src/main/java/org/Models/Pieces/PieceO.java @@ -4,7 +4,8 @@ import org.Models.PieceCourante; public class PieceO implements PieceCourante { -private boolean[][] motif = new boolean[4][4]; + private boolean[][] motif = new boolean[4][4]; + public PieceO() { motif[1][1] = true; motif[1][2] = true; @@ -16,4 +17,9 @@ private boolean[][] motif = new boolean[4][4]; public boolean[][] getMotif() { return motif; } + + @Override + public void setMotif(boolean[][] motif) { + this.motif = motif; + } } diff --git a/app/src/main/java/org/Models/Pieces/PieceS.java b/app/src/main/java/org/Models/Pieces/PieceS.java index 5ba4ebf..4c49495 100644 --- a/app/src/main/java/org/Models/Pieces/PieceS.java +++ b/app/src/main/java/org/Models/Pieces/PieceS.java @@ -4,7 +4,7 @@ import org.Models.PieceCourante; public class PieceS implements PieceCourante { -private boolean[][] motif = new boolean[3][3]; + private boolean[][] motif = new boolean[3][3]; public PieceS() { motif[0][1] = true; @@ -17,4 +17,9 @@ private boolean[][] motif = new boolean[3][3]; public boolean[][] getMotif() { return motif; } + + @Override + public void setMotif(boolean[][] motif) { + this.motif = motif; + } } diff --git a/app/src/main/java/org/Models/Pieces/PieceT.java b/app/src/main/java/org/Models/Pieces/PieceT.java index 74db025..6d41849 100644 --- a/app/src/main/java/org/Models/Pieces/PieceT.java +++ b/app/src/main/java/org/Models/Pieces/PieceT.java @@ -4,7 +4,7 @@ import org.Models.PieceCourante; public class PieceT implements PieceCourante { -private boolean[][] motif = new boolean[3][3]; + private boolean[][] motif = new boolean[3][3]; public PieceT() { motif[0][1] = true; @@ -17,4 +17,9 @@ private boolean[][] motif = new boolean[3][3]; public boolean[][] getMotif() { return motif; } + + @Override + public void setMotif(boolean[][] motif) { + this.motif = motif; + } } diff --git a/app/src/main/java/org/Models/Pieces/PieceZ.java b/app/src/main/java/org/Models/Pieces/PieceZ.java index 385080e..c7893c5 100644 --- a/app/src/main/java/org/Models/Pieces/PieceZ.java +++ b/app/src/main/java/org/Models/Pieces/PieceZ.java @@ -4,7 +4,7 @@ import org.Models.PieceCourante; public class PieceZ implements PieceCourante { -private boolean[][] motif = new boolean[3][3]; + private boolean[][] motif = new boolean[3][3]; public PieceZ() { motif[0][2] = true; @@ -17,4 +17,9 @@ private boolean[][] motif = new boolean[3][3]; public boolean[][] getMotif() { return motif; } + + @Override + public void setMotif(boolean[][] motif) { + this.motif = motif; + } } diff --git a/app/src/main/java/org/Views/GridLayoutCarre.java b/app/src/main/java/org/Views/GridLayoutCarre.java new file mode 100644 index 0000000..a0e868c --- /dev/null +++ b/app/src/main/java/org/Views/GridLayoutCarre.java @@ -0,0 +1,58 @@ +package org.Views; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.LayoutManager; + +public class GridLayoutCarre implements LayoutManager { + private int lignes; + private int colonnes; + + public GridLayoutCarre(int lignes, int colonnes) { + this.lignes = lignes; + this.colonnes = colonnes; + } + + @Override + public void addLayoutComponent(String name, Component comp) { + } + + @Override + public void removeLayoutComponent(Component comp) { + + } + + @Override + public Dimension preferredLayoutSize(Container parent) { + return parent.getPreferredSize(); + } + + @Override + public Dimension minimumLayoutSize(Container parent) { + return parent.getMinimumSize(); + } + + @Override + public void layoutContainer(Container parent) { + int largeur = parent.getWidth(); + int hauteur = parent.getHeight(); + int tailleCase = Math.min(largeur / colonnes, hauteur / lignes); + int offSetX = (largeur - tailleCase * colonnes) / 2; + int offSetY = (hauteur - tailleCase * lignes) / 2; + int index = 0; + + for (int i = 0; i < lignes; i++) { + for (int j = 0; j < colonnes; j++) { + if (index >= parent.getComponentCount()) { + return; + } + Component comp = parent.getComponent(index++); + int x = offSetX + j * tailleCase; + int y = offSetY + i * tailleCase; + comp.setBounds(x, y, tailleCase, tailleCase); + } + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/org/Views/VueBandeauControle.java b/app/src/main/java/org/Views/VueBandeauControle.java index 5977599..7d91495 100644 --- a/app/src/main/java/org/Views/VueBandeauControle.java +++ b/app/src/main/java/org/Views/VueBandeauControle.java @@ -1,14 +1,24 @@ package org.Views; -import org.Models.GridLayoutCarre; import org.Models.Jeu; import org.Models.PieceCourante; -import javax.swing.*; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Insets; import java.util.Observable; import java.util.Observer; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; + @SuppressWarnings("deprecation") public class VueBandeauControle extends JPanel implements Observer { private JLabel scoreLabel; @@ -34,7 +44,7 @@ public class VueBandeauControle extends JPanel implements Observer { scoreLabel.setAlignmentX(Component.CENTER_ALIGNMENT); // NB LIGNE - nbLigneLabel = new JLabel("LIGNES : "+ jeu.getGrille().getNbLignesSupprimees()); + nbLigneLabel = new JLabel("LIGNES : " + jeu.getGrille().getNbLignesSupprimees()); nbLigneLabel.setForeground(Color.white); nbLigneLabel.setFont(new Font("Arial", Font.PLAIN, 16)); nbLigneLabel.setAlignmentX(Component.CENTER_ALIGNMENT); @@ -55,7 +65,7 @@ public class VueBandeauControle extends JPanel implements Observer { quitterButton.setPreferredSize(buttonSize); quitterButton.setMargin(margeBoutton); JPanel hautBoutonsPanel = new JPanel(); - //boutonsPanel.setLayout(new BoxLayout(boutonsPanel, BoxLayout.X_AXIS)); + // boutonsPanel.setLayout(new BoxLayout(boutonsPanel, BoxLayout.X_AXIS)); hautBoutonsPanel.setOpaque(false); hautBoutonsPanel.add(pauseButton); hautBoutonsPanel.add(Box.createRigidArea(new Dimension(10, 0))); @@ -63,7 +73,7 @@ public class VueBandeauControle extends JPanel implements Observer { pauseButton.setFocusable(false); quitterButton.setFocusable(false); - //Relancer button + // Relancer button relancerButton = new JButton("RESTART"); relancerButton.setPreferredSize(buttonSize); relancerButton.setMargin(margeBoutton); @@ -89,7 +99,7 @@ public class VueBandeauControle extends JPanel implements Observer { add(nextPiecePanel); add(Box.createVerticalStrut(20)); add(hautBoutonsPanel); - add(Box.createVerticalGlue()); //force le JPanel à prendre toute la hauteur + add(Box.createVerticalGlue()); // force le JPanel à prendre toute la hauteur add(footerPanel); // setVisible(true); diff --git a/app/src/main/java/org/Views/VueGameOver.java b/app/src/main/java/org/Views/VueGameOver.java index 5e7028d..34e7cf1 100644 --- a/app/src/main/java/org/Views/VueGameOver.java +++ b/app/src/main/java/org/Views/VueGameOver.java @@ -10,26 +10,26 @@ public class VueGameOver extends JFrame { public VueGameOver(int score, ActionListener quitterListener, Runnable rejouerListener) { setTitle("FIN DE PARTIE"); - setSize(400,400); + setSize(400, 400); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); - //Fenetre de fin de partie + // Fenetre de fin de partie JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); - //Texte de fin de partie + // Texte de fin de partie JLabel messageFin = new JLabel("GAME OVER !", SwingConstants.CENTER); messageFin.setFont(new Font("Arial", Font.BOLD, 32)); panel.add(messageFin, BorderLayout.NORTH); - //Texte de score + // Texte de score JLabel messageScore = new JLabel("Votre score : " + score, SwingConstants.CENTER); messageScore.setFont(new Font("Arial", Font.PLAIN, 24)); panel.add(messageScore, BorderLayout.CENTER); - //Boutons + // Boutons JPanel buttonPanel = new JPanel(); quitterButton = new JButton("Quitter"); rejouerButton = new JButton("Rejouer"); - //mise en forme boutons + // mise en forme boutons quitterButton.addActionListener(quitterListener); rejouerButton.addActionListener(e -> { dispose(); diff --git a/app/src/main/java/org/Views/VueGrille.java b/app/src/main/java/org/Views/VueGrille.java index 4d2cb06..1735326 100644 --- a/app/src/main/java/org/Views/VueGrille.java +++ b/app/src/main/java/org/Views/VueGrille.java @@ -1,15 +1,19 @@ package org.Views; -import javax.swing.*; - -import org.Models.*; - import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.util.Observable; import java.util.Observer; +import javax.swing.BorderFactory; +import javax.swing.JPanel; + +import org.Models.Grille; +import org.Models.Jeu; +import org.Models.Ordonnanceur; +import org.Models.PieceCourante; + @SuppressWarnings("deprecation") public class VueGrille extends JPanel implements Observer, Runnable { private JPanel grillePanel; @@ -29,6 +33,8 @@ public class VueGrille extends JPanel implements Observer, Runnable { this.jeu = jeu; this.nbLignes = grille.getNbLignes(); this.nbColonnes = grille.getNbColonnes(); + this.nbLignes = grille.getNbLignes(); + this.nbColonnes = grille.getNbColonnes(); setLayout(new BorderLayout()); initialiserVueGrille(); diff --git a/app/src/main/java/org/Views/VueTetris.java b/app/src/main/java/org/Views/VueTetris.java index b43ea19..a914a9b 100644 --- a/app/src/main/java/org/Views/VueTetris.java +++ b/app/src/main/java/org/Views/VueTetris.java @@ -1,12 +1,16 @@ package org.Views; -import org.Models.*; - -import javax.swing.*; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Toolkit; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; +import javax.swing.JFrame; + +import org.Models.Grille; +import org.Models.Jeu; + public class VueTetris extends JFrame { private static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); public static double tailleJFrameX = screenSize.getHeight() / 2; @@ -17,6 +21,10 @@ public class VueTetris extends JFrame { public VueTetris(Grille grille, Jeu jeu) { super("Tetris"); + this.vueGrille = new VueGrille(grille, jeu); + this.vueControle = new VueBandeauControle(jeu); + // TetrisBandeauControleur controleur = new + // TetrisBandeauControleur(vueControle); this.vueGrille = new VueGrille(grille, jeu); this.vueControle = new VueBandeauControle(jeu); // TetrisBandeauControleur controleur = new @@ -39,8 +47,17 @@ public class VueTetris extends JFrame { } }); + // listener permettanbt de redimensionner les cases de la grille + addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + vueGrille.resizeCases(); + } + }); + setVisible(true); vueGrille.resizeCases(); + vueGrille.resizeCases(); vueControle.afficherPieceSuivante(jeu.getPieceSuivante()); } diff --git a/app/src/main/resources/TetrisMusic.mp3 b/app/src/main/resources/TetrisMusic.mp3 deleted file mode 100644 index 6000053..0000000 Binary files a/app/src/main/resources/TetrisMusic.mp3 and /dev/null differ diff --git a/app/src/main/resources/TetrisMusic.wav b/app/src/main/resources/TetrisMusic.wav new file mode 100644 index 0000000..2753ff2 Binary files /dev/null and b/app/src/main/resources/TetrisMusic.wav differ