updateBoule/immortel
This commit is contained in:
@@ -11,6 +11,14 @@ public class BouleBonus extends ObjetGraphique {
|
|||||||
private double vitesse = 5.0;
|
private double vitesse = 5.0;
|
||||||
private boolean estVerte; // true = bonus (niveau +1), false = malus (niveau -1)
|
private boolean estVerte; // true = bonus (niveau +1), false = malus (niveau -1)
|
||||||
private int frameCounter = 0;
|
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) {
|
public BouleBonus(double x, double y, boolean estVerte) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
@@ -19,8 +27,14 @@ public class BouleBonus extends ObjetGraphique {
|
|||||||
|
|
||||||
if (estVerte) {
|
if (estVerte) {
|
||||||
this.couleur = new Color(0.0f, 0.8f, 0.0f); // Vert
|
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 {
|
} else {
|
||||||
this.couleur = new Color(0.8f, 0.0f, 0.0f); // Rouge
|
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;
|
Graphics2D g2D = (Graphics2D) g;
|
||||||
|
|
||||||
// Effet de pulsation (le rayon augmente/diminue)
|
// 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.setColor(couleur);
|
||||||
g2D.fillOval((int)(x - rayonAffiche/2), (int)(y - rayonAffiche),
|
g2D.fillOval((int)(x - rayonAffiche), (int)(y - rayonAffiche),
|
||||||
(int)rayonAffiche, (int)rayonAffiche);
|
(int)(2 * rayonAffiche), (int)(2 * rayonAffiche));
|
||||||
|
|
||||||
// Contour
|
// Contour
|
||||||
g2D.setStroke(new BasicStroke(2.0f));
|
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.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),
|
g2D.drawOval((int)(x - rayonAffiche), (int)(y - rayonAffiche),
|
||||||
(int)rayonAffiche, (int)rayonAffiche);
|
(int)(2 * rayonAffiche), (int)(2 * rayonAffiche));
|
||||||
|
|
||||||
frameCounter++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -58,6 +70,64 @@ public class BouleBonus extends ObjetGraphique {
|
|||||||
// Déplacement vers la gauche (même vitesse que la ligne)
|
// Déplacement vers la gauche (même vitesse que la ligne)
|
||||||
x -= vitesse;
|
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
|
// Vérifier collision avec le cercle
|
||||||
public boolean collisionAvec(Cercle c) {
|
public boolean collisionAvec(Cercle c) {
|
||||||
@@ -66,7 +136,8 @@ public class BouleBonus extends ObjetGraphique {
|
|||||||
double cRayon = c.getRayon();
|
double cRayon = c.getRayon();
|
||||||
|
|
||||||
double dist = Math.hypot(cx - x, cy - y);
|
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) {
|
public void setVitesse(double vitesse) {
|
||||||
|
|||||||
@@ -71,6 +71,10 @@ public class Cercle extends ObjetGraphique{ // il s'agit plutôt d'arcs de cercl
|
|||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
public void Monter(){
|
public void Monter(){
|
||||||
montee = true;
|
montee = true;
|
||||||
|
// Évite l'effet "chute incontrôlable" quand on reprend la montée tard.
|
||||||
|
if (vitesse > 2.0) {
|
||||||
|
vitesse = 2.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -108,31 +112,36 @@ public class Cercle extends ObjetGraphique{ // il s'agit plutôt d'arcs de cercl
|
|||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
@Override
|
@Override
|
||||||
void Animer() {
|
void Animer() {
|
||||||
// pas est à prendre comme un "delta t"
|
double gravite = 0.95;
|
||||||
|
double poussee = 1.45;
|
||||||
// chute libre
|
double amortissement = 0.92;
|
||||||
vitesse = vitesse + 9.81 * pas;
|
|
||||||
|
|
||||||
// impulsion
|
|
||||||
if (montee==true) {
|
if (montee==true) {
|
||||||
vitesse = vitesse - impulsion *pas;
|
vitesse -= poussee;
|
||||||
|
} else {
|
||||||
|
vitesse += gravite;
|
||||||
}
|
}
|
||||||
|
|
||||||
depY = 1/2 * 9.81 + vitesse * pas;
|
// Lissage global pour un ressenti plus régulier.
|
||||||
|
vitesse *= amortissement;
|
||||||
if (depY<-10) {
|
|
||||||
depY=-10;
|
if (vitesse < -6.5) {
|
||||||
|
vitesse = -6.5;
|
||||||
}
|
}
|
||||||
if (depY>10){
|
if (vitesse > 6.5) {
|
||||||
depY =10;
|
vitesse = 6.5;
|
||||||
}
|
}
|
||||||
y+=depY;
|
|
||||||
|
depY = vitesse;
|
||||||
|
y += depY;
|
||||||
|
|
||||||
//position
|
//position
|
||||||
if(y<= 0 + rayon){
|
if(y<= 0 + rayon){
|
||||||
y = 0 + rayon;
|
y = 0 + rayon;
|
||||||
|
vitesse = 0;
|
||||||
}else if(y>=600 - rayon){
|
}else if(y>=600 - rayon){
|
||||||
y = 600 - rayon;
|
y = 600 - rayon;
|
||||||
|
vitesse = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,14 +65,6 @@ public class DatabaseConnection {
|
|||||||
);
|
);
|
||||||
""";
|
""";
|
||||||
|
|
||||||
String createNiveau = """
|
|
||||||
CREATE TABLE IF NOT EXISTS Niveau (
|
|
||||||
id_niveau INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
nom TEXT,
|
|
||||||
nb_Objet INTEGER NOT NULL
|
|
||||||
);
|
|
||||||
""";
|
|
||||||
|
|
||||||
String createScore = """
|
String createScore = """
|
||||||
CREATE TABLE IF NOT EXISTS Score (
|
CREATE TABLE IF NOT EXISTS Score (
|
||||||
id_score INTEGER PRIMARY KEY AUTOINCREMENT,
|
id_score INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
@@ -80,16 +72,23 @@ public class DatabaseConnection {
|
|||||||
nb_mort INTEGER,
|
nb_mort INTEGER,
|
||||||
temps_jeu INTEGER,
|
temps_jeu INTEGER,
|
||||||
id_compte INTEGER,
|
id_compte INTEGER,
|
||||||
id_niveau INTEGER,
|
FOREIGN KEY(id_compte) REFERENCES Compte(id_compte)
|
||||||
FOREIGN KEY(id_compte) REFERENCES Compte(id_compte),
|
);
|
||||||
FOREIGN KEY(id_niveau) REFERENCES Niveau(id_niveau)
|
""";
|
||||||
|
|
||||||
|
String createProgressionCampagne = """
|
||||||
|
CREATE TABLE IF NOT EXISTS ProgressionCampagne (
|
||||||
|
id_compte INTEGER PRIMARY KEY,
|
||||||
|
niveau_debloque_max INTEGER NOT NULL DEFAULT 1,
|
||||||
|
FOREIGN KEY(id_compte) REFERENCES Compte(id_compte)
|
||||||
);
|
);
|
||||||
""";
|
""";
|
||||||
|
|
||||||
try (Statement stmt = conn.createStatement()) {
|
try (Statement stmt = conn.createStatement()) {
|
||||||
stmt.executeUpdate(createCompte);
|
stmt.executeUpdate(createCompte);
|
||||||
stmt.executeUpdate(createNiveau);
|
|
||||||
stmt.executeUpdate(createScore);
|
stmt.executeUpdate(createScore);
|
||||||
|
stmt.executeUpdate("DROP TABLE IF EXISTS Niveau");
|
||||||
|
stmt.executeUpdate(createProgressionCampagne);
|
||||||
System.out.println("Tables créées / existantes OK");
|
System.out.println("Tables créées / existantes OK");
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
System.err.println("Erreur création tables : " + e.getMessage());
|
System.err.println("Erreur création tables : " + e.getMessage());
|
||||||
@@ -131,7 +130,11 @@ public class DatabaseConnection {
|
|||||||
ps.setString(1, pseudo.trim());
|
ps.setString(1, pseudo.trim());
|
||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
try (ResultSet rs = ps.getGeneratedKeys()) {
|
try (ResultSet rs = ps.getGeneratedKeys()) {
|
||||||
if (rs.next()) return rs.getInt(1);
|
if (rs.next()) {
|
||||||
|
int idCompte = rs.getInt(1);
|
||||||
|
initialiserProgressionCampagne(idCompte);
|
||||||
|
return idCompte;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
System.err.println("Erreur création compte : " + e.getMessage());
|
System.err.println("Erreur création compte : " + e.getMessage());
|
||||||
@@ -155,8 +158,11 @@ public class DatabaseConnection {
|
|||||||
|
|
||||||
public void supprimerCompte(int idCompte) {
|
public void supprimerCompte(int idCompte) {
|
||||||
if (conn == null || idCompte <= 0) return;
|
if (conn == null || idCompte <= 0) return;
|
||||||
try (PreparedStatement ps1 = conn.prepareStatement("DELETE FROM Score WHERE id_compte = ?");
|
try (PreparedStatement ps0 = conn.prepareStatement("DELETE FROM ProgressionCampagne WHERE id_compte = ?");
|
||||||
|
PreparedStatement ps1 = conn.prepareStatement("DELETE FROM Score WHERE id_compte = ?");
|
||||||
PreparedStatement ps2 = conn.prepareStatement("DELETE FROM Compte WHERE id_compte = ?")) {
|
PreparedStatement ps2 = conn.prepareStatement("DELETE FROM Compte WHERE id_compte = ?")) {
|
||||||
|
ps0.setInt(1, idCompte);
|
||||||
|
ps0.executeUpdate();
|
||||||
ps1.setInt(1, idCompte);
|
ps1.setInt(1, idCompte);
|
||||||
ps1.executeUpdate();
|
ps1.executeUpdate();
|
||||||
ps2.setInt(1, idCompte);
|
ps2.setInt(1, idCompte);
|
||||||
@@ -181,6 +187,53 @@ public class DatabaseConnection {
|
|||||||
return pseudos;
|
return pseudos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initialiserProgressionCampagne(int idCompte) {
|
||||||
|
if (conn == null || idCompte <= 0) return;
|
||||||
|
String sql = "INSERT OR IGNORE INTO ProgressionCampagne (id_compte, niveau_debloque_max) VALUES (?, 1)";
|
||||||
|
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||||
|
ps.setInt(1, idCompte);
|
||||||
|
ps.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.err.println("Erreur init progression campagne : " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNiveauDebloqueCampagne(int idCompte) {
|
||||||
|
if (conn == null || idCompte <= 0) return 1;
|
||||||
|
|
||||||
|
initialiserProgressionCampagne(idCompte);
|
||||||
|
String sql = "SELECT niveau_debloque_max FROM ProgressionCampagne WHERE id_compte = ?";
|
||||||
|
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||||
|
ps.setInt(1, idCompte);
|
||||||
|
try (ResultSet rs = ps.executeQuery()) {
|
||||||
|
if (rs.next()) {
|
||||||
|
int niveau = rs.getInt("niveau_debloque_max");
|
||||||
|
if (niveau < 1) return 1;
|
||||||
|
return Math.min(100, niveau);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.err.println("Erreur lecture progression campagne : " + e.getMessage());
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void debloquerNiveauCampagne(int idCompte, int niveauTermine) {
|
||||||
|
if (conn == null || idCompte <= 0) return;
|
||||||
|
|
||||||
|
int niveauCible = Math.min(100, Math.max(1, niveauTermine + 1));
|
||||||
|
initialiserProgressionCampagne(idCompte);
|
||||||
|
|
||||||
|
String sql = "UPDATE ProgressionCampagne SET niveau_debloque_max = MAX(niveau_debloque_max, ?) WHERE id_compte = ?";
|
||||||
|
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||||
|
ps.setInt(1, niveauCible);
|
||||||
|
ps.setInt(2, idCompte);
|
||||||
|
ps.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.err.println("Erreur mise à jour progression campagne : " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getStatsParCompte(int idCompte) {
|
public String getStatsParCompte(int idCompte) {
|
||||||
if (conn == null || idCompte <= 0) {
|
if (conn == null || idCompte <= 0) {
|
||||||
return "Aucune statistique disponible.";
|
return "Aucune statistique disponible.";
|
||||||
@@ -207,5 +260,18 @@ public class DatabaseConnection {
|
|||||||
}
|
}
|
||||||
return "Aucune statistique disponible.";
|
return "Aucune statistique disponible.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getStatsCampagneParCompte(int idCompte) {
|
||||||
|
if (conn == null || idCompte <= 0) {
|
||||||
|
return "Campagne : non disponible.";
|
||||||
|
}
|
||||||
|
|
||||||
|
int niveauMax = getNiveauDebloqueCampagne(idCompte);
|
||||||
|
int niveauxTermines = Math.max(0, niveauMax - 1);
|
||||||
|
|
||||||
|
return "Campagne\n"
|
||||||
|
+ "Niveau max débloqué : " + niveauMax
|
||||||
|
+ "\nNiveaux terminés : " + niveauxTermines;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
linea/Jeu.db
BIN
linea/Jeu.db
Binary file not shown.
227
linea/Jeu.java
227
linea/Jeu.java
@@ -29,9 +29,11 @@ public class Jeu implements KeyListener, ActionListener {
|
|||||||
|
|
||||||
private int _niv;
|
private int _niv;
|
||||||
protected Timer horloge;
|
protected Timer horloge;
|
||||||
|
protected JFrame fenetre;
|
||||||
protected double score = 0;
|
protected double score = 0;
|
||||||
protected JLabel labScore;
|
protected JLabel labScore;
|
||||||
protected JLabel labMeilleurScore;
|
protected JLabel labMeilleurScore;
|
||||||
|
protected JLabel labNiveau;
|
||||||
private DatabaseConnection db;
|
private DatabaseConnection db;
|
||||||
private int idCompte;
|
private int idCompte;
|
||||||
private int meilleurSansCompte = 0;
|
private int meilleurSansCompte = 0;
|
||||||
@@ -39,6 +41,7 @@ public class Jeu implements KeyListener, ActionListener {
|
|||||||
private int tempsSansCompteSec = 0;
|
private int tempsSansCompteSec = 0;
|
||||||
private long debutPartieMs = 0;
|
private long debutPartieMs = 0;
|
||||||
private boolean immortel = false;
|
private boolean immortel = false;
|
||||||
|
private final boolean modeCampagne;
|
||||||
|
|
||||||
private int meilleurActuel() {
|
private int meilleurActuel() {
|
||||||
return idCompte > 0 ? db.getMeilleurScoreParCompte(idCompte) : meilleurSansCompte;
|
return idCompte > 0 ? db.getMeilleurScoreParCompte(idCompte) : meilleurSansCompte;
|
||||||
@@ -46,11 +49,11 @@ public class Jeu implements KeyListener, ActionListener {
|
|||||||
|
|
||||||
private String statsActuelles() {
|
private String statsActuelles() {
|
||||||
if (idCompte > 0) {
|
if (idCompte > 0) {
|
||||||
return db.getStatsParCompte(idCompte);
|
return db.getStatsParCompte(idCompte) + "\n\n" + db.getStatsCampagneParCompte(idCompte);
|
||||||
}
|
}
|
||||||
return "Nombre de morts : " + mortsSansCompte
|
return "💀 Nombre de morts: " + mortsSansCompte
|
||||||
+ "\nTemps de jeu total : " + tempsSansCompteSec + " s"
|
+ "\n⏱️ Temps total: " + tempsSansCompteSec + "s"
|
||||||
+ "\nMeilleur score : " + meilleurSansCompte;
|
+ "\n🏆 Meilleur score: " + meilleurSansCompte;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enregistrerPartie(int scoreActuel, int tempsPartieSec) {
|
private void enregistrerPartie(int scoreActuel, int tempsPartieSec) {
|
||||||
@@ -67,26 +70,173 @@ public class Jeu implements KeyListener, ActionListener {
|
|||||||
// CONSTRUCTEUR
|
// CONSTRUCTEUR
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
public Jeu(DatabaseConnection db, int idCompte, int niveau) {
|
public Jeu(DatabaseConnection db, int idCompte, int niveau) {
|
||||||
|
this(db, idCompte, niveau, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Jeu(DatabaseConnection db, int idCompte, int niveau, boolean modeCampagne) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.idCompte = idCompte;
|
this.idCompte = idCompte;
|
||||||
this._niv = niveau;
|
this._niv = niveau;
|
||||||
|
this.modeCampagne = modeCampagne;
|
||||||
labScore = new JLabel();
|
labScore = new JLabel();
|
||||||
labScore.setText("<html><h3>score : 0</h3></html>");
|
labScore.setText("<html><h3>score : 0</h3></html>");
|
||||||
|
|
||||||
labMeilleurScore = new JLabel();
|
labMeilleurScore = new JLabel();
|
||||||
|
labNiveau = new JLabel();
|
||||||
|
|
||||||
JPanel panneauScores = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 0));
|
JPanel panneauScores = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 0));
|
||||||
panneauScores.setOpaque(false);
|
panneauScores.setOpaque(false);
|
||||||
panneauScores.add(labScore);
|
panneauScores.add(labScore);
|
||||||
panneauScores.add(labMeilleurScore);
|
panneauScores.add(labMeilleurScore);
|
||||||
|
panneauScores.add(labNiveau);
|
||||||
ecran.add(panneauScores, BorderLayout.NORTH);
|
ecran.add(panneauScores, BorderLayout.NORTH);
|
||||||
rafraichirMeilleurScore();
|
rafraichirMeilleurScore();
|
||||||
|
rafraichirNiveau();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rafraichirMeilleurScore() {
|
private void rafraichirMeilleurScore() {
|
||||||
labMeilleurScore.setText("<html><h3>meilleur : " + meilleurActuel() + "</h3></html>");
|
labMeilleurScore.setText("<html><h3>meilleur : " + meilleurActuel() + "</h3></html>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void rafraichirNiveau() {
|
||||||
|
labNiveau.setText("<html><h3>niveau : " + _niv + "</h3></html>");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rafraichirTitreFenetre() {
|
||||||
|
if (fenetre == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String titre = modeCampagne ? "Linea Game [CAMPAGNE]" : "Linea Game";
|
||||||
|
fenetre.setTitle(titre + (immortel ? " [MODE IMMORTEL 🛡️]" : ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String categorieNiveau(int niveau) {
|
||||||
|
if (niveau <= 2) return "Facile";
|
||||||
|
if (niveau <= 4) return "Moyen";
|
||||||
|
if (niveau <= 6) return "Difficile";
|
||||||
|
if (niveau <= 8) return "Tres Difficile";
|
||||||
|
if (niveau <= 10) return "Expert";
|
||||||
|
if (niveau <= 12) return "Cauchemar";
|
||||||
|
if (niveau <= 14) return "Chaos";
|
||||||
|
if (niveau <= 16) return "Infernal";
|
||||||
|
if (niveau <= 18) return "Apocalypse";
|
||||||
|
if (niveau <= 20) return "Extreme";
|
||||||
|
if (niveau <= 30) return "Infini";
|
||||||
|
if (niveau <= 50) return "Au-dela";
|
||||||
|
return "Cosmos";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appliquerThemeNiveau() {
|
||||||
|
String categorie = categorieNiveau(_niv);
|
||||||
|
Color fond;
|
||||||
|
Color couleurLigne;
|
||||||
|
Color couleurAvant;
|
||||||
|
Color couleurArriere;
|
||||||
|
Color couleurTexte;
|
||||||
|
|
||||||
|
switch (categorie) {
|
||||||
|
case "Facile":
|
||||||
|
fond = new Color(225, 245, 225);
|
||||||
|
couleurLigne = new Color(45, 120, 45);
|
||||||
|
couleurAvant = new Color(55, 185, 80);
|
||||||
|
couleurArriere = new Color(175, 70, 70);
|
||||||
|
couleurTexte = new Color(20, 50, 20);
|
||||||
|
break;
|
||||||
|
case "Moyen":
|
||||||
|
fond = new Color(215, 235, 250);
|
||||||
|
couleurLigne = new Color(40, 95, 150);
|
||||||
|
couleurAvant = new Color(50, 165, 120);
|
||||||
|
couleurArriere = new Color(185, 80, 85);
|
||||||
|
couleurTexte = new Color(20, 45, 80);
|
||||||
|
break;
|
||||||
|
case "Difficile":
|
||||||
|
fond = new Color(250, 235, 200);
|
||||||
|
couleurLigne = new Color(155, 95, 40);
|
||||||
|
couleurAvant = new Color(195, 145, 55);
|
||||||
|
couleurArriere = new Color(175, 70, 40);
|
||||||
|
couleurTexte = new Color(85, 55, 20);
|
||||||
|
break;
|
||||||
|
case "Tres Difficile":
|
||||||
|
fond = new Color(245, 215, 195);
|
||||||
|
couleurLigne = new Color(145, 70, 40);
|
||||||
|
couleurAvant = new Color(185, 110, 65);
|
||||||
|
couleurArriere = new Color(175, 55, 45);
|
||||||
|
couleurTexte = new Color(80, 35, 25);
|
||||||
|
break;
|
||||||
|
case "Expert":
|
||||||
|
fond = new Color(210, 190, 235);
|
||||||
|
couleurLigne = new Color(105, 55, 160);
|
||||||
|
couleurAvant = new Color(130, 85, 200);
|
||||||
|
couleurArriere = new Color(170, 60, 95);
|
||||||
|
couleurTexte = new Color(45, 20, 70);
|
||||||
|
break;
|
||||||
|
case "Cauchemar":
|
||||||
|
fond = new Color(175, 160, 210);
|
||||||
|
couleurLigne = new Color(85, 65, 150);
|
||||||
|
couleurAvant = new Color(120, 90, 190);
|
||||||
|
couleurArriere = new Color(155, 55, 110);
|
||||||
|
couleurTexte = new Color(245, 245, 245);
|
||||||
|
break;
|
||||||
|
case "Chaos":
|
||||||
|
fond = new Color(205, 120, 120);
|
||||||
|
couleurLigne = new Color(170, 40, 45);
|
||||||
|
couleurAvant = new Color(225, 115, 40);
|
||||||
|
couleurArriere = new Color(200, 30, 60);
|
||||||
|
couleurTexte = new Color(245, 245, 245);
|
||||||
|
break;
|
||||||
|
case "Infernal":
|
||||||
|
fond = new Color(165, 70, 55);
|
||||||
|
couleurLigne = new Color(190, 35, 25);
|
||||||
|
couleurAvant = new Color(235, 95, 25);
|
||||||
|
couleurArriere = new Color(210, 25, 20);
|
||||||
|
couleurTexte = new Color(245, 245, 245);
|
||||||
|
break;
|
||||||
|
case "Apocalypse":
|
||||||
|
fond = new Color(120, 40, 45);
|
||||||
|
couleurLigne = new Color(210, 30, 40);
|
||||||
|
couleurAvant = new Color(245, 95, 35);
|
||||||
|
couleurArriere = new Color(225, 20, 35);
|
||||||
|
couleurTexte = new Color(245, 245, 245);
|
||||||
|
break;
|
||||||
|
case "Extreme":
|
||||||
|
fond = new Color(70, 70, 70);
|
||||||
|
couleurLigne = new Color(225, 225, 225);
|
||||||
|
couleurAvant = new Color(255, 235, 70);
|
||||||
|
couleurArriere = new Color(240, 80, 80);
|
||||||
|
couleurTexte = new Color(245, 245, 245);
|
||||||
|
break;
|
||||||
|
case "Infini":
|
||||||
|
fond = new Color(35, 55, 85);
|
||||||
|
couleurLigne = new Color(95, 170, 255);
|
||||||
|
couleurAvant = new Color(70, 220, 255);
|
||||||
|
couleurArriere = new Color(180, 80, 255);
|
||||||
|
couleurTexte = new Color(245, 245, 245);
|
||||||
|
break;
|
||||||
|
case "Au-dela":
|
||||||
|
fond = new Color(20, 30, 70);
|
||||||
|
couleurLigne = new Color(120, 155, 255);
|
||||||
|
couleurAvant = new Color(80, 205, 255);
|
||||||
|
couleurArriere = new Color(205, 95, 255);
|
||||||
|
couleurTexte = new Color(245, 245, 245);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fond = new Color(10, 15, 45);
|
||||||
|
couleurLigne = new Color(140, 120, 255);
|
||||||
|
couleurAvant = new Color(120, 225, 255);
|
||||||
|
couleurArriere = new Color(235, 95, 255);
|
||||||
|
couleurTexte = new Color(245, 245, 245);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ecran.setCouleurFond(fond);
|
||||||
|
ligne.setCouleurLigne(couleurLigne);
|
||||||
|
demiCercleAvant.setCouleur(couleurAvant);
|
||||||
|
demiCercleArriere.setCouleur(couleurArriere);
|
||||||
|
labScore.setForeground(couleurTexte);
|
||||||
|
labMeilleurScore.setForeground(couleurTexte);
|
||||||
|
labNiveau.setForeground(couleurTexte);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean choisirNouveauCompte() {
|
private boolean choisirNouveauCompte() {
|
||||||
List<String> pseudos = new ArrayList<>(db.getPseudos());
|
List<String> pseudos = new ArrayList<>(db.getPseudos());
|
||||||
pseudos.add(0, "Sans compte");
|
pseudos.add(0, "Sans compte");
|
||||||
@@ -173,7 +323,7 @@ public class Jeu implements KeyListener, ActionListener {
|
|||||||
return "🌌 Niveau " + niveau + " - Cosmos";
|
return "🌌 Niveau " + niveau + " - Cosmos";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void choisirModeImmortel() {
|
private void choisirModeImmortel() {
|
||||||
int result = JOptionPane.showConfirmDialog(
|
int result = JOptionPane.showConfirmDialog(
|
||||||
null,
|
null,
|
||||||
@@ -202,15 +352,24 @@ public class Jeu implements KeyListener, ActionListener {
|
|||||||
demiCercleAvant = new Cercle(90, -180);
|
demiCercleAvant = new Cercle(90, -180);
|
||||||
demiCercleArriere = new Cercle(90, 180);
|
demiCercleArriere = new Cercle(90, 180);
|
||||||
ligne = new Ligne(_niv);
|
ligne = new Ligne(_niv);
|
||||||
|
ecran.setNiveau(_niv);
|
||||||
|
|
||||||
// 3. Configuration visuelle
|
// 3. En mode immortel, positionner les cercles loin (la force les attirera vers la ligne)
|
||||||
demiCercleArriere.setCouleur(new Color(0.8f, 0.0f, 0.0f));
|
// En mode normal, ils restent au centre (y = 200 par défaut du constructeur)
|
||||||
demiCercleAvant.setCouleur(new Color(0.0f, 0.8f, 0.0f));
|
if (immortel) {
|
||||||
|
demiCercleAvant.y = -300;
|
||||||
|
demiCercleArriere.y = 300;
|
||||||
|
}
|
||||||
|
|
||||||
// 4. Ajout à l'écran (l'ordre définit la superposition)
|
// 4. Configuration visuelle
|
||||||
|
appliquerThemeNiveau();
|
||||||
|
|
||||||
|
// 5. Ajout à l'écran (l'ordre définit la superposition)
|
||||||
ecran.ajouterObjet(demiCercleArriere);
|
ecran.ajouterObjet(demiCercleArriere);
|
||||||
ecran.ajouterObjet(ligne);
|
ecran.ajouterObjet(ligne);
|
||||||
ecran.ajouterObjet(demiCercleAvant);
|
ecran.ajouterObjet(demiCercleAvant);
|
||||||
|
|
||||||
|
rafraichirNiveau();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void demarrer() {
|
public void demarrer() {
|
||||||
@@ -220,7 +379,8 @@ public class Jeu implements KeyListener, ActionListener {
|
|||||||
// Passer le flag immortel à l'écran
|
// Passer le flag immortel à l'écran
|
||||||
ecran.setImmortel(immortel);
|
ecran.setImmortel(immortel);
|
||||||
|
|
||||||
JFrame fenetre = new JFrame("Linea Game" + (immortel ? " [MODE IMMORTEL 🛡️]" : ""));
|
fenetre = new JFrame();
|
||||||
|
rafraichirTitreFenetre();
|
||||||
|
|
||||||
// Initialise les objets une première fois
|
// Initialise les objets une première fois
|
||||||
initialiserPartie();
|
initialiserPartie();
|
||||||
@@ -243,12 +403,10 @@ public class Jeu implements KeyListener, ActionListener {
|
|||||||
// Réinitialisation des variables de jeu
|
// Réinitialisation des variables de jeu
|
||||||
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
|
// Passer le flag immortel à l'écran
|
||||||
ecran.setImmortel(immortel);
|
ecran.setImmortel(immortel);
|
||||||
|
rafraichirTitreFenetre();
|
||||||
|
|
||||||
// Ré-initialisation des objets graphiques
|
// Ré-initialisation des objets graphiques
|
||||||
initialiserPartie();
|
initialiserPartie();
|
||||||
@@ -271,6 +429,7 @@ public class Jeu implements KeyListener, ActionListener {
|
|||||||
int bonus = ecran.getBonusRecupere();
|
int bonus = ecran.getBonusRecupere();
|
||||||
if (bonus != 0) {
|
if (bonus != 0) {
|
||||||
ecran.reinitialiserBonus();
|
ecran.reinitialiserBonus();
|
||||||
|
int niveauActuel = _niv;
|
||||||
int nouveauNiveau = _niv + bonus;
|
int nouveauNiveau = _niv + bonus;
|
||||||
|
|
||||||
// Limiter le niveau entre 1 et 100
|
// Limiter le niveau entre 1 et 100
|
||||||
@@ -279,6 +438,10 @@ public class Jeu implements KeyListener, ActionListener {
|
|||||||
} else if (nouveauNiveau > 100) {
|
} else if (nouveauNiveau > 100) {
|
||||||
nouveauNiveau = 100;
|
nouveauNiveau = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (modeCampagne && idCompte > 0 && bonus > 0) {
|
||||||
|
db.debloquerNiveauCampagne(idCompte, niveauActuel);
|
||||||
|
}
|
||||||
|
|
||||||
_niv = nouveauNiveau;
|
_niv = nouveauNiveau;
|
||||||
resetLevel();
|
resetLevel();
|
||||||
@@ -295,18 +458,46 @@ public class Jeu implements KeyListener, ActionListener {
|
|||||||
rafraichirMeilleurScore();
|
rafraichirMeilleurScore();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
Object[] options = {"Relancer", "Changer de compte", "Changer de niveau", "Voir stats", "Quitter"};
|
Object[] options = modeCampagne
|
||||||
|
? new Object[]{"▶️ Relancer", "📊 Statistiques", "❌ Quitter"}
|
||||||
|
: new Object[]{"▶️ Relancer", "👤 Compte", "📈 Niveau", "📊 Statistiques", "❌ Quitter"};
|
||||||
|
String message = "🏁 GAME OVER\n\n"
|
||||||
|
+ "Score: " + scoreActuel + "\n"
|
||||||
|
+ "Meilleur: " + meilleurActuel() + "\n"
|
||||||
|
+ "Durée: " + tempsPartieSec + "s";
|
||||||
|
|
||||||
int choix = JOptionPane.showOptionDialog(null,
|
int choix = JOptionPane.showOptionDialog(null,
|
||||||
"Perdu\nScore : " + scoreActuel + "\nMeilleur : " + meilleurActuel(),
|
message,
|
||||||
"Game Over",
|
"🏁 Fin de Partie",
|
||||||
JOptionPane.DEFAULT_OPTION,
|
JOptionPane.DEFAULT_OPTION,
|
||||||
JOptionPane.INFORMATION_MESSAGE,
|
JOptionPane.PLAIN_MESSAGE,
|
||||||
null, options, options[0]);
|
null, options, options[0]);
|
||||||
|
|
||||||
if (choix == 0) {
|
if (choix == 0) {
|
||||||
|
int modeRelance = JOptionPane.showConfirmDialog(
|
||||||
|
null,
|
||||||
|
"Relancer en mode immortel ?",
|
||||||
|
"Relancer",
|
||||||
|
JOptionPane.YES_NO_CANCEL_OPTION,
|
||||||
|
JOptionPane.QUESTION_MESSAGE
|
||||||
|
);
|
||||||
|
|
||||||
|
if (modeRelance == JOptionPane.CANCEL_OPTION || modeRelance == JOptionPane.CLOSED_OPTION) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
immortel = (modeRelance == JOptionPane.YES_OPTION);
|
||||||
|
ecran.setImmortel(immortel);
|
||||||
resetLevel();
|
resetLevel();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (modeCampagne) {
|
||||||
|
if (choix == 1) {
|
||||||
|
JOptionPane.showMessageDialog(null, statsActuelles(), "📊 Statistiques", JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
if (choix == 1) {
|
if (choix == 1) {
|
||||||
if (choisirNouveauCompte()) {
|
if (choisirNouveauCompte()) {
|
||||||
resetLevel();
|
resetLevel();
|
||||||
@@ -324,7 +515,7 @@ public class Jeu implements KeyListener, ActionListener {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (choix == 3) {
|
if (choix == 3) {
|
||||||
JOptionPane.showMessageDialog(null, statsActuelles(), "Statistiques", JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.showMessageDialog(null, statsActuelles(), "📊 Statistiques", JOptionPane.INFORMATION_MESSAGE);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ public class Ligne extends ObjetGraphique{
|
|||||||
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)
|
||||||
private double vitesse = 5.0;
|
private double vitesse = 4.8;
|
||||||
// croissance initiale (fractionnelle) appliquée chaque frame
|
// croissance initiale (fractionnelle) appliquée chaque frame
|
||||||
private double croissance = 0.001; // ~0.1% initial
|
private double croissance = 0.0008; // montée plus progressive
|
||||||
// facteur qui amplifie la croissance elle-même (pour accélérer la montée)
|
// facteur qui amplifie la croissance elle-même (pour accélérer la montée)
|
||||||
private double facteurCroissance = 1.00003; // croissance augmente légèrement
|
private double facteurCroissance = 1.00002; // accélération plus douce
|
||||||
|
|
||||||
private int niveau = 1; // niveau de difficulté, à augmenter pour rendre le jeu plus difficile
|
private int niveau = 1; // niveau de difficulté, à augmenter pour rendre le jeu plus difficile
|
||||||
|
|
||||||
@@ -95,50 +95,63 @@ public class Ligne extends ObjetGraphique{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// appliquer la croissance (vitesse *= 1 + croissance)
|
// appliquer la croissance (vitesse *= 1 + croissance)
|
||||||
vitesse *= (1.0 + croissance + (niveau * 0.00001)); // augmenter la croissance avec le niveau
|
vitesse *= (1.0 + croissance + (niveau * 0.000006)); // hausse niveau plus progressive
|
||||||
// augmenter légèrement la croissance pour que l'accélération s'amplifie
|
// augmenter légèrement la croissance pour que l'accélération s'amplifie
|
||||||
croissance *= facteurCroissance;
|
croissance *= facteurCroissance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Indique si l'axe horizontal du cercle (cx) se trouve au niveau
|
// Trouve le segment couvrant l'abscisse cx (une seule itération)
|
||||||
// d'un des segments de la ligne -> le cercle est "sur la ligne"
|
private Segment trouverSegmentAuX(double cx) {
|
||||||
public boolean estSurLaLigne(double cx) {
|
|
||||||
for (Segment seg : segments) {
|
for (Segment seg : segments) {
|
||||||
double x1 = seg.x;
|
double x1 = seg.x;
|
||||||
double x2 = seg.x + seg.xLong;
|
double x2 = seg.x + seg.xLong;
|
||||||
if ((cx >= Math.min(x1, x2)) && (cx <= Math.max(x1, x2))) {
|
if (cx >= Math.min(x1, x2) && cx <= Math.max(x1, x2)) {
|
||||||
return true;
|
return seg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Résultat de contact : null = pas sur la ligne, sinon double[]{ligneY, distance}
|
||||||
|
public double[] contactInfo(double cx, double cy, double rayon) {
|
||||||
|
Segment seg = trouverSegmentAuX(cx);
|
||||||
|
if (seg == null) return null;
|
||||||
|
double ligneY = (seg.xLong != 0) ? seg.y + ((cx - seg.x) / seg.xLong) * seg.yLong : seg.y;
|
||||||
|
double dist = pointSegmentDistance(cx, cy, seg.x, seg.y, seg.x + seg.xLong, seg.y + seg.yLong);
|
||||||
|
return new double[]{ligneY, dist};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
return trouverSegmentAuX(cx) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vérifie la collision entre la ligne (segments) et un cercle
|
// Vérifie la collision entre la ligne (segments) et un cercle
|
||||||
public boolean collisionAvec(Cercle c) {
|
public boolean collisionAvec(Cercle c) {
|
||||||
double cx = c.getX();
|
double[] info = contactInfo(c.getX(), c.getY(), c.getRayon());
|
||||||
double cy = c.getY();
|
return info != null && info[1] <= c.getRayon();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Retourne la coordonnée Y de la ligne à l'abscisse cx
|
||||||
|
public double getYAuX(double cx) {
|
||||||
|
Segment seg = trouverSegmentAuX(cx);
|
||||||
|
if (seg == null || seg.xLong == 0) return 300;
|
||||||
|
return seg.y + ((cx - seg.x) / seg.xLong) * seg.yLong;
|
||||||
|
}
|
||||||
|
|
||||||
// Obtenir la vitesse actuelle de la ligne (pour les boules bonus)
|
// Obtenir la vitesse actuelle de la ligne (pour les boules bonus)
|
||||||
public double getVitesse() {
|
public double getVitesse() {
|
||||||
return vitesse;
|
return vitesse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCouleurLigne(Color couleur) {
|
||||||
|
for (Segment seg : segments) {
|
||||||
|
seg.setCouleur(couleur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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;
|
||||||
|
|||||||
@@ -1,13 +1,29 @@
|
|||||||
package linea;
|
package linea;
|
||||||
|
|
||||||
|
import java.awt.GridLayout;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import javax.swing.ButtonGroup;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JRadioButton;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
public class LineaAppli {
|
public class LineaAppli {
|
||||||
|
|
||||||
|
private static class SelectionJeu {
|
||||||
|
final int idCompte;
|
||||||
|
final boolean modeCampagne;
|
||||||
|
|
||||||
|
SelectionJeu(int idCompte, boolean modeCampagne) {
|
||||||
|
this.idCompte = idCompte;
|
||||||
|
this.modeCampagne = modeCampagne;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static String choisirPseudo(DatabaseConnection db, String message, int messageType) {
|
private static String choisirPseudo(DatabaseConnection db, String message, int messageType) {
|
||||||
List<String> pseudos = db.getPseudos();
|
List<String> pseudos = db.getPseudos();
|
||||||
if (pseudos.isEmpty()) {
|
if (pseudos.isEmpty()) {
|
||||||
@@ -50,7 +66,38 @@ public class LineaAppli {
|
|||||||
if (result == JOptionPane.OK_OPTION) {
|
if (result == JOptionPane.OK_OPTION) {
|
||||||
return list.getSelectedIndex() + 1;
|
return list.getSelectedIndex() + 1;
|
||||||
}
|
}
|
||||||
return 1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int choisirNiveauCampagne(DatabaseConnection db, int idCompte) {
|
||||||
|
int niveauMaxDebloque = db.getNiveauDebloqueCampagne(idCompte);
|
||||||
|
if (niveauMaxDebloque < 1) {
|
||||||
|
niveauMaxDebloque = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] niveaux = new String[niveauMaxDebloque];
|
||||||
|
for (int i = 1; i <= niveauMaxDebloque; i++) {
|
||||||
|
niveaux[i - 1] = genererLabelNiveau(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
JList<String> list = new JList<>(niveaux);
|
||||||
|
list.setSelectedIndex(niveauMaxDebloque - 1);
|
||||||
|
list.setVisibleRowCount(15);
|
||||||
|
JScrollPane scrollPane = new JScrollPane(list);
|
||||||
|
scrollPane.setPreferredSize(new java.awt.Dimension(350, 350));
|
||||||
|
|
||||||
|
int result = JOptionPane.showConfirmDialog(
|
||||||
|
null,
|
||||||
|
scrollPane,
|
||||||
|
"🏆 Campagne - Niveaux débloqués (1 à " + niveauMaxDebloque + ")",
|
||||||
|
JOptionPane.OK_CANCEL_OPTION,
|
||||||
|
JOptionPane.QUESTION_MESSAGE
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result == JOptionPane.OK_OPTION) {
|
||||||
|
return list.getSelectedIndex() + 1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String genererLabelNiveau(int niveau) {
|
private static String genererLabelNiveau(int niveau) {
|
||||||
@@ -129,6 +176,63 @@ public class LineaAppli {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static SelectionJeu choisirCompteEtModeRapide(DatabaseConnection db) {
|
||||||
|
while (true) {
|
||||||
|
List<String> pseudos = db.getPseudos();
|
||||||
|
|
||||||
|
JPanel panel = new JPanel(new GridLayout(0, 1, 8, 8));
|
||||||
|
panel.add(new JLabel("Compte :"));
|
||||||
|
|
||||||
|
String[] optionsCompte = new String[pseudos.size() + 2];
|
||||||
|
optionsCompte[0] = "Sans compte";
|
||||||
|
for (int i = 0; i < pseudos.size(); i++) {
|
||||||
|
optionsCompte[i + 1] = pseudos.get(i);
|
||||||
|
}
|
||||||
|
optionsCompte[optionsCompte.length - 1] = "Gérer les comptes...";
|
||||||
|
|
||||||
|
JComboBox<String> comboCompte = new JComboBox<>(optionsCompte);
|
||||||
|
panel.add(comboCompte);
|
||||||
|
|
||||||
|
panel.add(new JLabel("Mode :"));
|
||||||
|
JRadioButton modeClassique = new JRadioButton("Classique", true);
|
||||||
|
JRadioButton modeCampagne = new JRadioButton("Campagne");
|
||||||
|
ButtonGroup group = new ButtonGroup();
|
||||||
|
group.add(modeClassique);
|
||||||
|
group.add(modeCampagne);
|
||||||
|
|
||||||
|
JPanel panelMode = new JPanel(new GridLayout(1, 2, 8, 0));
|
||||||
|
panelMode.add(modeClassique);
|
||||||
|
panelMode.add(modeCampagne);
|
||||||
|
panel.add(panelMode);
|
||||||
|
|
||||||
|
int result = JOptionPane.showConfirmDialog(
|
||||||
|
null,
|
||||||
|
panel,
|
||||||
|
"Jouer rapidement",
|
||||||
|
JOptionPane.OK_CANCEL_OPTION,
|
||||||
|
JOptionPane.QUESTION_MESSAGE
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result != JOptionPane.OK_OPTION) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String choixCompte = (String) comboCompte.getSelectedItem();
|
||||||
|
if (choixCompte == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("Gérer les comptes...".equals(choixCompte)) {
|
||||||
|
menuComptes(db);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int idCompte = "Sans compte".equals(choixCompte) ? -1 : db.getIdParPseudo(choixCompte);
|
||||||
|
boolean campagne = modeCampagne.isSelected();
|
||||||
|
return new SelectionJeu(idCompte, campagne);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Classe de base de l'application, rien à modifier ici
|
// Classe de base de l'application, rien à modifier ici
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
@@ -140,31 +244,37 @@ public class LineaAppli {
|
|||||||
db.createTables();
|
db.createTables();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
Object[] options = {"Comptes", "Sans compte", "Quitter"};
|
SelectionJeu selection = choisirCompteEtModeRapide(db);
|
||||||
int choix = JOptionPane.showOptionDialog(null,
|
if (selection == null) {
|
||||||
"Choisissez une action :",
|
|
||||||
"Menu", JOptionPane.DEFAULT_OPTION,
|
|
||||||
JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
|
|
||||||
|
|
||||||
if (choix == JOptionPane.CLOSED_OPTION || choix == 2) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (choix) {
|
if (!selection.modeCampagne) {
|
||||||
case 1 -> {
|
int niveau = choisirNiveau();
|
||||||
int niveau = choisirNiveau();
|
if (niveau > 0) {
|
||||||
new Jeu(db, -1, niveau).demarrer();
|
new Jeu(db, selection.idCompte, niveau).demarrer();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 0 -> {
|
continue;
|
||||||
Integer idCompte = menuComptes(db);
|
|
||||||
if (idCompte != null) {
|
|
||||||
int niveau = choisirNiveau();
|
|
||||||
new Jeu(db, idCompte, niveau).demarrer();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selection.idCompte > 0) {
|
||||||
|
int niveau = choisirNiveauCampagne(db, selection.idCompte);
|
||||||
|
if (niveau > 0) {
|
||||||
|
new Jeu(db, selection.idCompte, niveau, true).demarrer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
JOptionPane.showMessageDialog(
|
||||||
|
null,
|
||||||
|
"Campagne sans compte : progression non sauvegardée.",
|
||||||
|
"Campagne",
|
||||||
|
JOptionPane.INFORMATION_MESSAGE
|
||||||
|
);
|
||||||
|
new Jeu(db, -1, 1, true).demarrer();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,10 @@ public class ZoneDessin extends JPanel {
|
|||||||
private ArrayList<BouleBonus> boolesBonus = new ArrayList<BouleBonus>();
|
private ArrayList<BouleBonus> boolesBonus = new ArrayList<BouleBonus>();
|
||||||
// compteur pour générer les boules à intervalle régulier
|
// compteur pour générer les boules à intervalle régulier
|
||||||
private int compteurBoule = 0;
|
private int compteurBoule = 0;
|
||||||
private int intervalleBoule = 80; // générer une boule tous les 80 frames
|
private int intervalleBouleBase = 165; // moins de boules sur la durée
|
||||||
|
private int delaiInitialBoule = 97; // apparition initiale avancée de 3%
|
||||||
|
private int niveauActuel = 1;
|
||||||
|
private Double dernierJoueurY = null;
|
||||||
// type de bonus récupéré (-1 = rouge, 1 = vert, 0 = aucun)
|
// type de bonus récupéré (-1 = rouge, 1 = vert, 0 = aucun)
|
||||||
private int bonusRecupere = 0;
|
private int bonusRecupere = 0;
|
||||||
|
|
||||||
@@ -38,10 +41,24 @@ public class ZoneDessin extends JPanel {
|
|||||||
setPreferredSize(new Dimension(800, 600));
|
setPreferredSize(new Dimension(800, 600));
|
||||||
setBackground(new Color(220,170,0));
|
setBackground(new Color(220,170,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCouleurFond(Color couleurFond) {
|
||||||
|
setBackground(couleurFond);
|
||||||
|
}
|
||||||
|
|
||||||
public void setImmortel(boolean immortel) {
|
public void setImmortel(boolean immortel) {
|
||||||
this.immortel = immortel;
|
this.immortel = immortel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setNiveau(int niveau) {
|
||||||
|
if (niveau < 1) {
|
||||||
|
niveauActuel = 1;
|
||||||
|
} else if (niveau > 100) {
|
||||||
|
niveauActuel = 100;
|
||||||
|
} else {
|
||||||
|
niveauActuel = niveau;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int getBonusRecupere() {
|
public int getBonusRecupere() {
|
||||||
return bonusRecupere;
|
return bonusRecupere;
|
||||||
@@ -68,6 +85,20 @@ public class ZoneDessin extends JPanel {
|
|||||||
if (estArrete==true) {
|
if (estArrete==true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cercle cercleReference = null;
|
||||||
|
for (ObjetGraphique obj : listeObjets) {
|
||||||
|
if (obj instanceof Cercle) {
|
||||||
|
cercleReference = (Cercle) obj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double joueurY = (cercleReference != null) ? cercleReference.getY() : 300;
|
||||||
|
double vitesseJoueurY = 0.0;
|
||||||
|
if (dernierJoueurY != null) {
|
||||||
|
vitesseJoueurY = joueurY - dernierJoueurY;
|
||||||
|
}
|
||||||
|
dernierJoueurY = joueurY;
|
||||||
|
|
||||||
// --- 0. Récupérer la ligne pour synchroniser les boules ---
|
// --- 0. Récupérer la ligne pour synchroniser les boules ---
|
||||||
Ligne ligneObjet = null;
|
Ligne ligneObjet = null;
|
||||||
@@ -79,67 +110,107 @@ public class ZoneDessin extends JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- 1. Générer une boule au bord droit sur la ligne ---
|
// --- 1. Générer une boule au bord droit sur la ligne ---
|
||||||
|
double progression = Math.min(1.0, (niveauActuel - 1) / 25.0);
|
||||||
|
int intervalleBoule = (int) Math.round(intervalleBouleBase - progression * 20.0); // ~165 -> 145
|
||||||
|
double probaVerteBase = 0.35 - progression * 0.06; // ~35% -> 29%
|
||||||
|
double variationAleatoire = (Math.random() - 0.5) * 0.10; // +/- 5%
|
||||||
|
double probaVerte = Math.max(0.22, Math.min(0.45, probaVerteBase + variationAleatoire));
|
||||||
|
|
||||||
compteurBoule++;
|
compteurBoule++;
|
||||||
if (compteurBoule >= intervalleBoule && ligneObjet != null) {
|
if (compteurBoule >= intervalleBoule && ligneObjet != null) {
|
||||||
compteurBoule = 0;
|
compteurBoule = 0;
|
||||||
boolean estVerte = Math.random() < 0.7;
|
boolean estVerte = Math.random() < probaVerte;
|
||||||
|
|
||||||
// On récupère le Y du dernier segment de la ligne (bord droit de l'écran)
|
double spawnX = 800;
|
||||||
// Note: Si votre classe Ligne n'a pas de méthode pour avoir le Y à X=800,
|
double spawnY;
|
||||||
// utilisez une valeur proche de la fin de votre liste de segments.
|
if (estVerte) {
|
||||||
double spawnX = 800;
|
// Vertes: proches de la trajectoire du joueur pour être récupérables.
|
||||||
double spawnY = 300; // Valeur par défaut
|
double margeVerte = 95.0 + progression * 45.0;
|
||||||
|
spawnY = joueurY + (Math.random() * (2.0 * margeVerte)) - margeVerte;
|
||||||
|
} else {
|
||||||
|
// Rouges: visent davantage le joueur, mais démarrent avec une marge d'esquive.
|
||||||
|
double offset = 220 + progression * 20.0 + Math.random() * 150.0;
|
||||||
|
spawnY = joueurY + (Math.random() < 0.5 ? -offset : offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spawnY < 20) spawnY = 20;
|
||||||
|
if (spawnY > 580) spawnY = 580;
|
||||||
|
|
||||||
|
if (!estVerte) {
|
||||||
|
// Marge suffisante pour esquiver, sans rendre les rouges inoffensives.
|
||||||
|
double distanceMin = 125.0;
|
||||||
|
if (Math.abs(spawnY - joueurY) < distanceMin) {
|
||||||
|
if (spawnY >= joueurY) {
|
||||||
|
spawnY = Math.min(580, joueurY + distanceMin);
|
||||||
|
} else {
|
||||||
|
spawnY = Math.max(20, joueurY - distanceMin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// On crée la boule au bord droit (800)
|
// On crée la boule au bord droit (800)
|
||||||
BouleBonus boule = new BouleBonus(spawnX, spawnY, estVerte);
|
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);
|
boolesBonus.add(boule);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 2. Animation des objets ---
|
// --- 2. Animation des objets ---
|
||||||
for (ObjetGraphique obj : listeObjets) obj.Animer();
|
for (ObjetGraphique obj : listeObjets) obj.Animer();
|
||||||
|
|
||||||
// Mettre à jour la vitesse des boules (car la ligne accélère avec le temps)
|
// Mettre à jour et animer les boules (une seule fois par frame)
|
||||||
if (ligneObjet != null) {
|
if (ligneObjet != null) {
|
||||||
for (BouleBonus boule : boolesBonus) {
|
for (BouleBonus boule : boolesBonus) {
|
||||||
boule.setVitesse(ligneObjet.getVitesse());
|
boule.animerAvecCible(ligneObjet.getVitesse(), joueurY, vitesseJoueurY);
|
||||||
boule.Animer();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Les boules bougent via leur propre Animer() qui ajuste leur vitesse
|
// 2. vérifier collision entre la Ligne et le Cercle (une seule passe de segments)
|
||||||
|
if (ligneObjet != null && cercleReference != null) {
|
||||||
for (BouleBonus boule : boolesBonus) {
|
double[] info = ligneObjet.contactInfo(
|
||||||
boule.Animer();
|
cercleReference.getX(), cercleReference.getY(), cercleReference.getRayon());
|
||||||
}
|
|
||||||
|
boolean enContact = (info != null) && (info[1] <= cercleReference.getRayon());
|
||||||
// 2. vérifier collisions entre une Ligne et un Cercle
|
double ligneY = (info != null) ? info[0] : ligneObjet.getYAuX(cercleReference.getX());
|
||||||
for (ObjetGraphique obj : listeObjets) {
|
|
||||||
if (obj instanceof Ligne) {
|
// Phase initiale en mode immortel : force d'attraction depuis le début
|
||||||
Ligne l = (Ligne) obj;
|
if (!hadBeenOnLine && immortel) {
|
||||||
for (ObjetGraphique other : listeObjets) {
|
double delta = ligneY - cercleReference.y;
|
||||||
if (other instanceof Cercle) {
|
cercleReference.vitesse += delta * 0.12;
|
||||||
Cercle c = (Cercle) other;
|
|
||||||
// On commence à surveiller une fois que le centre du
|
// Marquer le premier contact
|
||||||
// cercle est au-dessus d'un segment (le cercle est "sur la ligne").
|
if (enContact) {
|
||||||
if (l.estSurLaLigne(c.getX())) {
|
hadBeenOnLine = true;
|
||||||
hadBeenOnLine = true;
|
}
|
||||||
// Si le cercle n'est plus en contact (distance > rayon)
|
} else if (hadBeenOnLine && immortel) {
|
||||||
// alors le joueur perd (il doit maintenir le contact).
|
// Phase maintenance : après le premier contact, maintenir le cercle sur la ligne
|
||||||
if (!l.collisionAvec(c)) {
|
double rayon = cercleReference.getRayon();
|
||||||
// Ignorer la collision si on est en mode immortel
|
double limite = ligneY - rayon;
|
||||||
if (!immortel) {
|
double limiteBas = ligneY + rayon;
|
||||||
collisionOccur = true;
|
|
||||||
estArrete = true;
|
// Clamping : empêcher le cercle de sortir au-dessus
|
||||||
break;
|
if (cercleReference.y < limite) {
|
||||||
}
|
cercleReference.y = limite;
|
||||||
}
|
if (cercleReference.vitesse < 0) cercleReference.vitesse *= -0.3;
|
||||||
}
|
}
|
||||||
|
// Clamping : empêcher le cercle de sortir en-dessous
|
||||||
|
else if (cercleReference.y > limiteBas) {
|
||||||
|
cercleReference.y = limiteBas;
|
||||||
|
if (cercleReference.vitesse > 0) cercleReference.vitesse *= -0.3;
|
||||||
|
}
|
||||||
|
} else if (info != null && !enContact && !immortel) {
|
||||||
|
// Mode normal : mort si hors contact
|
||||||
|
collisionOccur = true;
|
||||||
|
estArrete = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Synchroniser tous les autres Cercle en mode immortel
|
||||||
|
if (immortel) {
|
||||||
|
for (ObjetGraphique obj : listeObjets) {
|
||||||
|
if (obj instanceof Cercle && obj != cercleReference) {
|
||||||
|
Cercle autre = (Cercle) obj;
|
||||||
|
autre.y = cercleReference.y;
|
||||||
|
autre.vitesse = cercleReference.vitesse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (estArrete) break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +235,7 @@ public class ZoneDessin extends JPanel {
|
|||||||
|
|
||||||
//4. Détruire la boule si elle dépasse le joueur sans être touchée ---
|
//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".
|
// Le cercle est à X = 400. Si la boule est à X < 350, elle est "passée".
|
||||||
if (!collision && boule.getX() < 350) {
|
if (!collision && boule.getX() < 320) {
|
||||||
boolesBonus.remove(i);
|
boolesBonus.remove(i);
|
||||||
// On ne change pas bonusRecupere ici (donc rien ne se passe)
|
// On ne change pas bonusRecupere ici (donc rien ne se passe)
|
||||||
}
|
}
|
||||||
@@ -205,7 +276,8 @@ public class ZoneDessin extends JPanel {
|
|||||||
collisionOccur = false;
|
collisionOccur = false;
|
||||||
hadBeenOnLine = false;
|
hadBeenOnLine = false;
|
||||||
bonusRecupere = 0;
|
bonusRecupere = 0;
|
||||||
compteurBoule = 0;
|
compteurBoule = -delaiInitialBoule;
|
||||||
|
dernierJoueurY = null;
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user