diff --git a/src/linea/Jeu.java b/src/linea/Jeu.java index 0c826fb..1325cd1 100644 --- a/src/linea/Jeu.java +++ b/src/linea/Jeu.java @@ -9,22 +9,18 @@ public class Jeu implements KeyListener, ActionListener { protected JPanel conteneurPrincipal; protected CardLayout layout; - // Instances du jeu protected ZoneDessin ecran = new ZoneDessin(); protected MenuPrincipal menu; - protected Cercle demiCercleAvant = new Cercle(90, -180); - protected Cercle demiCercleArriere = new Cercle(90, 180); + protected Cercle demiCercleAvant; + protected Cercle demiCercleArriere; protected Ligne laligne = new Ligne(); - protected Timer horloge; protected JLabel labScore; - public Jeu() { - // Initialisation du score (comme dans le fichier original) - labScore = new JLabel(); - labScore.setText("

score : 0

"); - labScore.setBounds(20, 0, 200, 50); + public Jeu(){ + labScore = new JLabel("

score : 0

"); + labScore.setBounds(20, 540, 200, 50); ecran.add(labScore); } @@ -33,81 +29,89 @@ public class Jeu implements KeyListener, ActionListener { layout = new CardLayout(); conteneurPrincipal = new JPanel(layout); - // Création du menu en lui passant l'instance actuelle de Jeu menu = new MenuPrincipal(this); - // Configuration de la zone de dessin - ecran.ajouterObjet(demiCercleArriere); - ecran.ajouterObjet(demiCercleAvant); - ecran.ajouterObjet(laligne); - ecran.addKeyListener(this); // Le jeu écoute le clavier + // Initialisation initiale + resetPartie(); + + // --- C'EST ICI QUE LA MAGIE OPÈRE --- + // On ajoute l'action au bouton créé dans ZoneDessin + ecran.btnRetour.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // 1. On change la carte visible vers le MENU + layout.show(conteneurPrincipal, "MENU"); + } + }); + // ------------------------------------- + + ecran.addKeyListener(this); - // Ajout des "cartes" au conteneur principal conteneurPrincipal.add(menu, "MENU"); conteneurPrincipal.add(ecran, "JEU"); - // Configuration de la fenêtre fenetre.setContentPane(conteneurPrincipal); fenetre.pack(); - fenetre.setLocationRelativeTo(null); // Centrer à l'écran + fenetre.setLocationRelativeTo(null); fenetre.setVisible(true); fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - - // Timer (40ms = 25 fps) - horloge = new Timer(40, this); - - // Couleurs - demiCercleArriere.setCouleur(new Color(0.8f, 0.0f, 0.0f)); - demiCercleAvant.setCouleur(new Color(1.0f, 0.2f, 0.2f)); } - // Méthode appelée par le bouton PLAY du menu public void lancerPartie() { + resetPartie(); // Très important : remettre à zéro avant de jouer layout.show(conteneurPrincipal, "JEU"); ecran.setFocusable(true); - ecran.requestFocusInWindow(); // Indispensable pour capter le clavier + ecran.requestFocusInWindow(); horloge.start(); } + private void resetPartie() { + if(horloge != null) horloge.stop(); + horloge = new Timer(40, this); + + demiCercleAvant = new Cercle(90, -180); + demiCercleArriere = new Cercle(90, 180); + + demiCercleArriere.setCouleur(new Color(0.8f, 0.0f, 0.0f)); + demiCercleAvant.setCouleur(new Color(1.0f, 0.2f, 0.2f)); + + ecran.viderObjets(); + ecran.ajouterObjet(demiCercleArriere); + ecran.ajouterObjet(demiCercleAvant); + ecran.ajouterObjet(laligne); + + ecran.setGameOver(false); // Cela cachera le bouton retour + } + @Override public void actionPerformed(ActionEvent e) { - // CORRECTION ICI : Appel de la bonne méthode de ZoneDessin ecran.traiterBoucleAnimation(); - // Logique de collision (réintégrée depuis le fichier original) - double yLigne = laligne.getHauteurLigneA(400); // 400 est une valeur arbitraire pour tester au centre - double yCercle = demiCercleAvant.getY(); - - if (Math.abs(yLigne - yCercle) > 30) { + // Gestion collision simple + if (Math.abs(laligne.getHauteurLigneA(400) - demiCercleAvant.getY()) > 30) { gameOver(); } } public void gameOver() { horloge.stop(); - ecran.setGameOver(true); + ecran.setGameOver(true); // Affiche "Game Over" et le bouton Retour } - // --- Gestion du Clavier --- - + // Gestion touches... @Override public void keyPressed(KeyEvent e) { - int keyCode = e.getKeyCode(); - if (keyCode == 38) { // Flèche HAUT + if (e.getKeyCode() == 38) { demiCercleAvant.Monter(); demiCercleArriere.Monter(); } } - @Override public void keyReleased(KeyEvent e) { - int keyCode = e.getKeyCode(); - if (keyCode == 38) { + if (e.getKeyCode() == 38) { demiCercleAvant.ArreterMonter(); demiCercleArriere.ArreterMonter(); } } - - @Override - public void keyTyped(KeyEvent e) {} + @Override public void keyTyped(KeyEvent e) {} } \ No newline at end of file diff --git a/src/linea/ZoneDessin.java b/src/linea/ZoneDessin.java index b642e17..ac37c72 100644 --- a/src/linea/ZoneDessin.java +++ b/src/linea/ZoneDessin.java @@ -2,113 +2,76 @@ package linea; import java.awt.*; import java.util.ArrayList; +import javax.swing.*; -import javax.swing.JPanel; - -public class ZoneDessin extends JPanel { // hérite d'une classe du frameWork standard +public class ZoneDessin extends JPanel { private static final long serialVersionUID = 1L; - protected ArrayList listeObjets = new ArrayList(); - - //------------------------------------------------------------------------- - // PROPRIETES - //------------------------------------------------------------------------- - - // un booleen qui permet d'arreter l'animation (suspendre) - protected boolean estArrete = false; + // Etats du jeu + protected boolean estArrete = false; protected boolean isGameOver = false; - - - //------------------------------------------------------------------------- - // METHODES - //------------------------------------------------------------------------- - - //------------------------------------------------------------------------- - // Constructeur de la classe - //------------------------------------------------------------------------- + + // LE BOUTON DOIT ÊTRE PUBLIC POUR ÊTRE ACCESSIBLE DEPUIS JEU.JAVA + public JButton btnRetour; + public ZoneDessin(){ - // on prépare la zone d'affichage - setLayout(new BorderLayout()); + // 1. IMPORTANT : Layout null pour positionner le bouton pixel par pixel + setLayout(null); setPreferredSize(new Dimension(800, 600)); setBackground(new Color(100,100,100)); + + // 2. Création et configuration du bouton + btnRetour = new JButton("Retour au Menu"); + // x, y, largeur, hauteur (centré horizontalement pour une fenêtre de 800px) + btnRetour.setBounds(300, 350, 200, 50); + btnRetour.setFont(new Font("Arial", Font.BOLD, 16)); + btnRetour.setFocusable(false); // Important pour ne pas gêner le clavier + btnRetour.setVisible(false); // Caché au début + + this.add(btnRetour); } - - //------------------------------------------------------------------------- - // Ajout d'un objet graphique à la zonde de dessin - //------------------------------------------------------------------------- - public void ajouterObjet(ObjetGraphique unObjet) { - this.listeObjets.add(unObjet); - } - - - //------------------------------------------------------------------------- - // Mettre en pause et redémarrer - //------------------------------------------------------------------------- - public void arreter(){ - estArrete = true; - } - - public void demarrer(){ - estArrete = false; - } - + // ... (méthodes ajouterObjet, viderObjets, arreter, demarrer restent pareilles) ... + public void ajouterObjet(ObjetGraphique unObjet) { this.listeObjets.add(unObjet); } + public void viderObjets() { this.listeObjets.clear(); } - //------------------------------------------------------------------------- - // Boucle d'animation : - // - appelée par exemple 25 fois par seconde - // - à chaque appel : - // - on anime (déplace) chaque objet - // - on redessine tout : appel à paintComponent, déclenché par repaint - //------------------------------------------------------------------------- public void traiterBoucleAnimation(){ - if (estArrete==true) { - return; - } - - // 1. on déplace chaque objet graphique - // A FAIRE : décommenter lorsque cela devienda exécutable, et compléter + if (estArrete || isGameOver) return; for (ObjetGraphique obj : listeObjets){ obj.Animer(); } - // 2. on demande à redessiner, ce qui déclenchera automatiquement - // l'appel à la méthode paintComponent, qui est ci-dessous - repaint(); + repaint(); } - - - //------------------------------------------------------------------------- - // Dessin, déclenché par le repaint() de la méthode ci-dessus - //------------------------------------------------------------------------- + public void paintComponent(Graphics g) { - // On demande à la super-classe (JPanel) de se redessiner super.paintComponent(g); - // Puis on ajoute ce qui est spécifique à la classe - // on indique qu'il faut de l'antialiasing Graphics2D g2D = (Graphics2D) g; g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); + for (ObjetGraphique obj : listeObjets){ obj.Afficher(g); } + + // Affichage de l'écran Game Over if (isGameOver) { - g2D.setColor(new Color(0, 0, 0, 150)); // Fond noir transparent + g2D.setColor(new Color(0, 0, 0, 150)); // Fond sombre g2D.fillRect(0, 0, getWidth(), getHeight()); g2D.setColor(Color.WHITE); g2D.setFont(new Font("Arial", Font.BOLD, 50)); String msg = "GAME OVER"; - int largeurTexte = g2D.getFontMetrics().stringWidth(msg); - g2D.drawString(msg, (getWidth() - largeurTexte) / 2, getHeight() / 2); + int largeur = g2D.getFontMetrics().stringWidth(msg); + g2D.drawString(msg, (getWidth() - largeur) / 2, getHeight() / 2 - 50); } } public void setGameOver(boolean state) { this.isGameOver = state; + // 3. C'est ici qu'on affiche ou cache le bouton + btnRetour.setVisible(state); repaint(); } -} - - +} \ No newline at end of file