Compare commits

...

5 Commits

Author SHA1 Message Date
e93b1cfb64 fix: some fixes and actual L piece 2025-05-20 11:34:18 +02:00
8eafa03d77 refactor: split in init vueGrille initialization of vueGrille rather than in constructor 2025-05-20 11:29:49 +02:00
Morph01
a3854362c8 refactor: better achitecture and next piece preview fixed 2025-05-20 11:29:20 +02:00
Morph01
aa6ab95728 Squashed commit of the following:
commit a8f543114e
Author: ROGER <gwendal.roger@etu.univ-lyon1.fr>
Date:   Mon May 19 21:59:38 2025 +0200

    ajout d'une fonctionnalité permettant de mettre en pause le Jeu grace à un bouton. Ajout d'un vérouillage du clavier pendant lause

commit 27862eb3cd
Author: ROGER <gwendal.roger@etu.univ-lyon1.fr>
Date:   Fri May 16 17:10:15 2025 +0200

    Ajoute de l'arret de la musique en fin de partie + arret propre de l'ordonanceur

commit 2fec9fc96e
Author: ROGER <gwendal.roger@etu.univ-lyon1.fr>
Date:   Fri May 16 16:17:58 2025 +0200

    integration du responsive dans l'affichage de la grille
2025-05-20 11:28:35 +02:00
Morph01
85aafa8240 fix: piece generation 2025-05-20 11:25:34 +02:00
21 changed files with 274 additions and 100 deletions

View File

@@ -0,0 +1,13 @@
arguments=--init-script /home/morph/.config/Code/User/globalStorage/redhat.java/1.42.0/config_linux/org.eclipse.osgi/58/0/.cp/gradle/init/init.gradle --init-script /home/morph/.config/Code/User/globalStorage/redhat.java/1.42.0/config_linux/org.eclipse.osgi/58/0/.cp/gradle/protobuf/init.gradle
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=
eclipse.preferences.version=1
gradle.user.home=
java.home=/home/morph/.sdkman/candidates/java/23-tem
jvm.arguments=
offline.mode=false
override.workspace.settings=true
show.console.view=true
show.executions.view=true

View File

@@ -0,0 +1,13 @@
arguments=--init-script /home/morph/.cache/jdtls/config/org.eclipse.osgi/248/0/.cp/gradle/init/init.gradle
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(LOCAL_INSTALLATION(/home/morph/.sdkman/candidates/gradle/current))
connection.project.dir=..
eclipse.preferences.version=1
gradle.user.home=
java.home=/usr/lib/jvm/java-21-openjdk
jvm.arguments=
offline.mode=false
override.workspace.settings=true
show.console.view=true
show.executions.view=true

View File

@@ -0,0 +1,4 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
org.eclipse.jdt.core.compiler.compliance=21
org.eclipse.jdt.core.compiler.source=21

View File

