From 64062f04f2ee4fef990f9422cee975477a019878 Mon Sep 17 00:00:00 2001 From: MOISOIU Stefan-Mihai <66520304+stefanmoisoiu@users.noreply.github.com> Date: Mon, 16 Mar 2026 16:09:19 +0100 Subject: [PATCH] ajout des niveaux --- .gitignore | 2 +- src/Cercle.java | 43 +++++++----- src/GestionnaireNiveau.java | 129 ++++++++++++++++++++++++++++++++++++ src/Jeu.java | 27 ++++++-- src/Ligne.java | 63 +++++++++++------- src/Niveau.java | 25 +++++++ src/ZoneDessin.java | 9 ++- 7 files changed, 252 insertions(+), 46 deletions(-) create mode 100644 src/GestionnaireNiveau.java create mode 100644 src/Niveau.java diff --git a/.gitignore b/.gitignore index 14392bf..09f6b6f 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,7 @@ bin/ # ======================== # 3. ANTIGRAVITY / VSCODE # ======================== -.vscode/ +.claude/ .antigravity/ *.code-workspace diff --git a/src/Cercle.java b/src/Cercle.java index 9463e6a..0d45a28 100644 --- a/src/Cercle.java +++ b/src/Cercle.java @@ -15,11 +15,12 @@ public class Cercle extends ObjetGraphique { // il s'agit plutôt d'arcs de cerc protected double fin = 360; protected boolean montee = false; - protected double vitesse = -1.0; + protected boolean descente = false; + protected double vitesse = 0; // pas = "delta t", permet de régler la jouabilité protected double pas = 0.2; - protected double impulsion = 35; + protected double impulsion = 2; public static int xCercle = 400; @@ -39,8 +40,10 @@ public class Cercle extends ObjetGraphique { // il s'agit plutôt d'arcs de cerc return rayon; } - // note que "haut" a été appuyée (évite d'être tributaire de la répétition - // clavier) + public void setRayon(double r) { + rayon = r; + } + public void Monter() { montee = true; } @@ -49,6 +52,14 @@ public class Cercle extends ObjetGraphique { // il s'agit plutôt d'arcs de cerc montee = false; } + public void Descendre() { + descente = true; + } + + public void ArreterDescendre() { + descente = false; + } + @Override void Afficher(Graphics g) { Graphics2D g2D = (Graphics2D) g; @@ -59,23 +70,25 @@ public class Cercle extends ObjetGraphique { // il s'agit plutôt d'arcs de cerc @Override void Animer() { - // chute libre - vitesse = vitesse + 9.81 * pas; - - // impulsion vers le haut + // acceleration vers le haut if (montee == true) { - vitesse = vitesse - impulsion * pas; + vitesse -= impulsion * pas; } - depY = 1 / 2 * 9.81 + vitesse * pas; + // acceleration vers le bas + if (descente == true) { + vitesse += impulsion * pas; + } - if (depY < -10) { - depY = -10; + // limiter la vitesse max + if (vitesse < -10) { + vitesse = -10; } - if (depY > 10) { - depY = 10; + if (vitesse > 10) { + vitesse = 10; } - y += depY; + + y += vitesse; } public void ResterDansLigne(Ligne li) { diff --git a/src/GestionnaireNiveau.java b/src/GestionnaireNiveau.java new file mode 100644 index 0000000..8b853b9 --- /dev/null +++ b/src/GestionnaireNiveau.java @@ -0,0 +1,129 @@ +package linea; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.List; + +public class GestionnaireNiveau { + + public static final int FRAMES_PAR_NIVEAU = 25 * 10; // 10s a 25 FPS (timer 40ms) + + private final List niveaux = new ArrayList<>(); + private int indexNiveau = 0; + private int framesDepuisDebut = 0; + private int framesDansNiveau = 0; + + // Duree du fade en frames + private static final int DUREE_FADE = 75; // 3 secondes + + public GestionnaireNiveau() { + + // Niveau 1 : lisse, cercle large + niveaux.add(new Niveau(1, + new Color(0, 73, 220), + 8, 1 / 80.0, 80, 100, 500)); + + // Niveau 2 + niveaux.add(new Niveau(2, + new Color(75, 0, 180), + 10, 1 / 60.0, 60, 100, 500)); + + // Niveau 3 + niveaux.add(new Niveau(3, + new Color(83, 30, 39), + 12, 1 / 40.0, 50, 100, 500)); + + // Niveau 4 + niveaux.add(new Niveau(4, + new Color(20, 100, 40), + 14, 1 / 30.0, 40, 100, 500)); + + // Niveau 5 : chaos, cercle petit + niveaux.add(new Niveau(5, + new Color(30, 30, 30), + 16, 1 / 20.0, 30, 100, 500)); + } + + public void mettreAJour() { + framesDepuisDebut++; + framesDansNiveau++; + + if (framesDansNiveau >= FRAMES_PAR_NIVEAU && indexNiveau < niveaux.size() - 1) { + indexNiveau++; + framesDansNiveau = 0; + } + } + + public Niveau getNiveauActuel() { + return niveaux.get(indexNiveau); + } + + public int getNumeroNiveau() { + return niveaux.get(indexNiveau).numero; + } + + public Color getCouleurFondInterpolee() { + if (framesDansNiveau < DUREE_FADE && indexNiveau > 0) { + Color de = niveaux.get(indexNiveau - 1).couleurFond; + Color vers = niveaux.get(indexNiveau).couleurFond; + double t = (double) framesDansNiveau / DUREE_FADE; + return interpolerCouleur(de, vers, t); + } + return niveaux.get(indexNiveau).couleurFond; + } + + public double getVitesseScroll() { + if (framesDansNiveau < DUREE_FADE && indexNiveau > 0) { + double de = niveaux.get(indexNiveau - 1).vitesseScroll; + double vers = niveaux.get(indexNiveau).vitesseScroll; + double t = (double) framesDansNiveau / DUREE_FADE; + return de + (vers - de) * t; + } + return niveaux.get(indexNiveau).vitesseScroll; + } + + public double getNoiseFrequence() { + if (framesDansNiveau < DUREE_FADE && indexNiveau > 0) { + double de = niveaux.get(indexNiveau - 1).noiseFrequence; + double vers = niveaux.get(indexNiveau).noiseFrequence; + double t = (double) framesDansNiveau / DUREE_FADE; + return de + (vers - de) * t; + } + return niveaux.get(indexNiveau).noiseFrequence; + } + + public double getRayonCercle() { + if (framesDansNiveau < DUREE_FADE && indexNiveau > 0) { + double de = niveaux.get(indexNiveau - 1).rayonCercle; + double vers = niveaux.get(indexNiveau).rayonCercle; + double t = (double) framesDansNiveau / DUREE_FADE; + return de + (vers - de) * t; + } + return niveaux.get(indexNiveau).rayonCercle; + } + + public double getLimiteHaut() { + return niveaux.get(indexNiveau).limiteHaut; + } + + public double getLimiteBas() { + return niveaux.get(indexNiveau).limiteBas; + } + + public void reinitialiser() { + indexNiveau = 0; + framesDepuisDebut = 0; + framesDansNiveau = 0; + } + + private static Color interpolerCouleur(Color de, Color vers, double t) { + int r = (int) (de.getRed() + (vers.getRed() - de.getRed()) * t); + int g = (int) (de.getGreen() + (vers.getGreen() - de.getGreen()) * t); + int b = (int) (de.getBlue() + (vers.getBlue() - de.getBlue()) * t); + return new Color( + Math.max(0, Math.min(255, r)), + Math.max(0, Math.min(255, g)), + Math.max(0, Math.min(255, b)) + ); + } +} diff --git a/src/Jeu.java b/src/Jeu.java index 9705bb0..5e56c3d 100644 --- a/src/Jeu.java +++ b/src/Jeu.java @@ -21,8 +21,8 @@ public class Jeu implements KeyListener, ActionListener, MouseListener { protected Cercle demiCercleAvant = new Cercle(90, -180); // celui qui est sur la ligne protected Cercle demiCercleArriere = new Cercle(90, 180); // celui qui est derrière la ligne - // A FAIRE : ajouter les objets graphiques manquants, s'il y en a - protected Ligne lili = new Ligne(new NoiseGenerator(0)); + protected GestionnaireNiveau gestionnaireNiveau = new GestionnaireNiveau(); + protected Ligne lili = new Ligne(new NoiseGenerator(0), gestionnaireNiveau); protected Timer horloge; @@ -69,16 +69,24 @@ public class Jeu implements KeyListener, ActionListener, MouseListener { demiCercleAvant.Monter(); demiCercleArriere.Monter(); } + if (keyCode == 40) { // flèche bas + demiCercleAvant.Descendre(); + demiCercleArriere.Descendre(); + } } @Override public void keyReleased(KeyEvent e) { int keyCode = e.getKeyCode(); - if (keyCode == 38) { + if (keyCode == 38) { // flèche haut demiCercleAvant.ArreterMonter(); demiCercleArriere.ArreterMonter(); } + if (keyCode == 40) { // flèche bas + demiCercleAvant.ArreterDescendre(); + demiCercleArriere.ArreterDescendre(); + } } @Override @@ -122,6 +130,7 @@ public class Jeu implements KeyListener, ActionListener, MouseListener { enCollision = false; estGameOver = false; compteurInvincible = 0; + gestionnaireNiveau.reinitialiser(); labGameOver.setVisible(false); ecran.demarrer(); @@ -141,6 +150,13 @@ public class Jeu implements KeyListener, ActionListener, MouseListener { return; } + gestionnaireNiveau.mettreAJour(); + ecran.setCouleurFond(gestionnaireNiveau.getCouleurFondInterpolee()); + + double rayon = gestionnaireNiveau.getRayonCercle(); + demiCercleAvant.setRayon(rayon); + demiCercleArriere.setRayon(rayon); + ecran.traiterBoucleAnimation(); compteurFrames = compteurFrames + 1; @@ -174,7 +190,7 @@ public class Jeu implements KeyListener, ActionListener, MouseListener { } } - labScore.setText("

