updateBoule/immortel

This commit is contained in:
2026-03-28 14:18:17 +01:00
parent 4e8e947ff5
commit 1e7f70ab6b
9 changed files with 679 additions and 147 deletions

View File

@@ -11,6 +11,14 @@ public class BouleBonus extends ObjetGraphique {
private double vitesse = 5.0;
private boolean estVerte; // true = bonus (niveau +1), false = malus (niveau -1)
private int frameCounter = 0;
private double vitesseVerticale = 0.0;
private double amplitudeOndulation = 0.2;
private double vitesseHorizontaleLisse = 0.0;
private double phaseOndulation = Math.random() * Math.PI * 2; // phase unique par boule
private static double clamp(double value, double min, double max) {
return Math.max(min, Math.min(max, value));
}
public BouleBonus(double x, double y, boolean estVerte) {
this.x = x;
@@ -19,8 +27,14 @@ public class BouleBonus extends ObjetGraphique {
if (estVerte) {
this.couleur = new Color(0.0f, 0.8f, 0.0f); // Vert
this.rayon = 15;
this.amplitudeOndulation = 0.45; // onde visible plus ample
this.vitesseHorizontaleLisse = 4.8;
} else {
this.couleur = new Color(0.8f, 0.0f, 0.0f); // Rouge
this.rayon = 14;
this.amplitudeOndulation = 0.14;
this.vitesseHorizontaleLisse = 4.3;
}
}
@@ -37,20 +51,18 @@ public class BouleBonus extends ObjetGraphique {
Graphics2D g2D = (Graphics2D) g;
// Effet de pulsation (le rayon augmente/diminue)
double rayonAffiche = rayon + Math.sin(frameCounter * 0.1) * 3;
double rayonAffiche = rayon + Math.sin(frameCounter * 0.12) * 1.5;
// Dessiner le cercle rempli
// Dessiner le cercle rempli (centré sur x,y)
g2D.setColor(couleur);
g2D.fillOval((int)(x - rayonAffiche/2), (int)(y - rayonAffiche),
(int)rayonAffiche, (int)rayonAffiche);
g2D.fillOval((int)(x - rayonAffiche), (int)(y - rayonAffiche),
(int)(2 * rayonAffiche), (int)(2 * 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++;
g2D.drawOval((int)(x - rayonAffiche), (int)(y - rayonAffiche),
(int)(2 * rayonAffiche), (int)(2 * rayonAffiche));
}
@Override
@@ -58,6 +70,64 @@ public class BouleBonus extends ObjetGraphique {
// Déplacement vers la gauche (même vitesse que la ligne)
x -= vitesse;
}
public void animerAvecCible(double vitesseLigne, double cibleY) {
animerAvecCible(vitesseLigne, cibleY, 0.0);
}
public void animerAvecCible(double vitesseLigne, double cibleY, double cibleVitesseY) {
// Vertes: trajectoire fluide à intercepter. Rouges: poursuite plus nette avec fenêtre d'esquive.
double facteurHorizontal = estVerte ? 0.88 : 0.64;
double vitesseMax = estVerte ? 9.2 : 5.8;
double vitessePoursuite = estVerte ? 0.075 : 0.050; // meilleure réactivité
double limiteVerticale = estVerte ? 1.85 : 1.05; // accélération verticale
double amortissement = estVerte ? 0.87 : 0.81; // moins de friction
double zoneMorte = estVerte ? 18.0 : 16.0; // zone mort réduite
double vitesseVerticaleMax = estVerte ? 4.2 : 2.6; // vitesses verticales plus hautes
double vitesseLigneSecurisee = Math.max(0.0, vitesseLigne);
double vitesseCible = Math.min(vitesseMax, vitesseLigneSecurisee * facteurHorizontal);
if (!estVerte) {
// Les rouges gardent une vitesse plus stable d'une boule à l'autre.
vitesseCible = vitesseCible * 0.68 + 4.5 * 0.32;
}
double deltaVitesse = clamp(vitesseCible - vitesseHorizontaleLisse, -0.25, 0.25);
double vitesseMaxLocale = vitesseMax;
if (!estVerte && x < 380) {
// En fin d'écran, on plafonne un peu la vitesse pour laisser une fenêtre d'esquive stable.
double facteurApproche = clamp((380.0 - x) / 180.0, 0.0, 1.0);
vitesseMaxLocale = vitesseMax - (0.55 * facteurApproche);
}
vitesseHorizontaleLisse = clamp(vitesseHorizontaleLisse + deltaVitesse, 4.0, vitesseMaxLocale);
vitesse = vitesseHorizontaleLisse;
x -= vitesse;
double vitesseJoueurLimitee = clamp(cibleVitesseY, -6.0, 6.0);
// Verte: anticipation légère + oscillation. Rouge: AUCUNE anticipation → trajectoire lisible, esquivable.
double anticipation = estVerte ? vitesseJoueurLimitee * 3.2 : 0.0;
double cibleLisse = cibleY + anticipation + (estVerte ? Math.sin(frameCounter * 0.055 + phaseOndulation) * 45.0 : 0.0);
double deltaY = cibleLisse - y;
if (Math.abs(deltaY) < zoneMorte) {
deltaY = 0;
}
vitesseVerticale += clamp(deltaY * vitessePoursuite, -limiteVerticale, limiteVerticale);
vitesseVerticale *= amortissement;
vitesseVerticale = clamp(vitesseVerticale, -vitesseVerticaleMax, vitesseVerticaleMax);
double ondulation = Math.sin(frameCounter * 0.085 + (estVerte ? 0.0 : 1.1)) * amplitudeOndulation;
y += vitesseVerticale + ondulation;
frameCounter++;
if (y < 20) {
y = 20;
vitesseVerticale = 0;
} else if (y > 580) {
y = 580;
vitesseVerticale = 0;
}
}
// Vérifier collision avec le cercle
public boolean collisionAvec(Cercle c) {
@@ -66,7 +136,8 @@ public class BouleBonus extends ObjetGraphique {
double cRayon = c.getRayon();
double dist = Math.hypot(cx - x, cy - y);
return dist <= (rayon + cRayon);
double seuil = estVerte ? (rayon + cRayon - 6.0) : (rayon + cRayon - 9.0);
return dist <= seuil;
}
public void setVitesse(double vitesse) {