package linea; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.util.ArrayList; import javax.swing.JPanel; public class ZoneDessin extends JPanel { private static final long serialVersionUID = 1L; // un booleen qui permet d'arreter l'animation (suspendre) protected boolean estArrete = false; // 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; // mode immortel - ignore les collisions private boolean immortel = false; // liste des boules bonus private ArrayList boolesBonus = new ArrayList(); // 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(){ setLayout(new BorderLayout()); setPreferredSize(new Dimension(800, 600)); 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 public void ajouterObjet(ObjetGraphique unObjet) { listeObjets.add(unObjet); } public void arreter(){ estArrete = true; } public void demarrer(){ estArrete = false; } public void traiterBoucleAnimation(){ if (estArrete==true) { return; } // --- 0. Récupérer la ligne pour synchroniser les boules --- Ligne ligneObjet = null; 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 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)) { // Ignorer la collision si on est en mode immortel if (!immortel) { collisionOccur = true; estArrete = true; 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; 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(); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2D = (Graphics2D) g; g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); // Afficher tous les objets for (ObjetGraphique obj : listeObjets) { obj.Afficher(g); } // Afficher les boules bonus for (BouleBonus boule : boolesBonus) { boule.Afficher(g); } } // Indique si une collision est survenue public boolean aCollision() { return collisionOccur; } // Réinitialise l'état de la zone de dessin et supprime les objets graphiques public void reinitialiser() { listeObjets.clear(); boolesBonus.clear(); estArrete = false; collisionOccur = false; hadBeenOnLine = false; bonusRecupere = 0; compteurBoule = 0; repaint(); } }