package linea; import java.awt.BorderLayout; import java.awt.Color; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.List; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.Timer; public class Jeu implements KeyListener, ActionListener { //------------------------------------------------------------------------- // PROPRIETES //------------------------------------------------------------------------- protected ZoneDessin ecran = new ZoneDessin(); protected Cercle demiCercleAvant; protected Cercle demiCercleArriere; protected Ligne ligne; private int _niv; protected Timer horloge; protected double score = 0; protected JLabel labScore; protected JLabel labMeilleurScore; private DatabaseConnection db; private int idCompte; private int meilleurSansCompte = 0; private int mortsSansCompte = 0; private int tempsSansCompteSec = 0; private long debutPartieMs = 0; private boolean immortel = false; private int meilleurActuel() { return idCompte > 0 ? db.getMeilleurScoreParCompte(idCompte) : meilleurSansCompte; } private String statsActuelles() { if (idCompte > 0) { return db.getStatsParCompte(idCompte); } return "Nombre de morts : " + mortsSansCompte + "\nTemps de jeu total : " + tempsSansCompteSec + " s" + "\nMeilleur score : " + meilleurSansCompte; } private void enregistrerPartie(int scoreActuel, int tempsPartieSec) { if (idCompte > 0) { db.sauvegarderScore(scoreActuel, idCompte, 1, tempsPartieSec); return; } meilleurSansCompte = Math.max(meilleurSansCompte, scoreActuel); mortsSansCompte += 1; tempsSansCompteSec += tempsPartieSec; } //------------------------------------------------------------------------- // CONSTRUCTEUR //------------------------------------------------------------------------- public Jeu(DatabaseConnection db, int idCompte, int niveau) { this.db = db; this.idCompte = idCompte; this._niv = niveau; labScore = new JLabel(); labScore.setText("

score : 0

"); labMeilleurScore = new JLabel(); JPanel panneauScores = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 0)); panneauScores.setOpaque(false); panneauScores.add(labScore); panneauScores.add(labMeilleurScore); ecran.add(panneauScores, BorderLayout.NORTH); rafraichirMeilleurScore(); } private void rafraichirMeilleurScore() { labMeilleurScore.setText("

meilleur : " + meilleurActuel() + "

"); } private boolean choisirNouveauCompte() { List pseudos = new ArrayList<>(db.getPseudos()); pseudos.add(0, "Sans compte"); String choix = (String) JOptionPane.showInputDialog( null, "Choisissez le compte pour la prochaine partie :", "Changer de compte", JOptionPane.QUESTION_MESSAGE, null, pseudos.toArray(String[]::new), pseudos.get(0) ); if (choix == null) { return false; } if ("Sans compte".equals(choix)) { idCompte = -1; meilleurSansCompte = 0; mortsSansCompte = 0; tempsSansCompteSec = 0; } else { idCompte = db.getIdParPseudo(choix); } rafraichirMeilleurScore(); return true; } private int choisirNouveauNiveau() { // Générer les niveaux dynamiquement jusqu'à 100 String[] niveaux = new String[100]; for (int i = 1; i <= 100; i++) { niveaux[i - 1] = genererLabelNiveau(i); } JList list = new JList<>(niveaux); list.setSelectedIndex(_niv - 1); list.setVisibleRowCount(15); JScrollPane scrollPane = new JScrollPane(list); scrollPane.setPreferredSize(new java.awt.Dimension(350, 350)); int result = JOptionPane.showConfirmDialog( null, scrollPane, "🎮 Sélection du Niveau - Linea", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE ); if (result == JOptionPane.OK_OPTION) { return list.getSelectedIndex() + 1; } return -1; } private String genererLabelNiveau(int niveau) { if (niveau <= 2) { return "⭐ Niveau " + niveau + " - Facile" + (niveau == 2 ? "+" : ""); } else if (niveau <= 4) { return "⭐⭐ Niveau " + niveau + " - Moyen" + (niveau == 4 ? "+" : ""); } else if (niveau <= 6) { return "⭐⭐⭐ Niveau " + niveau + " - Difficile" + (niveau == 6 ? "+" : ""); } else if (niveau <= 8) { return "⭐⭐⭐⭐ Niveau " + niveau + " - Très Difficile" + (niveau == 8 ? "+" : ""); } else if (niveau <= 10) { return "⭐⭐⭐⭐⭐ Niveau " + niveau + " - Expert" + (niveau == 10 ? "+" : ""); } else if (niveau <= 12) { return "🔥 Niveau " + niveau + " - Cauchemar" + (niveau == 12 ? "+" : ""); } else if (niveau <= 14) { return "🔥 Niveau " + niveau + " - Chaos" + (niveau == 14 ? "+" : ""); } else if (niveau <= 16) { return "💀 Niveau " + niveau + " - Infernal" + (niveau == 16 ? "+" : ""); } else if (niveau <= 18) { return "💀 Niveau " + niveau + " - Apocalypse" + (niveau == 18 ? "+" : ""); } else if (niveau <= 20) { return "⚡ Niveau " + niveau + " - Extrême" + (niveau == 20 ? "+" : ""); } else if (niveau <= 30) { return "⚡ Niveau " + niveau + " - Infini"; } else if (niveau <= 50) { return "∞ Niveau " + niveau + " - Au-delà"; } else { return "🌌 Niveau " + niveau + " - Cosmos"; } } private void choisirModeImmortel() { int result = JOptionPane.showConfirmDialog( null, "Activer le mode IMMORTEL ? 🛡️\n(Vous ne pourrez pas mourir)", "Mode Immortel", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE ); immortel = (result == JOptionPane.YES_OPTION); } //------------------------------------------------------------------------- // METHODES DE GESTION DU JEU //------------------------------------------------------------------------- /** * Centralise la création et la configuration des objets du jeu. * Évite de répéter ce code dans demarrer() et resetLevel(). */ private void initialiserPartie() { // 1. Nettoyage de l'écran ecran.reinitialiser(); // 2. Création des instances demiCercleAvant = new Cercle(90, -180); demiCercleArriere = new Cercle(90, 180); ligne = new Ligne(_niv); // 3. Configuration visuelle demiCercleArriere.setCouleur(new Color(0.8f, 0.0f, 0.0f)); demiCercleAvant.setCouleur(new Color(0.0f, 0.8f, 0.0f)); // 4. Ajout à l'écran (l'ordre définit la superposition) ecran.ajouterObjet(demiCercleArriere); ecran.ajouterObjet(ligne); ecran.ajouterObjet(demiCercleAvant); } public void demarrer() { // Demander si le mode immortel est activé choisirModeImmortel(); // Passer le flag immortel à l'écran ecran.setImmortel(immortel); JFrame fenetre = new JFrame("Linea Game" + (immortel ? " [MODE IMMORTEL 🛡️]" : "")); // Initialise les objets une première fois initialiserPartie(); ecran.addKeyListener(this); ecran.setFocusable(true); fenetre.setContentPane(ecran); fenetre.pack(); fenetre.setLocation(100, 100); fenetre.setVisible(true); fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Création et lancement du timer horloge = new Timer(40, this); horloge.start(); debutPartieMs = System.currentTimeMillis(); } private void resetLevel() { // Réinitialisation des variables de jeu score = 0; labScore.setText("

score : 0

"); // Demander le mode immortel à chaque reset choisirModeImmortel(); // Passer le flag immortel à l'écran ecran.setImmortel(immortel); // Ré-initialisation des objets graphiques initialiserPartie(); debutPartieMs = System.currentTimeMillis(); // Relance le timer existant et redonne le focus if (horloge != null) horloge.restart(); ecran.requestFocusInWindow(); } //------------------------------------------------------------------------- // EVENEMENTS (Timer & Clavier) //------------------------------------------------------------------------- @Override public void actionPerformed(ActionEvent e) { ecran.traiterBoucleAnimation(); // Vérifier si un bonus a été récupéré int bonus = ecran.getBonusRecupere(); if (bonus != 0) { ecran.reinitialiserBonus(); int nouveauNiveau = _niv + bonus; // Limiter le niveau entre 1 et 100 if (nouveauNiveau < 1) { nouveauNiveau = 1; } else if (nouveauNiveau > 100) { nouveauNiveau = 100; } _niv = nouveauNiveau; resetLevel(); return; } if (ecran.aCollision() && !immortel) { horloge.stop(); int scoreActuel = (int) score; int tempsPartieSec = (int) ((System.currentTimeMillis() - debutPartieMs) / 1000L); enregistrerPartie(scoreActuel, tempsPartieSec); rafraichirMeilleurScore(); while (true) { Object[] options = {"Relancer", "Changer de compte", "Changer de niveau", "Voir stats", "Quitter"}; int choix = JOptionPane.showOptionDialog(null, "Perdu\nScore : " + scoreActuel + "\nMeilleur : " + meilleurActuel(), "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]); if (choix == 0) { resetLevel(); break; } if (choix == 1) { if (choisirNouveauCompte()) { resetLevel(); break; } continue; } if (choix == 2) { int nouveauNiveau = choisirNouveauNiveau(); if (nouveauNiveau > 0) { _niv = nouveauNiveau; resetLevel(); break; } continue; } if (choix == 3) { JOptionPane.showMessageDialog(null, statsActuelles(), "Statistiques", JOptionPane.INFORMATION_MESSAGE); continue; } System.exit(0); } return; } // Calcul du score basé sur le temps écoulé score += (0.05 + (0.05 * horloge.getDelay() / 100.0)); labScore.setText("

score : " + (int)score + "

"); } @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_UP) { demiCercleAvant.Monter(); demiCercleArriere.Monter(); } } @Override public void keyReleased(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_UP) { demiCercleAvant.ArreterMonter(); demiCercleArriere.ArreterMonter(); } } @Override public void keyTyped(KeyEvent e) {} }