Ajout menu et boule(Bug sur cette derniere)

This commit is contained in:
2026-03-28 08:16:44 +01:00
parent 91aeead9e6
commit 4e8e947ff5
5 changed files with 368 additions and 15 deletions

75
linea/BouleBonus.java Normal file
View File

@@ -0,0 +1,75 @@
package linea;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
public class BouleBonus extends ObjetGraphique {
private double rayon = 15;
private double vitesse = 5.0;
private boolean estVerte; // true = bonus (niveau +1), false = malus (niveau -1)
private int frameCounter = 0;
public BouleBonus(double x, double y, boolean estVerte) {
this.x = x;
this.y = y;
this.estVerte = estVerte;
if (estVerte) {
this.couleur = new Color(0.0f, 0.8f, 0.0f); // Vert
} else {
this.couleur = new Color(0.8f, 0.0f, 0.0f); // Rouge
}
}
public double getRayon() {
return rayon;
}
public boolean isVerte() {
return estVerte;
}
@Override
void Afficher(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
// Effet de pulsation (le rayon augmente/diminue)
double rayonAffiche = rayon + Math.sin(frameCounter * 0.1) * 3;
// Dessiner le cercle rempli
g2D.setColor(couleur);
g2D.fillOval((int)(x - rayonAffiche/2), (int)(y - rayonAffiche),
(int)rayonAffiche, (int)rayonAffiche);
// Contour
g2D.setStroke(new BasicStroke(2.0f));
g2D.setColor(estVerte ? new Color(0.0f, 1.0f, 0.0f) : new Color(1.0f, 0.0f, 0.0f));
g2D.drawOval((int)(x - rayonAffiche/2), (int)(y - rayonAffiche),
(int)rayonAffiche, (int)rayonAffiche);
frameCounter++;
}
@Override
void Animer() {
// Déplacement vers la gauche (même vitesse que la ligne)
x -= vitesse;
}
// Vérifier collision avec le cercle
public boolean collisionAvec(Cercle c) {
double cx = c.getX();
double cy = c.getY();
double cRayon = c.getRayon();
double dist = Math.hypot(cx - x, cy - y);
return dist <= (rayon + cRayon);
}
public void setVitesse(double vitesse) {
this.vitesse = vitesse;
}
}

View File

