From 866bd17e29986b55999e688e15ca49849001f1a1 Mon Sep 17 00:00:00 2001 From: Richard3il Date: Mon, 23 Feb 2026 09:41:54 +0100 Subject: [PATCH] Collision entre le cercle et la ligne --- linea/Cercle.java | 10 ++++---- linea/Jeu.java | 10 +++++++- linea/Ligne.java | 56 ++++++++++++++++++++++++++++++++++++++++--- linea/LineaAppli.java | 1 - linea/ZoneDessin.java | 38 +++++++++++++++++++++++++++-- 5 files changed, 103 insertions(+), 12 deletions(-) diff --git a/linea/Cercle.java b/linea/Cercle.java index 6bdece3..c311c30 100644 --- a/linea/Cercle.java +++ b/linea/Cercle.java @@ -97,6 +97,11 @@ public class Cercle extends ObjetGraphique{ // il s'agit plutôt d'arcs de cercl g2D.draw(new Arc2D.Double(x-rayon/2, y-rayon, rayon, rayon*2, debut, fin, Arc2D.OPEN)); } + // Accesseur pour savoir si le joueur maintient la montée + public boolean isMontee() { + return montee; + } + //------------------------------------------------------------------------- // Redéfinition de la méthode Animer, spécifiquement pour la classe @@ -131,9 +136,4 @@ public class Cercle extends ObjetGraphique{ // il s'agit plutôt d'arcs de cercl } } - - - - - } diff --git a/linea/Jeu.java b/linea/Jeu.java index 079a8f9..6a53e7c 100644 --- a/linea/Jeu.java +++ b/linea/Jeu.java @@ -7,6 +7,7 @@ import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.Timer; public class Jeu implements KeyListener, ActionListener{ @@ -114,8 +115,8 @@ public class Jeu implements KeyListener, ActionListener{ // A FAIRE : // placer dans l'instance de l'écran tous les objets graphiques nécessaires // par exemple : ecran.ajouterObjet(demiCerleArriere); - ecran.ajouterObjet(ligne); ecran.ajouterObjet(demiCercleArriere); + ecran.ajouterObjet(ligne); ecran.ajouterObjet(demiCercleAvant); @@ -146,6 +147,13 @@ public class Jeu implements KeyListener, ActionListener{ @Override public void actionPerformed(ActionEvent e) { ecran.traiterBoucleAnimation(); + if (ecran.aCollision()) { + horloge.stop(); + JOptionPane.showMessageDialog(null, "Game Over"); + return; + } + score+=(0.05+(0.05*horloge.getDelay()/100.0)); + labScore.setText("

score : "+(int)score+"

"); } } diff --git a/linea/Ligne.java b/linea/Ligne.java index db2cf45..24b46d9 100644 --- a/linea/Ligne.java +++ b/linea/Ligne.java @@ -51,7 +51,57 @@ public class Ligne extends ObjetGraphique{ for (Segment seg : segments) { seg.x -= delta; } - - - } } + + + // Indique si l'axe horizontal du cercle (cx) se trouve au niveau + // d'un des segments de la ligne -> le cercle est "sur la ligne" + public boolean estSurLaLigne(double cx) { + for (Segment seg : segments) { + double x1 = seg.x; + double x2 = seg.x + seg.xLong; + if ((cx >= Math.min(x1, x2)) && (cx <= Math.max(x1, x2))) { + return true; + } + } + return false; + } + + // Vérifie la collision entre la ligne (segments) et un cercle + public boolean collisionAvec(Cercle c) { + double cx = c.getX(); + double cy = c.getY(); + double rayon = c.getRayon(); + + for (Segment seg : segments) { + double x1 = seg.x; + double y1 = seg.y; + double x2 = seg.x + seg.xLong; + double y2 = seg.y + seg.yLong; + + double dist = pointSegmentDistance(cx, cy, x1, y1, x2, y2); + if (dist <= rayon) { + return true; + } + } + return false; + } + + // 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) { + double vx = x2 - x1; + double vy = y2 - y1; + double wx = px - x1; + double wy = py - y1; + double c = vx*vx + vy*vy; + if (c == 0) { + return Math.hypot(px - x1, py - y1); + } + double t = (vx*wx + vy*wy) / c; + if (t < 0) t = 0; + else if (t > 1) t = 1; + double projx = x1 + t * vx; + double projy = y1 + t * vy; + return Math.hypot(px - projx, py - projy); + } +} diff --git a/linea/LineaAppli.java b/linea/LineaAppli.java index eaddfaf..eb40de1 100644 --- a/linea/LineaAppli.java +++ b/linea/LineaAppli.java @@ -11,5 +11,4 @@ public class LineaAppli { jeu.demarrer(); } - } diff --git a/linea/ZoneDessin.java b/linea/ZoneDessin.java index eec682d..2bd241a 100644 --- a/linea/ZoneDessin.java +++ b/linea/ZoneDessin.java @@ -19,6 +19,10 @@ public class ZoneDessin extends JPanel { // liste des objets graphiques private ArrayList listeObjets = new ArrayList(); + // indicateur qu'une défaite (perte de contact) est survenue + private boolean collisionOccur = false; + // indique si le cercle a déjà été sur la ligne (début de la phase de maintien) + private boolean hadBeenOnLine = false; public ZoneDessin(){ setLayout(new BorderLayout()); @@ -49,8 +53,33 @@ public class ZoneDessin extends JPanel { obj.Animer(); } - // 2. on demande à redessiner - repaint(); + // 2. vérifier collisions entre une Ligne et un Cercle + for (ObjetGraphique obj : listeObjets) { + if (obj instanceof Ligne) { + Ligne l = (Ligne) obj; + for (ObjetGraphique other : listeObjets) { + if (other instanceof Cercle) { + Cercle c = (Cercle) other; + // On commence à surveiller une fois que le centre du + // cercle est au-dessus d'un segment (le cercle est "sur la ligne"). + if (l.estSurLaLigne(c.getX())) { + hadBeenOnLine = true; + // Si le cercle n'est plus en contact (distance > rayon) + // alors le joueur perd (il doit maintenir le contact). + if (!l.collisionAvec(c)) { + collisionOccur = true; + estArrete = true; + break; + } + } + } + } + if (estArrete) break; + } + } + + // 3. on demande à redessiner + repaint(); } @Override @@ -65,4 +94,9 @@ public class ZoneDessin extends JPanel { obj.Afficher(g); } } + + // Indique si une collision est survenue + public boolean aCollision() { + return collisionOccur; + } } \ No newline at end of file