diff --git a/src/linea/CampagneAutoroute.java b/src/linea/CampagneAutoroute.java index 467d948..bbf4b9d 100644 --- a/src/linea/CampagneAutoroute.java +++ b/src/linea/CampagneAutoroute.java @@ -19,19 +19,11 @@ public class CampagneAutoroute { jeu.ecran.viderObjets(); // --- 1. CONFIGURATION DE LA DIFFICULTÉ --- - double vitesse = 5.0; - double pente = 30.0; + // On récupère les paramètres depuis la BDD au lieu de les coder en dur + double[] params = jeu.bdd.getParametresDifficulte(difficulte); + double vitesse = params[0]; + double pente = params[1]; - if (difficulte == 1) { // FACILE - vitesse = 6.0; - pente = 20.0; - } else if (difficulte == 2) { // MOYEN - vitesse = 7.0; - pente = 45.0; - } else if (difficulte == 3) { // DIFFICILE - vitesse = 8.0; - pente = 70.0; - } // --- 2. CRÉATION DES OBJETS diff --git a/src/linea/CampagneEspace.java b/src/linea/CampagneEspace.java index 8b5cc5b..1caf26e 100644 --- a/src/linea/CampagneEspace.java +++ b/src/linea/CampagneEspace.java @@ -19,19 +19,10 @@ public class CampagneEspace { jeu.ecran.viderObjets(); - double vitesse = 5.0; - double pente = 30.0; - - if (difficulte == 1) { // FACILE - vitesse = 6.0; - pente = 20.0; - } else if (difficulte == 2) { // MOYEN - vitesse = 7.0; - pente = 45.0; - } else if (difficulte == 3) { // DIFFICILE - vitesse = 8.0; - pente = 70.0; - } + // On récupère les paramètres depuis la BDD + double[] params = jeu.bdd.getParametresDifficulte(difficulte); + double vitesse = params[0]; + double pente = params[1]; // 1. Fond étoilé FondEspace fond = new FondEspace(); diff --git a/src/linea/CampagneOcean.java b/src/linea/CampagneOcean.java index f22422b..2d6693e 100644 --- a/src/linea/CampagneOcean.java +++ b/src/linea/CampagneOcean.java @@ -18,19 +18,10 @@ public class CampagneOcean { jeuPrincipal.horloge.stop(); } jeuPrincipal.horloge = new Timer(40, jeuPrincipal); - double vitesse = 5.0; - double pente = 30.0; - - if (difficulte == 1) { // FACILE - vitesse = 6.0; - pente = 20.0; - } else if (difficulte == 2) { // MOYEN - vitesse = 7.0; - pente = 45.0; - } else if (difficulte == 3) { // DIFFICILE - vitesse = 8.0; - pente = 70.0; - } + // On récupère les paramètres depuis la BDD + double[] params = jeuPrincipal.bdd.getParametresDifficulte(difficulte); + double vitesse = params[0]; + double pente = params[1]; jeuPrincipal.ecran.viderObjets(); diff --git a/src/linea/GestionnaireBDD.java b/src/linea/GestionnaireBDD.java index 4e510ff..53b119b 100644 --- a/src/linea/GestionnaireBDD.java +++ b/src/linea/GestionnaireBDD.java @@ -1,16 +1,16 @@ package linea; import java.sql.*; +import java.util.ArrayList; +import java.util.List; public class GestionnaireBDD { private Connection conn = null; - // On utilise une base de données SQLite, qui est un simple fichier. private final String DB_URL = "jdbc:sqlite:linea.db"; public GestionnaireBDD() { try { - // Le pilote JDBC pour SQLite doit être ajouté à votre projet. Class.forName("org.sqlite.JDBC"); conn = DriverManager.getConnection(DB_URL); System.out.println("Connexion à la base de données SQLite établie."); @@ -37,9 +37,11 @@ public class GestionnaireBDD { "campagne_id INT, " + "difficulte_id INT, " + "score INT, " + - "date_partie TIMESTAMP DEFAULT CURRENT_TIMESTAMP)"); + "utilisateur_id INT, " + + "date_partie TIMESTAMP DEFAULT CURRENT_TIMESTAMP, " + + "FOREIGN KEY(utilisateur_id) REFERENCES utilisateurs(id))"); - // NOUVELLE TABLE POUR LES UTILISATEURS + // TABLE POUR LES UTILISATEURS stmt.execute("CREATE TABLE IF NOT EXISTS utilisateurs (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "identifiant TEXT UNIQUE NOT NULL, " + @@ -56,17 +58,19 @@ public class GestionnaireBDD { } } - public boolean verifierUtilisateur(String identifiant, String motDePasse) { + public int verifierUtilisateur(String identifiant, String motDePasse) { String sql = "SELECT id FROM utilisateurs WHERE identifiant = ? AND mot_de_passe = ?"; try (PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, identifiant); pstmt.setString(2, motDePasse); - // Si rs.next() est vrai, cela signifie que la requête a trouvé une correspondance. - return pstmt.executeQuery().next(); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) { + return rs.getInt("id"); + } } catch (SQLException e) { System.out.println("Erreur lors de la vérification des identifiants : " + e.getMessage()); - return false; } + return -1; } public boolean creerCompte(String identifiant, String motDePasse) { @@ -113,20 +117,47 @@ public class GestionnaireBDD { return params; } - public void enregistrerPartie(int dureePartie, int idCampagneActive, int difficulteActive, int score) { - String sql = "INSERT INTO parties(duree, campagne_id, difficulte_id, score) VALUES(?,?,?,?)"; + public void enregistrerPartie(int dureePartie, int idCampagneActive, int difficulteActive, int score, int utilisateurId) { + if (utilisateurId == -1) { + System.out.println("Partie non enregistrée : aucun utilisateur connecté."); + return; + } + String sql = "INSERT INTO parties(duree, campagne_id, difficulte_id, score, utilisateur_id) VALUES(?,?,?,?,?)"; try (PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setInt(1, dureePartie); pstmt.setInt(2, idCampagneActive); pstmt.setInt(3, difficulteActive); pstmt.setInt(4, score); + pstmt.setInt(5, utilisateurId); pstmt.executeUpdate(); - System.out.println("Partie enregistrée avec succès."); + System.out.println("Partie enregistrée pour l'utilisateur ID " + utilisateurId); } catch (SQLException e) { System.out.println("Erreur lors de l'enregistrement de la partie : " + e.getMessage()); } } + public Object[][] getLeaderboardData() { + String sql = "SELECT u.identifiant, p.score, p.date_partie " + + "FROM parties p " + + "JOIN utilisateurs u ON p.utilisateur_id = u.id " + + "ORDER BY p.score DESC LIMIT 10"; + List data = new ArrayList<>(); + try (Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(sql)) { + while (rs.next()) { + Object[] row = { + rs.getString("identifiant"), + rs.getInt("score"), + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm").format(rs.getTimestamp("date_partie")) + }; + data.add(row); + } + } catch (SQLException e) { + System.out.println("Erreur lors de la récupération du leaderboard : " + e.getMessage()); + } + return data.toArray(new Object[0][]); + } + public void fermerConnexion() { try { if (conn != null) { diff --git a/src/linea/Jeu.java b/src/linea/Jeu.java index ed0798d..bdfe22f 100644 --- a/src/linea/Jeu.java +++ b/src/linea/Jeu.java @@ -15,6 +15,7 @@ public class Jeu implements KeyListener, ActionListener { protected MenuLogin menuLogin; protected MenuPrincipal menu; protected MenuCampagne menuCampagne; + protected MenuLeaderboard menuLeaderboard; protected Cercle demiCercleAvant; protected Cercle demiCercleArriere; @@ -26,6 +27,8 @@ public class Jeu implements KeyListener, ActionListener { //base de données protected GestionnaireBDD bdd = new GestionnaireBDD(); + protected int utilisateurIdConnecte = -1; + protected String identifiantUtilisateurConnecte; public int idCampagneActive = 0; // Retient la campagne (1 = Autoroute, etc.) public int difficulteActive = 0; // Retient la difficulté (1=Facile, 2=Moyen, 3=Difficile) @@ -48,6 +51,7 @@ public class Jeu implements KeyListener, ActionListener { menuLogin = new MenuLogin(this); menu = new MenuPrincipal(this); menuCampagne = new MenuCampagne(this); + menuLeaderboard = new MenuLeaderboard(this); // Initialisation initiale resetPartie(6,20); @@ -66,6 +70,7 @@ public class Jeu implements KeyListener, ActionListener { conteneurPrincipal.add(menuLogin, "LOGIN"); conteneurPrincipal.add(menu, "MENU"); conteneurPrincipal.add(menuCampagne, "CAMPAGNE"); + conteneurPrincipal.add(menuLeaderboard, "LEADERBOARD"); conteneurPrincipal.add(ecran, "JEU"); fenetre.setContentPane(conteneurPrincipal); @@ -85,6 +90,16 @@ public class Jeu implements KeyListener, ActionListener { fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } + public void setUtilisateurConnecte(int id, String identifiant) { + this.utilisateurIdConnecte = id; + this.identifiantUtilisateurConnecte = identifiant; + } + + public void afficherLeaderboard() { + menuLeaderboard.rafraichirLeaderboard(); + layout.show(conteneurPrincipal, "LEADERBOARD"); + } + public void afficherMenuCampagne() { layout.show(conteneurPrincipal, "CAMPAGNE"); } @@ -178,7 +193,7 @@ public class Jeu implements KeyListener, ActionListener { // On utilise nos deux variables pour la sauvegarde ! // L'appel est maintenant plus robuste grâce au nouveau GestionnaireBDD - bdd.enregistrerPartie(dureePartie, idCampagneActive, difficulteActive, score); + bdd.enregistrerPartie(dureePartie, idCampagneActive, difficulteActive, score, utilisateurIdConnecte); } // Gestion touches... @@ -197,4 +212,4 @@ public class Jeu implements KeyListener, ActionListener { } } @Override public void keyTyped(KeyEvent e) {} -} \ No newline at end of file +} diff --git a/src/linea/MenuLeaderboard.java b/src/linea/MenuLeaderboard.java new file mode 100644 index 0000000..983eced --- /dev/null +++ b/src/linea/MenuLeaderboard.java @@ -0,0 +1,58 @@ +package linea; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.*; + +public class MenuLeaderboard extends JPanel { + private JTable leaderboardTable; + private final Jeu jeu; + + public MenuLeaderboard(Jeu jeu) { + this.jeu = jeu; + setLayout(new BorderLayout(10, 10)); + setBackground(new Color(45, 45, 45)); + + JLabel titre = new JLabel("LEADERBOARD", SwingConstants.CENTER); + titre.setForeground(Color.WHITE); + titre.setFont(new Font("SansSerif", Font.BOLD, 40)); + add(titre, BorderLayout.NORTH); + + // Configuration du tableau + leaderboardTable = new JTable(); + leaderboardTable.setFont(new Font("SansSerif", Font.PLAIN, 16)); + leaderboardTable.setRowHeight(25); + leaderboardTable.setBackground(new Color(60, 60, 60)); + leaderboardTable.setForeground(Color.WHITE); + leaderboardTable.getTableHeader().setFont(new Font("SansSerif", Font.BOLD, 18)); + leaderboardTable.getTableHeader().setBackground(new Color(30, 30, 30)); + leaderboardTable.getTableHeader().setForeground(Color.WHITE); + + JScrollPane scrollPane = new JScrollPane(leaderboardTable); + scrollPane.getViewport().setBackground(new Color(45, 45, 45)); + scrollPane.setBorder(BorderFactory.createEmptyBorder(20, 50, 20, 50)); + add(scrollPane, BorderLayout.CENTER); + + // Bouton de retour + JButton btnRetour = new JButton("Retour"); + btnRetour.setFont(new Font("SansSerif", Font.PLAIN, 18)); + btnRetour.addActionListener(e -> jeu.afficherMenuPrincipal()); + + JPanel southPanel = new JPanel(); + southPanel.setBackground(new Color(45, 45, 45)); + southPanel.add(btnRetour); + add(southPanel, BorderLayout.SOUTH); + } + + public void rafraichirLeaderboard() { + Object[][] data = jeu.bdd.getLeaderboardData(); + String[] columnNames = {"Identifiant", "Score", "Date"}; + // Utilisation d'un DefaultTableModel pour rendre les cellules non éditables + leaderboardTable.setModel(new DefaultTableModel(data, columnNames) { + @Override + public boolean isCellEditable(int row, int column) { + return false; + } + }); + } +} \ No newline at end of file diff --git a/src/linea/MenuLogin.java b/src/linea/MenuLogin.java index 453952f..b877616 100644 --- a/src/linea/MenuLogin.java +++ b/src/linea/MenuLogin.java @@ -29,7 +29,8 @@ public class MenuLogin extends JPanel { fieldsPanel.add(identifiantField); fieldsPanel.add(new JLabel("Mot de passe :") {{ setForeground(Color.WHITE); setFont(new Font("SansSerif", Font.BOLD, 16)); }}); fieldsPanel.add(motDePasseField); -// Boutons + + // Boutons JButton btnLogin = creerBouton("Se connecter"); JButton btnSignup = creerBouton("Créer un compte"); JButton btnQuit = creerBouton("Quitter"); @@ -44,7 +45,9 @@ public class MenuLogin extends JPanel { return; } - if (jeu.bdd.verifierUtilisateur(identifiant, motDePasse)) { + int utilisateurId = jeu.bdd.verifierUtilisateur(identifiant, motDePasse); + if (utilisateurId != -1) { + jeu.setUtilisateurConnecte(utilisateurId, identifiant); JOptionPane.showMessageDialog(this, "Connexion réussie ! Bienvenue " + identifiant + "."); jeu.afficherMenuPrincipal(); } else { diff --git a/src/linea/MenuPrincipal.java b/src/linea/MenuPrincipal.java index a9ccebd..d77ab17 100644 --- a/src/linea/MenuPrincipal.java +++ b/src/linea/MenuPrincipal.java @@ -5,7 +5,8 @@ import javax.swing.*; public class MenuPrincipal extends JPanel { private JButton btnPlay; - private JButton btnCampaign; // Nouveau bouton + private JButton btnCampaign; + private JButton btnLeaderboard; private JButton btnSettings; private JButton btnQuit; @@ -21,17 +22,18 @@ public class MenuPrincipal extends JPanel { // Création des Boutons btnPlay = creerBouton("PLAY"); - btnCampaign = creerBouton("CAMPAGNES"); // Création + btnCampaign = creerBouton("CAMPAGNES"); + btnLeaderboard = creerBouton("LEADERBOARD"); btnSettings = creerBouton("SETTINGS"); btnQuit = creerBouton("QUIT"); // Actions btnPlay.addActionListener(e -> jeu.lancerPartie()); - // Action pour aller vers le menu campagne - // (Assure-toi d'avoir cette méthode dans ta classe Jeu) + btnCampaign.addActionListener(e -> jeu.afficherMenuCampagne()); + btnLeaderboard.addActionListener(e -> jeu.afficherLeaderboard()); btnSettings.addActionListener(e -> JOptionPane.showMessageDialog(this, "Options bientôt disponibles !")); btnQuit.addActionListener(e -> System.exit(0)); @@ -41,7 +43,9 @@ public class MenuPrincipal extends JPanel { add(Box.createRigidArea(new Dimension(0, 50))); add(btnPlay); add(Box.createRigidArea(new Dimension(0, 15))); - add(btnCampaign); // Ajout à l'affichage + add(btnCampaign); + add(Box.createRigidArea(new Dimension(0, 15))); + add(btnLeaderboard); add(Box.createRigidArea(new Dimension(0, 15))); add(btnSettings); add(Box.createRigidArea(new Dimension(0, 15)));