@@ -11,8 +11,10 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Timer; import javax.swing.Timer;
public class Jeu implements KeyListener, ActionListener { public class Jeu implements KeyListener, ActionListener {
@@ -25,7 +27,7 @@ public class Jeu implements KeyListener, ActionListener {
protected Cercle demiCercleArriere; protected Cercle demiCercleArriere;
protected Ligne ligne; protected Ligne ligne;
private int _niv = 1; private int _niv;
protected Timer horloge; protected Timer horloge;
protected double score = 0; protected double score = 0;
protected JLabel labScore; protected JLabel labScore;
@@ -36,6 +38,7 @@ public class Jeu implements KeyListener, ActionListener {
private int mortsSansCompte = 0; private int mortsSansCompte = 0;
private int tempsSansCompteSec = 0; private int tempsSansCompteSec = 0;
private long debutPartieMs = 0; private long debutPartieMs = 0;
private boolean immortel = false;
private int meilleurActuel() { private int meilleurActuel() {
return idCompte > 0 ? db.getMeilleurScoreParCompte(idCompte) : meilleurSansCompte; return idCompte > 0 ? db.getMeilleurScoreParCompte(idCompte) : meilleurSansCompte;
@@ -63,9 +66,10 @@ public class Jeu implements KeyListener, ActionListener {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// CONSTRUCTEUR // CONSTRUCTEUR
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
public Jeu(DatabaseConnection db, int idCompte) { public Jeu(DatabaseConnection db, int idCompte, int niveau) {
this.db = db; this.db = db;
this.idCompte = idCompte; this.idCompte = idCompte;
this._niv = niveau;
labScore = new JLabel(); labScore = new JLabel();
labScore.setText("<html><h3>score : 0</h3></html>"); labScore.setText("<html><h3>score : 0</h3></html>");
@@ -113,6 +117,75 @@ public class Jeu implements KeyListener, ActionListener {
return true; 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<String> 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 // METHODES DE GESTION DU JEU
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@@ -141,7 +214,13 @@ public class Jeu implements KeyListener, ActionListener {
} }
public void demarrer() { public void demarrer() {
JFrame fenetre = new JFrame("Linea Game"); // 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 // Initialise les objets une première fois
initialiserPartie(); initialiserPartie();
@@ -165,6 +244,12 @@ public class Jeu implements KeyListener, ActionListener {
score = 0; score = 0;
labScore.setText("<html><h3>score : 0</h3></html>"); labScore.setText("<html><h3>score : 0</h3></html>");
// Demander le mode immortel à chaque reset
choisirModeImmortel();
// Passer le flag immortel à l'écran
ecran.setImmortel(immortel);
// Ré-initialisation des objets graphiques // Ré-initialisation des objets graphiques
initialiserPartie(); initialiserPartie();
debutPartieMs = System.currentTimeMillis(); debutPartieMs = System.currentTimeMillis();
@@ -181,8 +266,26 @@ public class Jeu implements KeyListener, ActionListener {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
ecran.traiterBoucleAnimation(); 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()) { if (ecran.aCollision() && !immortel) {
horloge.stop(); horloge.stop();
int scoreActuel = (int) score; int scoreActuel = (int) score;
@@ -192,7 +295,7 @@ public class Jeu implements KeyListener, ActionListener {
rafraichirMeilleurScore(); rafraichirMeilleurScore();
while (true) { while (true) {
Object[] options = {"Relancer", "Changer de compte", "Voir stats", "Quitter"}; Object[] options = {"Relancer", "Changer de compte", "Changer de niveau", "Voir stats", "Quitter"};
int choix = JOptionPane.showOptionDialog(null, int choix = JOptionPane.showOptionDialog(null,
"Perdu\nScore : " + scoreActuel + "\nMeilleur : " + meilleurActuel(), "Perdu\nScore : " + scoreActuel + "\nMeilleur : " + meilleurActuel(),
"Game Over", "Game Over",
@@ -212,6 +315,15 @@ public class Jeu implements KeyListener, ActionListener {
continue; continue;
} }
if (choix == 2) { 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); JOptionPane.showMessageDialog(null, statsActuelles(), "Statistiques", JOptionPane.INFORMATION_MESSAGE);
continue; continue;
} }

View File

@@ -8,7 +8,7 @@ import java.util.ArrayList;
public class Ligne extends ObjetGraphique{ public class Ligne extends ObjetGraphique{
private int nbSegments = 400; private int nbSegments = 4000;
private double xCercle = 400; private double xCercle = 400;
private Segment SegCourant; private Segment SegCourant;
// vitesse de déplacement (augmente légèrement chaque frame) // vitesse de déplacement (augmente légèrement chaque frame)
@@ -134,6 +134,11 @@ public class Ligne extends ObjetGraphique{
return false; return false;
} }
// Obtenir la vitesse actuelle de la ligne (pour les boules bonus)
public double getVitesse() {
return vitesse;
}
// distance minimale entre un point (px,py) et un segment (x1,y1)-(x2,y2) // distance minimale entre un point (px,py) et un segment (x1,y1)-(x2,y2)
private double pointSegmentDistance(double px, double py, double x1, double y1, double x2, double y2) { private double pointSegmentDistance(double px, double py, double x1, double y1, double x2, double y2) {
double vx = x2 - x1; double vx = x2 - x1;

View File

@@ -1,7 +1,9 @@
package linea; package linea;
import java.util.List; import java.util.List;
import javax.swing.JList;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.UIManager; import javax.swing.UIManager;
public class LineaAppli { public class LineaAppli {
@@ -24,6 +26,63 @@ public class LineaAppli {
); );
} }
private static int choisirNiveau() {
// 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<String> list = new JList<>(niveaux);
list.setSelectedIndex(0);
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 static 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 static Integer menuComptes(DatabaseConnection db) { private static Integer menuComptes(DatabaseConnection db) {
while (true) { while (true) {
Object[] options = {"Sélectionner", "Créer", "Supprimer", "Retour"}; Object[] options = {"Sélectionner", "Créer", "Supprimer", "Retour"};
@@ -93,13 +152,15 @@ public class LineaAppli {
switch (choix) { switch (choix) {
case 1 -> { case 1 -> {
new Jeu(db, -1).demarrer(); int niveau = choisirNiveau();
new Jeu(db, -1, niveau).demarrer();
return; return;
} }
case 0 -> { case 0 -> {
Integer idCompte = menuComptes(db); Integer idCompte = menuComptes(db);
if (idCompte != null) { if (idCompte != null) {
new Jeu(db, idCompte).demarrer(); int niveau = choisirNiveau();
new Jeu(db, idCompte, niveau).demarrer();
return; return;
} }
} }

View File

@@ -23,12 +23,33 @@ public class ZoneDessin extends JPanel {
private boolean collisionOccur = false; private boolean collisionOccur = false;
// indique si le cercle a déjà été sur la ligne (début de la phase de maintien) // indique si le cercle a déjà été sur la ligne (début de la phase de maintien)
private boolean hadBeenOnLine = false; private boolean hadBeenOnLine = false;
// mode immortel - ignore les collisions
private boolean immortel = false;
// liste des boules bonus
private ArrayList<BouleBonus> boolesBonus = new ArrayList<BouleBonus>();
// compteur pour générer les boules à intervalle régulier
private int compteurBoule = 0;
private int intervalleBoule = 80; // générer une boule tous les 80 frames
// type de bonus récupéré (-1 = rouge, 1 = vert, 0 = aucun)
private int bonusRecupere = 0;
public ZoneDessin(){ public ZoneDessin(){
setLayout(new BorderLayout()); setLayout(new BorderLayout());
setPreferredSize(new Dimension(800, 600)); setPreferredSize(new Dimension(800, 600));
setBackground(new Color(220,170,0)); setBackground(new Color(220,170,0));
} }
public void setImmortel(boolean immortel) {
this.immortel = immortel;
}
public int getBonusRecupere() {
return bonusRecupere;
}
public void reinitialiserBonus() {
bonusRecupere = 0;
}
// Ajout d'un objet graphique à la zone de dessin // Ajout d'un objet graphique à la zone de dessin
public void ajouterObjet(ObjetGraphique unObjet) { public void ajouterObjet(ObjetGraphique unObjet) {
@@ -48,9 +69,50 @@ public class ZoneDessin extends JPanel {
return; return;
} }
// 1. on déplace chaque objet graphique // --- 0. Récupérer la ligne pour synchroniser les boules ---
for (ObjetGraphique obj : listeObjets){ Ligne ligneObjet = null;
obj.Animer(); for (ObjetGraphique obj : listeObjets) {
if (obj instanceof Ligne) {
ligneObjet = (Ligne) obj;
break;
}
}
// --- 1. Générer une boule au bord droit sur la ligne ---
compteurBoule++;
if (compteurBoule >= intervalleBoule && ligneObjet != null) {
compteurBoule = 0;
boolean estVerte = Math.random() < 0.7;
// On récupère le Y du dernier segment de la ligne (bord droit de l'écran)
// Note: Si votre classe Ligne n'a pas de méthode pour avoir le Y à X=800,
// utilisez une valeur proche de la fin de votre liste de segments.
double spawnX = 800;
double spawnY = 300; // Valeur par défaut
// On crée la boule au bord droit (800)
BouleBonus boule = new BouleBonus(spawnX, spawnY, estVerte);
// On lui donne la vitesse actuelle de la ligne pour qu'elle suive le mouvement
boule.setVitesse(ligneObjet.getVitesse());
boolesBonus.add(boule);
}
// --- 2. Animation des objets ---
for (ObjetGraphique obj : listeObjets) obj.Animer();
// Mettre à jour la vitesse des boules (car la ligne accélère avec le temps)
if (ligneObjet != null) {
for (BouleBonus boule : boolesBonus) {
boule.setVitesse(ligneObjet.getVitesse());
boule.Animer();
}
}
// Les boules bougent via leur propre Animer() qui ajuste leur vitesse
for (BouleBonus boule : boolesBonus) {
boule.Animer();
} }
// 2. vérifier collisions entre une Ligne et un Cercle // 2. vérifier collisions entre une Ligne et un Cercle
@@ -67,9 +129,12 @@ public class ZoneDessin extends JPanel {
// Si le cercle n'est plus en contact (distance > rayon) // Si le cercle n'est plus en contact (distance > rayon)
// alors le joueur perd (il doit maintenir le contact). // alors le joueur perd (il doit maintenir le contact).
if (!l.collisionAvec(c)) { if (!l.collisionAvec(c)) {
collisionOccur = true; // Ignorer la collision si on est en mode immortel
estArrete = true; if (!immortel) {
break; collisionOccur = true;
estArrete = true;
break;
}
} }
} }
} }
@@ -77,8 +142,35 @@ public class ZoneDessin extends JPanel {
if (estArrete) break; if (estArrete) break;
} }
} }
// 3. vérifier collisions entre les boules bonus et le cercle
for (int i = boolesBonus.size() - 1; i >= 0; i--)
{
BouleBonus boule = boolesBonus.get(i);
boolean collision = false;
// 3. on demande à redessiner for (ObjetGraphique obj : listeObjets) {
if (obj instanceof Cercle) {
Cercle c = (Cercle) obj;
if (boule.collisionAvec(c)) {
// Si touché : on définit le bonus et on détruit la boule
bonusRecupere = boule.isVerte() ? 1 : -1;
boolesBonus.remove(i);
collision = true;
break;
}
}
}
//4. Détruire la boule si elle dépasse le joueur sans être touchée ---
// Le cercle est à X = 400. Si la boule est à X < 350, elle est "passée".
if (!collision && boule.getX() < 350) {
boolesBonus.remove(i);
// On ne change pas bonusRecupere ici (donc rien ne se passe)
}
}
// 5. on demande à redessiner
repaint(); repaint();
} }
@@ -93,6 +185,11 @@ public class ZoneDessin extends JPanel {
for (ObjetGraphique obj : listeObjets) { for (ObjetGraphique obj : listeObjets) {
obj.Afficher(g); obj.Afficher(g);
} }
// Afficher les boules bonus
for (BouleBonus boule : boolesBonus) {
boule.Afficher(g);
}
} }
// Indique si une collision est survenue // Indique si une collision est survenue
@@ -103,9 +200,12 @@ public class ZoneDessin extends JPanel {
// Réinitialise l'état de la zone de dessin et supprime les objets graphiques // Réinitialise l'état de la zone de dessin et supprime les objets graphiques
public void reinitialiser() { public void reinitialiser() {
listeObjets.clear(); listeObjets.clear();
boolesBonus.clear();
estArrete = false; estArrete = false;
collisionOccur = false; collisionOccur = false;
hadBeenOnLine = false; hadBeenOnLine = false;
bonusRecupere = 0;
compteurBoule = 0;
repaint(); repaint();
} }
} }