Score : " + (int) score + " | Vies : " + vies + "

"); + labScore.setText("

Score : " + (int) score + " | Vies : " + vies + " | Niv. " + gestionnaireNiveau.getNumeroNiveau() + "

"); demiCercleArriere.ResterDansLigne(lili); demiCercleAvant.ResterDansLigne(lili); @@ -185,7 +201,8 @@ public class Jeu implements KeyListener, ActionListener, MouseListener { horloge.stop(); } - lili = new Ligne(new NoiseGenerator(0)); + gestionnaireNiveau.reinitialiser(); + lili = new Ligne(new NoiseGenerator(0), gestionnaireNiveau); demiCercleAvant.y = 200; demiCercleAvant.vitesse = -1.0; diff --git a/src/Ligne.java b/src/Ligne.java index 4a6a89b..3452152 100644 --- a/src/Ligne.java +++ b/src/Ligne.java @@ -13,35 +13,43 @@ public class Ligne extends ObjetGraphique { protected ArrayList listeSegments = new ArrayList(); - protected double limiteHaut = 50; - protected double limiteBas = 550; - protected Segment dernierSegment; private double decalageXDernierSegment = 0; - protected double noiseFrequence = 1/50f; - private NoiseGenerator noiseGenerator; + private GestionnaireNiveau gestionnaireNiveau; private double xActuel; - public Ligne(NoiseGenerator noiseGenerator) { + // Curseur dans le noise : avance plus vite quand la frequence du niveau augmente + private double noiseCurseur = 0; + + public Ligne(NoiseGenerator noiseGenerator, GestionnaireNiveau gestionnaireNiveau) { double x = 0; this.noiseGenerator = noiseGenerator; - for (int i = 0; i < nbSegments; i++) { + this.gestionnaireNiveau = gestionnaireNiveau; - Segment s = CreerSegment(x); + double dx = GetLargeurSegment(); + double freq = gestionnaireNiveau.getNoiseFrequence(); + + for (int i = 0; i < nbSegments; i++) { + double noiseStep = dx * freq; + double yDebut = CalculerY(noiseCurseur); + double yFin = CalculerY(noiseCurseur + noiseStep); + + Segment s = new Segment(x, yDebut, dx, yFin - yDebut); + s.setCouleur(new Color(0.2f, 0.2f, 0.2f)); listeSegments.add(s); + noiseCurseur += noiseStep; - if (i == nbSegments - 1) - { + if (i == nbSegments - 1) { dernierSegment = s; - xActuel = x + s.xLong; + xActuel = x + dx; } - x += s.xLong; + x += dx; } } @@ -49,26 +57,31 @@ public class Ligne extends ObjetGraphique { return (double)ZoneDessin.largeur / nbSegments; } - protected Segment CreerSegment(double x){ + protected Segment CreerSegmentSuivant(){ double dx = GetLargeurSegment(); - double y = CalculerY(x); - double dy = CalculerY(x + dx) - y; + double freq = gestionnaireNiveau.getNoiseFrequence(); + double noiseStep = dx * freq; - Segment s = new Segment(x, y, dx, dy); + double yDebut = CalculerY(noiseCurseur); + double yFin = CalculerY(noiseCurseur + noiseStep); + noiseCurseur += noiseStep; + + Segment s = new Segment(0, yDebut, dx, yFin - yDebut); s.setCouleur(new Color(0.2f, 0.2f, 0.2f)); return s; } - protected double CalculerY(double x){ - + protected double CalculerY(double noisePos){ + double limiteHaut = gestionnaireNiveau.getLimiteHaut(); + double limiteBas = gestionnaireNiveau.getLimiteBas(); double hauteur = limiteBas - limiteHaut; - double bruit = noiseGenerator.noise(x * noiseFrequence); - bruit = (bruit + 1) / 2; + double bruit = noiseGenerator.noise(noisePos); + double normalise = (bruit + 1) / 2; - return limiteBas - bruit * hauteur; + return limiteBas - normalise * hauteur; } @Override @@ -94,9 +107,11 @@ public class Ligne extends ObjetGraphique { @Override public void Animer() { + double vitesse = gestionnaireNiveau.getVitesseScroll(); + for (Segment s : listeSegments) { s.Animer(); - s.x -= 10; + s.x -= vitesse; } UpdateSegments(); @@ -110,7 +125,7 @@ public class Ligne extends ObjetGraphique { Segment s = listeSegments.get(i); if (s.x + s.xLong < 0) { - Segment nouveauSegment = CreerSegment(xActuel); + Segment nouveauSegment = CreerSegmentSuivant(); nouveauSegment.x = dernierSegment.x + dernierSegment.xLong; listeSegments.set(i, nouveauSegment); @@ -125,4 +140,4 @@ public class Ligne extends ObjetGraphique { return SegCourant.y + SegCourant.yLong * t; } -} \ No newline at end of file +} diff --git a/src/Niveau.java b/src/Niveau.java new file mode 100644 index 0000000..cf6696f --- /dev/null +++ b/src/Niveau.java @@ -0,0 +1,25 @@ +package linea; + +import java.awt.Color; + +public class Niveau { + + public final int numero; + public final Color couleurFond; + public final double vitesseScroll; + public final double noiseFrequence; // vitesse d'avancement dans le noise + public final double rayonCercle; + public final double limiteHaut; + public final double limiteBas; + + public Niveau(int numero, Color couleurFond, double vitesseScroll, + double noiseFrequence, double rayonCercle, double limiteHaut, double limiteBas) { + this.numero = numero; + this.couleurFond = couleurFond; + this.vitesseScroll = vitesseScroll; + this.noiseFrequence = noiseFrequence; + this.rayonCercle = rayonCercle; + this.limiteHaut = limiteHaut; + this.limiteBas = limiteBas; + } +} diff --git a/src/ZoneDessin.java b/src/ZoneDessin.java index 681fd6f..7f5f724 100644 --- a/src/ZoneDessin.java +++ b/src/ZoneDessin.java @@ -21,10 +21,17 @@ public class ZoneDessin extends JPanel { public static int largeur = 800; public static int hauteur = 600; + private Color couleurFond = new Color(0, 73, 220); + public ZoneDessin() { setLayout(new BorderLayout()); setPreferredSize(new Dimension(largeur, hauteur)); - setBackground(new Color(0, 73, 220)); + setBackground(couleurFond); + } + + public void setCouleurFond(Color c) { + couleurFond = c; + setBackground(c); } public void ajouterObjet(ObjetGraphique unObjet) {