@@ -12,25 +12,34 @@ import org.Views.VueTetris;
public class App {
public String getGreeting() {
return "Hello World!";
public String getGreeting() {
return "Hello World!";
}
public static void main(String[] args) {
// Models
Grille grille = new Grille(20, 10);
Musique musique = new Musique();
musique.start();
Jeu jeu = new Jeu(grille, musique);
// Views
VueTetris vueTetris = new VueTetris(grille, jeu);
// Controllers
IO io = new IO(jeu);
vueTetris.addKeyListener(io);
new TetrisBandeauControleur(vueTetris.getVueBandeauControle(), musique, grille);// Création d'un controleur de
// bandeau avec la musique
// instanciée
}
public static void main(String[] args) {
// Models
Grille grille = new Grille(20, 10);
Musique musique = new Musique();
musique.start();
Jeu jeu = new Jeu(grille,musique);
// Views
VueTetris vueTetris = new VueTetris(grille, jeu);
// Controllers
IO io = new IO(jeu);
vueTetris.addKeyListener(io);
new TetrisBandeauControleur(vueTetris.getVueBandeauControle(), musique, grille);//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 ?
}

View File

@@ -16,7 +16,7 @@ public class IO implements KeyListener {
@Override
public void keyPressed(KeyEvent e) {
if (jeu.getGrille().estEnPause()){
if (jeu.getGrille().estEnPause()) {
System.err.println("Grille est en pause");
return;
}

View File

@@ -4,9 +4,6 @@ import org.Models.Grille;
import org.Models.Musique;
import org.Views.VueBandeauControle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TetrisBandeauControleur {
private boolean partieEnPause = false;
private boolean partieTerminee = false;

View File

@@ -70,22 +70,22 @@ public class Grille extends Observable { // TODO: ?? implements Runnable {
switch (direction) {
case BAS:
if (peuxBouger(direction)) {
if (peuxBouger(direction, this.motifPieceCouranteColoriee())) {
deplacerPieceBas();
}
break;
case GAUCHE:
if (peuxBouger(direction)) {
if (peuxBouger(direction, this.motifPieceCouranteColoriee())) {
deplacerPieceGauche();
}
break;
case DROITE:
if (peuxBouger(direction)) {
if (peuxBouger(direction, this.motifPieceCouranteColoriee())) {
deplacerPieceDroite();
}
break;
case TOUTENBAS:
if (peuxBouger(direction)) {
if (peuxBouger(direction, this.motifPieceCouranteColoriee())) {
deplacerPieceToutEnBas();
}
default:
@@ -115,7 +115,7 @@ public class Grille extends Observable { // TODO: ?? implements Runnable {
}
private void deplacerPieceToutEnBas() {
while (peuxBouger(Direction.BAS)) {
while (peuxBouger(Direction.BAS, this.motifPieceCouranteColoriee())) {
deplacerPieceBas();
}
}
@@ -166,7 +166,7 @@ public class Grille extends Observable { // TODO: ?? implements Runnable {
return casesColores;
}
public boolean peuxBouger(Direction direction) {
public boolean peuxBouger(Direction direction, List<Point> motif) {
int deltaX = 0;
int deltaY = 0;
@@ -186,8 +186,7 @@ public class Grille extends Observable { // TODO: ?? implements Runnable {
break;
}
List<Point> motifPieceColoree = motifPieceCouranteColoriee();
for (Point caseColoree : motifPieceColoree) {
for (Point caseColoree : motif) {
int newX = caseColoree.x + deltaX;
int newY = caseColoree.y + deltaY;
@@ -211,10 +210,13 @@ public class Grille extends Observable { // TODO: ?? implements Runnable {
for (Point caseColoree : motifPieceCouranteColoriee()) {
setCase(caseColoree.y, caseColoree.x, true);
}
System.err.println("post fixage de piece");
verifierEtSupprimerLignesSiBesoin();
}
public boolean doitFixerPiece() {
if (!peuxBouger(Direction.BAS)) {
if (!peuxBouger(Direction.BAS, this.motifPieceCouranteColoriee())) {
return true;
}
@@ -229,5 +231,95 @@ 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() {
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;
break;
}
}
if (ligneSupprimable) {
supprimerLigne(i);
i++;
}
}
}
// // 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
// supprimes
// // dans la grille
// // ->
// // faire tomber JUSQU'EN bas la ligne X au dessus des n lines supprimes
// // PAR CONTRE faire tomber de n lignes toutes les lignes au dessus de X.
// while (peuxBouger(Direction.BAS, getLignePoints(i))) {
// System.err.println("testtttttttttt descnete");
// descendreLigne(i - 1);
// }
// // for (int j = i - 2; j > 0; j--) {
// // descendreLigne(j);
// // }
// }
public void supprimerLigne(int i) {
for (int ligne = i; ligne > 0; ligne--) {
for (int j = 0; j < nbColonnes; j++) {
this.setCase(ligne, j, this.getCase(ligne - 1, j));
}
}
for (int j = 0; j < nbColonnes; j++) {
this.setCase(0, j, false);
}
setChanged();
notifyObservers();
}
public List<Point> getLignePoints(int i) {
List<Point> coordonnesCase = new ArrayList<>();
for (int j = 0; j < nbColonnes; j++) {
coordonnesCase.add(new Point(j, i));
}
return coordonnesCase;
}
public void descendreLigne(int i) {
for (int j = 0; j < nbColonnes; j++) {
List<Point> coordonnesCase = new ArrayList<>();
coordonnesCase.add(new Point(j, i));
if (this.grille[i][j]) {
this.setCase(i + 1, j, true);
}
this.setCase(i, j, false);
}
}
}

View File

@@ -2,8 +2,15 @@ package org.Models;
import java.awt.Point;
import java.util.Observable;
import java.util.Random;
import org.Models.Pieces.PieceI;
import org.Models.Pieces.PieceJ;
import org.Models.Pieces.PieceL;
import org.Models.Pieces.PieceO;
import org.Models.Pieces.PieceS;
import org.Models.Pieces.PieceT;
import org.Models.Pieces.PieceZ;
@SuppressWarnings("deprecation")
public class Jeu extends Observable implements Runnable {
@@ -15,16 +22,16 @@ public class Jeu extends Observable implements Runnable {
private int pieceSuivanteX;
private int pieceSuivanteY;
// TODO : remove test variable
public int test = 0;
public boolean jeuEnCours = true;
public Jeu(Grille grille, Musique musique) {
System.err.println("init jeu");
this.grille = grille;
this.musique = musique;
System.err.println("init nouvelle piece courante");
this.grille.setPieceCourante(getNouvellePiece());
System.err.println("init nouvelle piece suivante");
this.pieceSuivante = getNouvellePiece();
this.ordonnanceur = new Ordonnanceur(this, 1000);
@@ -32,10 +39,46 @@ public class Jeu extends Observable implements Runnable {
}
private PieceCourante getNouvellePiece() {
this.pieceSuivante = new PieceL();
this.pieceSuivanteX = 3;
this.pieceSuivanteY = 0;
return pieceSuivante;
Random random = new Random();
int randomiiii = random.nextInt(6);
System.err.println("randomiiiii : " + randomiiii);
PieceCourante nouvellePiece;
switch (randomiiii) {
case 0:
nouvellePiece = new PieceI();
System.err.println("piece I");
break;
case 1:
nouvellePiece = new PieceL();
System.err.println("piece L");
break;
case 2:
nouvellePiece = new PieceJ();
System.err.println("piece J");
break;
case 3:
nouvellePiece = new PieceO();
System.err.println("piece O");
break;
case 4:
nouvellePiece = new PieceS();
System.err.println("piece S");
break;
case 5:
nouvellePiece = new PieceT();
System.err.println("piece T");
break;
case 6:
nouvellePiece = new PieceZ();
System.err.println("piece Z");
break;
default:
nouvellePiece = new PieceL();
break;
}
return nouvellePiece;
}
public PieceCourante getPieceSuivante() {
@@ -91,7 +134,8 @@ public class Jeu extends Observable implements Runnable {
this.grille.deplacerPiece(Direction.BAS);
} else {
this.grille.fixerPiece();
this.grille.setPieceCourante(getNouvellePiece());
this.grille.setPieceCourante(pieceSuivante);
this.pieceSuivante = getNouvellePiece();
}
setChanged();

View File

@@ -4,7 +4,6 @@ public class Ordonnanceur extends Thread {
Runnable runnable;
long pause;
private boolean estActif = true;
public Ordonnanceur(Runnable runnable, long pause) {
this.runnable = runnable;
@@ -12,7 +11,6 @@ public class Ordonnanceur extends Thread {
}
public void stopOrdonnanceur() {
estActif = false;
interrupt();
}

View File

@@ -1,6 +1,5 @@
package org.Models;
public interface PieceCourante {
boolean[][] motif = new boolean[4][4];
abstract public boolean[][] getMotif();
}

View File

@@ -1,18 +0,0 @@
package org.Models.Pieces;
import org.Models.PieceCourante;
public class PieceCarre implements PieceCourante {
public PieceCarre() {
motif[1][1] = true;
motif[1][2] = true;
motif[2][1] = true;
motif[2][2] = true;
}
@Override
public boolean[][] getMotif() {
return motif;
}
}

View File

@@ -4,6 +4,8 @@ import org.Models.PieceCourante;
public class PieceI implements PieceCourante {
private boolean[][] motif = new boolean[4][4];
public PieceI() {
motif[0][1] = true;
motif[1][1] = true;

View File

@@ -4,6 +4,8 @@ import org.Models.PieceCourante;
public class PieceJ implements PieceCourante {
private boolean[][] motif = new boolean[3][3];
public PieceJ() {
motif[0][2] = true;
motif[1][2] = true;

View File

@@ -4,12 +4,13 @@ import org.Models.PieceCourante;
public class PieceL implements PieceCourante {
private boolean[][] motif = new boolean[3][3];
public PieceL(){
motif[0][0] = true;
motif[1][0] = true;
motif[2][0] = true;
motif[3][0] = true;
motif[3][1] = true;
motif[3][2] = true;
motif[2][1] = true;
}
@Override

View File

@@ -3,11 +3,13 @@ package org.Models.Pieces;
import org.Models.PieceCourante;
public class PieceO implements PieceCourante {
private boolean[][] motif = new boolean[4][4];
public PieceO() {
motif[0][1] = true;
motif[0][2] = true;
motif[1][1] = true;
motif[1][2] = true;
motif[2][1] = true;
motif[2][2] = true;
}
@Override

View File

@@ -4,6 +4,8 @@ import org.Models.PieceCourante;
public class PieceS implements PieceCourante {
private boolean[][] motif = new boolean[3][3];
public PieceS() {
motif[0][1] = true;
motif[1][1] = true;

View File

@@ -4,6 +4,8 @@ import org.Models.PieceCourante;
public class PieceT implements PieceCourante {
private boolean[][] motif = new boolean[3][3];
public PieceT() {
motif[0][1] = true;
motif[1][1] = true;

View File

@@ -4,6 +4,8 @@ import org.Models.PieceCourante;
public class PieceZ implements PieceCourante {
private boolean[][] motif = new boolean[3][3];
public PieceZ() {
motif[0][2] = true;
motif[1][2] = true;

View File

@@ -1,20 +1,26 @@
package org.Views;
import org.Models.GridLayoutCarre;
import org.Models.Jeu;
import org.Models.PieceCourante;
import javax.swing.*;
import java.awt.*;
import java.util.Observable;
import java.util.Observer;
public class VueBandeauControle extends JPanel {
@SuppressWarnings("deprecation")
public class VueBandeauControle extends JPanel implements Observer {
private JLabel scoreLabel;
private JPanel nextPiecePanel;
private JButton pauseButton;
private JPanel[][] caseNextPiece = new JPanel[4][4];
private JLabel nbLigneLabel;
private JButton quitterButton;
private Jeu jeu;
public VueBandeauControle() {
public VueBandeauControle(Jeu jeu) {
this.jeu = jeu;
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setBackground(Color.gray);
// setPreferredSize();
@@ -64,6 +70,7 @@ public class VueBandeauControle extends JPanel {
add(boutonsPanel);
// setVisible(true);
jeu.addObserver(this);
}
public void setScore(int score) {
@@ -103,19 +110,31 @@ public class VueBandeauControle extends JPanel {
}
public void afficherPieceSuivante(PieceCourante piece) {
boolean[][] motif = piece.getMotif();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
caseNextPiece[i][j].setBackground(Color.WHITE);
}
}
boolean[][] motif = piece.getMotif();
for (int i = 0; i < motif.length; i++) {
for (int j = 0; j < motif[i].length; j++) {
if (motif[i][j]) {
caseNextPiece[i][j].setBackground(Color.RED);
} else {
caseNextPiece[i][j].setBackground(Color.WHITE);
}
}
}
nextPiecePanel.revalidate();
nextPiecePanel.repaint();
}
@Override
public void update(Observable o, Object arg) {
if (o instanceof Jeu) {
afficherPieceSuivante(jeu.getPieceSuivante());
// TODO : setScore ??
}
}
}

View File

@@ -7,8 +7,6 @@ import org.Models.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.util.Observable;
import java.util.Observer;
@@ -32,23 +30,7 @@ public class VueGrille extends JPanel implements Observer, Runnable {
this.nbLignes = grille.getNbLignes();
this.nbColonnes = grille.getNbColonnes();
setLayout(new BorderLayout());
grillePanel = new JPanel(new GridLayoutCarre(nbLignes,nbColonnes)); //pour que les cases soient carrés
add(grillePanel, BorderLayout.CENTER);
casesGrille = new JPanel[nbLignes][nbColonnes];
for (int i = 0; i < nbLignes; i++) {
for (int j = 0; j < nbColonnes; j++) {
JPanel caseG = new JPanel(){
@Override
public Dimension getPreferredSize(){
return super.getPreferredSize();
}
};
caseG.setBackground(Color.WHITE);
caseG.setBorder(BorderFactory.createLineBorder(Color.GRAY));
casesGrille[i][j] = caseG;
grillePanel.add(caseG);
}
}
initialiserVueGrille();
grille.addObserver(this);
jeu.addObserver(this);
@@ -60,7 +42,7 @@ public class VueGrille extends JPanel implements Observer, Runnable {
public void resizeCases() {
int largeurPanel = grillePanel.getWidth();
int hauteurPanel = grillePanel.getHeight();
if (largeurPanel==0||hauteurPanel==0) {
if (largeurPanel == 0 || hauteurPanel == 0) {
return;
}
int taille = Math.min(largeurPanel, hauteurPanel);
@@ -71,7 +53,7 @@ public class VueGrille extends JPanel implements Observer, Runnable {
int tailleCaseX = largeurPanel / nbColonnes;
int tailleCaseY = hauteurPanel / nbLignes;
int tailleCase = Math.min(tailleCaseX, tailleCaseY);
Dimension taillePreferee=new Dimension(tailleCase, tailleCase);
Dimension taillePreferee = new Dimension(tailleCase, tailleCase);
for (int i = 0; i < nbLignes; i++) {
for (int j = 0; j < nbColonnes; j++) {
casesGrille[i][j].setPreferredSize(taillePreferee);
@@ -82,10 +64,20 @@ public class VueGrille extends JPanel implements Observer, Runnable {
}
private void initialiserVueGrille() {
for (int i = 0; i < grille.getNbLignes(); i++) {
for (int j = 0; j < grille.getNbColonnes(); j++) {
JPanel caseG = new JPanel();
grillePanel = new JPanel(new GridLayoutCarre(nbLignes, nbColonnes)); // pour que les cases soient carrés
add(grillePanel, BorderLayout.CENTER);
casesGrille = new JPanel[nbLignes][nbColonnes];
for (int i = 0; i < nbLignes; i++) {
for (int j = 0; j < nbColonnes; j++) {
JPanel caseG = new JPanel() {
@Override
public Dimension getPreferredSize() {
return super.getPreferredSize();
}
};
caseG.setBackground(Color.WHITE);
caseG.setBorder(BorderFactory.createLineBorder(Color.GRAY));
casesGrille[i][j] = caseG;
grillePanel.add(caseG);
}
}

View File

@@ -1,6 +1,5 @@
package org.Views;
import org.Controllers.TetrisBandeauControleur;
import org.Models.*;
import javax.swing.*;
@@ -19,8 +18,9 @@ public class VueTetris extends JFrame {
super("Tetris");
this.vueGrille = new VueGrille(grille, jeu);
this.vueControle = new VueBandeauControle();
//TetrisBandeauControleur controleur = new TetrisBandeauControleur(vueControle);
this.vueControle = new VueBandeauControle(jeu);
// TetrisBandeauControleur controleur = new
// TetrisBandeauControleur(vueControle);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
@@ -31,7 +31,7 @@ public class VueTetris extends JFrame {
setSize((int) tailleJFrameX, (int) tailleJFrameY);
setLocationRelativeTo(null);
//listener permettanbt de redimensionner les cases de la grille
// listener permettanbt de redimensionner les cases de la grille
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
@@ -42,7 +42,6 @@ public class VueTetris extends JFrame {
setVisible(true);
vueGrille.resizeCases();
// Utilisation de la pièce L
vueControle.afficherPieceSuivante(jeu.getPieceSuivante());
}