import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.SwingUtilities; import javax.swing.Timer; public class Jeu implements KeyListener, ActionListener{ //------------------------------------------------------------------------- // PROPRIETES //------------------------------------------------------------------------- // Ecran : instance de ZoneDessin, qui contiendra tous les objets graphiques // et les animera protected ZoneDessin ecran = new ZoneDessin(); // Le cercle : en fait 2 demis-cercles, un qui passera sous la ligne // un qui passera dessus protected Cercle demiCercleAvant = new Cercle(90,-180); // celui qui est sur la ligne protected Cercle demiCercleArriere = new Cercle(90,180); // celui qui est derrière la ligne // A FAIRE : ajouter les objets graphiques manquants, s'il y en a protected Ligne laLigne = new Ligne(); // Ligne infinie du jeu // Timer : un objet qui émet des événements à un intervalle choisi, // il sert à donner le pas de l'animation protected Timer horloge; // Une variable qui contiendra le score protected double score=0; // un label qui servira à afficher le score protected JLabel labScore; protected JLabel labTriche; protected boolean jeuCommence = false; protected boolean modeTriche = false; //------------------------------------------------------------------------- // METHODES //------------------------------------------------------------------------- //------------------------------------------------------------------------- // Constructeur de la classe //------------------------------------------------------------------------- public Jeu(){ // Gestion du score : a réactiver en fin de TP, inutile au début ecran.setLayout(null); labScore = new JLabel(); labScore.setText("

score : 0

"); labScore.setBounds(20, 0, 200, 50); ecran.add(labScore); labTriche = new JLabel(); labTriche.setText("

Mode de triche activé

"); labTriche.setBounds(600, 0, 200, 50); // Placé en haut à droite (la fenêtre fait 800 de large) labTriche.setVisible(false); // Caché par défaut au lancement ecran.add(labTriche); } //------------------------------------------------------------------------- // Méthodes qu'il faut implémenter pour être // conforme à un KeyListener //------------------------------------------------------------------------- //------------------------------------------------------------------------- // Appui sur une touche // -> l'événement est émis lorsqu'on appuie, puis selon le rythme de // répétition du clavier //------------------------------------------------------------------------- @Override public void keyPressed(KeyEvent e){ // keyCode 38 : up // keyCode 40 : down int keyCode = e.getKeyCode(); if (keyCode==38){ // touche "flèche vers le haut" // On demande aux deux demi-cercle de "monter" demiCercleAvant.Monter(); demiCercleArriere.Monter(); } if(keyCode==32){//touche espace modeTriche =!modeTriche; labTriche.setVisible(modeTriche); //afficher ou cacher le label } } //------------------------------------------------------------------------- // Relâchement de la touche //------------------------------------------------------------------------- @Override public void keyReleased(KeyEvent e){ // keyCode 38 : up // keyCode 40 : down int keyCode = e.getKeyCode(); if (keyCode==38){ // On demande aux deux demi-cercle "d'arrêter de monter" demiCercleAvant.ArreterMonter(); demiCercleArriere.ArreterMonter(); } } //------------------------------------------------------------------------- // Une méthode que nous n'utilisons pas //------------------------------------------------------------------------- @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } //------------------------------------------------------------------------- // Démarrage du jeu : // création de diverses instances et //------------------------------------------------------------------------- public void demarrer(){ // Création d'une fenêtre JFrame fenetre = new JFrame(); // A FAIRE : // placer dans l'instance de l'écran tous les objets graphiques nécessaires // par exemple : ecran.ajouterObjet(demiCerleArriere); this.ecran.ajouterObjet(demiCercleArriere); this.ecran.ajouterObjet(laLigne); this.ecran.ajouterObjet(demiCercleAvant); // on indique que c'est le jeu qui traitera les appuis sur une touche ecran.addKeyListener(this); ecran.setFocusable(true); fenetre.setContentPane(ecran); fenetre.pack(); fenetre.setLocation(100, 100); fenetre.setVisible(true); // s'assurer que l'écran reçoit le focus clavier ecran.requestFocusInWindow(); fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 🔹 Création du bouton Voir Scores javax.swing.JButton boutonScores = new javax.swing.JButton("Voir mes scores"); boutonScores.setBackground(Color.BLACK); // Couleur fond boutonScores.setForeground(Color.WHITE); // Couleur texte //boutonScores.setFont(new Font("Arial", Font.BOLD, 14)); // Police // Position du bouton boutonScores.setBounds(300, 20, 160, 30); // Action quand on clique boutonScores.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { java.util.List scores = GestionBDD.recupererTousLesScores(); int meilleurScore = GestionBDD.recupererMeilleurScore(); StringBuilder message = new StringBuilder(); message.append("Meilleur score : ").append(meilleurScore).append("\n\n"); message.append("Tous les scores :\n"); for (int score : scores) { message.append(score).append("\n"); } javax.swing.JOptionPane.showMessageDialog( fenetre, message.toString(), "Mes Scores", javax.swing.JOptionPane.INFORMATION_MESSAGE ); } }); // affichier le bouton à l'écran ecran.setLayout(null); ecran.add(boutonScores); // Création du timer horloge = new Timer(40, this); //propriétés dont on aura besoin pour utiliser NiveauxDataConnect //--------------------------------------------------------------------------------- // C'est ici qu'on appelle NiveauxDataConnect pour initialiser la connexion à la base de données des niveaux // On fera une synchronisation pour éviter que le jeu se fige // pendant l'initialisation de la base de données, qui peut prendre un peu de temps // On utilise un thread synchrone pour ne pas bloquer le thread principal du jeu //-------------------------------------------------------------------------------- // Initialisation de la BDD dans un thread séparé ; // démarrer le timer quoiqu'il arrive pour ne pas figer l'UI new Thread(() -> { try { NiveauxDataConnect niveau = new NiveauxDataConnect(); System.out.println("Connexion réussie !!!"); // démarrer le timer sur l'EDT même si l'initialisation BDD a échoué SwingUtilities.invokeLater(() -> { if (horloge != null && !horloge.isRunning()) { horloge.start(); } }); } catch (Exception ex) { ex.printStackTrace(); System.err.println("Erreur lors de l'initialisation de la connexion à la base de données : " + ex.getMessage()); } }).start(); // A FAIRE : // donner la couleur des 2 demi-cercles, par exemple : demiCerleArriere.setCouleur(new Color(0.8f,0.0f,0.0f)); demiCercleArriere.setCouleur(new Color(26, 95, 161)); demiCercleAvant.setCouleur(new Color(26, 95, 161)); } //------------------------------------------------------------------------------------------------ // Méthode appelée lorsqu'un événement timer se produit // -> C'est ici que la loqique et l'animation du jeu sont traitées // -> C'est ici que la vérification de la collision entre la ligne et le cercle doit être faite //------------------------------------------------------------------------------------------------ @Override public void actionPerformed(ActionEvent e) { this.ecran.traiterBoucleAnimation(); boolean verification = this.laLigne.estDansCercle(this.demiCercleAvant); if(verification){ // Ajouter les points continuellement tant que le segment est vert (cyan) this.score += 5; this.jeuCommence = true; }else{ //------------------------------------------------------------------------------------------------------------------- // A FAIRE: Le jeu peut s'arrêter si la ligne n'est pas dans le cercle // NB: Le jeu commence quand la ligne est dans le cercle // Au début le ligne n'est pas dans le cercle car la ligne est à droite du cercle, et elle se déplace vers la gauche //------------------------------------------------------------------------------------------------------------------- if (this.laLigne.getSegCourant()!=null && !this.modeTriche) { // Le jeu s'arrête si le joueur n'a pas traversé la première ligne this.horloge.stop(); // 1. Arrêter le temps this.ecran.partiePerdue = true; // 2. Signaler à l'écran this.ecran.repaint(); // 3. Forcer l'affichage du texte GestionBDD.ajouterScore((int)this.score);// enregistrement du score dans la base de donne } } labScore.setText("

score : " + this.score + "

"); } }