Compare commits
35 Commits
99a1dfe5ee
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4ed39dd92a | |||
|
|
5660a6c5c6 | ||
|
|
607ee1fff4 | ||
|
|
f295a34ca5 | ||
|
|
6de8ca830e | ||
|
|
a01e27ad2c | ||
| 16787a4113 | |||
|
|
d69b806001 | ||
| 2c93a102f2 | |||
|
|
ba78c22e91 | ||
| e1e0ef5054 | |||
| eb74186d05 | |||
|
|
732d29dad6 | ||
|
|
0b82113441 | ||
| 0a4825d9ef | |||
|
|
eab0280f5e | ||
|
|
f8c74c4306 | ||
|
|
b37f6cb881 | ||
|
|
9ec6f0ebfa | ||
| b4ff63e92c | |||
|
|
dbafa23b4d | ||
|
|
7639df7abd | ||
|
|
8126007805 | ||
|
|
3dd0408323 | ||
| 2017bd1907 | |||
|
|
4e5ab18694 | ||
|
|
2b52a88132 | ||
|
|
5d1c525890 | ||
|
|
c15787681f | ||
|
|
5a58534a40 | ||
|
|
65a99a3e3e | ||
|
|
834ea28872 | ||
|
|
64062f04f2 | ||
| 76494174cd | |||
|
|
468a88196e |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -24,7 +24,7 @@ bin/
|
|||||||
# ========================
|
# ========================
|
||||||
# 3. ANTIGRAVITY / VSCODE
|
# 3. ANTIGRAVITY / VSCODE
|
||||||
# ========================
|
# ========================
|
||||||
.vscode/
|
.claude/
|
||||||
.antigravity/
|
.antigravity/
|
||||||
*.code-workspace
|
*.code-workspace
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
37
src/Bonus.java
Normal file
37
src/Bonus.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package linea;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Bonus extends ObjetCollectible {
|
||||||
|
|
||||||
|
public Bonus(Ligne l, List<Joueur> joueurs, Jeu j) {
|
||||||
|
super(l, joueurs, j);
|
||||||
|
this.taille = 10;
|
||||||
|
this.couleur = Color.GREEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override protected int getSeuilActivation() { return 220; }
|
||||||
|
|
||||||
|
@Override protected Color getCouleurCapture() { return Color.BLUE; } // couleur après avoir été ramasssé
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected double calculerY(double hauteurLigne) {
|
||||||
|
if (Math.random() > 0.5) return hauteurLigne - 10 - (Math.random() * 50); // position du bonus
|
||||||
|
else return hauteurLigne + 10 + (Math.random() * 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void appliquerEffet(Joueur joueur) {
|
||||||
|
if (!monJeu.cheatMode) joueur.ajouterVie();
|
||||||
|
} // En cheat mode, le bonus ne sert à rien (on a déjà l'invincibilité)
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void dessiner(Graphics g) {
|
||||||
|
g.fillRect((int)Math.round(x), (int)Math.round(y), (int)taille, (int)taille);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
35
src/BonusTaille.java
Normal file
35
src/BonusTaille.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package linea;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BonusTaille extends ObjetCollectible {
|
||||||
|
|
||||||
|
public BonusTaille(Ligne l, List<Joueur> joueurs, Jeu j) {
|
||||||
|
super(l, joueurs, j);
|
||||||
|
this.taille = 12;
|
||||||
|
this.couleur = Color.CYAN;
|
||||||
|
this.compteurFrames = 200; // démarre déjà à 200 pour apparaître plus tôt
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override protected int getSeuilActivation() { return 320; }
|
||||||
|
|
||||||
|
@Override protected Color getCouleurCapture() { return new Color(255, 255, 255, 100); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected double calculerY(double hauteurLigne) {
|
||||||
|
if (Math.random() > 0.5) return hauteurLigne - 8 - (Math.random() * 45); // position du bonus
|
||||||
|
else return hauteurLigne + 8 + (Math.random() * 45);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void appliquerEffet(Joueur joueur) {
|
||||||
|
joueur.activerBonusTaille();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void dessiner(Graphics g) {
|
||||||
|
g.fillOval((int)Math.round(x), (int)Math.round(y), (int)taille, (int)taille);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,8 @@ import java.awt.Graphics;
|
|||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Arc2D;
|
import java.awt.geom.Arc2D;
|
||||||
|
|
||||||
public class Cercle extends ObjetGraphique { // il s'agit plutôt d'arcs de cercle
|
// Gère l'affichage et le déplacement du demi-cercle
|
||||||
|
public class Cercle extends ObjetGraphique {
|
||||||
|
|
||||||
protected double rayon = 50;
|
protected double rayon = 50;
|
||||||
protected double depY = 0;
|
protected double depY = 0;
|
||||||
@@ -15,11 +16,13 @@ public class Cercle extends ObjetGraphique { // il s'agit plutôt d'arcs de cerc
|
|||||||
protected double fin = 360;
|
protected double fin = 360;
|
||||||
|
|
||||||
protected boolean montee = false;
|
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é
|
// pas = "delta t", permet de régler la jouabilité
|
||||||
protected double pas = 0.2;
|
protected double pas = 0.2;
|
||||||
protected double impulsion = 35;
|
protected double impulsion = 6;
|
||||||
|
protected double gravite = 1;
|
||||||
|
|
||||||
public static int xCercle = 400;
|
public static int xCercle = 400;
|
||||||
|
|
||||||
@@ -39,8 +42,10 @@ public class Cercle extends ObjetGraphique { // il s'agit plutôt d'arcs de cerc
|
|||||||
return rayon;
|
return rayon;
|
||||||
}
|
}
|
||||||
|
|
||||||
// note que "haut" a été appuyée (évite d'être tributaire de la répétition
|
public void setRayon(double r) {
|
||||||
// clavier)
|
rayon = r;
|
||||||
|
}
|
||||||
|
|
||||||
public void Monter() {
|
public void Monter() {
|
||||||
montee = true;
|
montee = true;
|
||||||
}
|
}
|
||||||
@@ -49,6 +54,14 @@ public class Cercle extends ObjetGraphique { // il s'agit plutôt d'arcs de cerc
|
|||||||
montee = false;
|
montee = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Descendre() {
|
||||||
|
descente = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ArreterDescendre() {
|
||||||
|
descente = false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void Afficher(Graphics g) {
|
void Afficher(Graphics g) {
|
||||||
Graphics2D g2D = (Graphics2D) g;
|
Graphics2D g2D = (Graphics2D) g;
|
||||||
@@ -59,36 +72,42 @@ public class Cercle extends ObjetGraphique { // il s'agit plutôt d'arcs de cerc
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
void Animer() {
|
void Animer() {
|
||||||
// chute libre
|
// gravite
|
||||||
vitesse = vitesse + 9.81 * pas;
|
vitesse += gravite * pas;
|
||||||
|
|
||||||
// impulsion vers le haut
|
// acceleration vers le haut
|
||||||
if (montee == true) {
|
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) {
|
// limiter la vitesse max
|
||||||
depY = -10;
|
if (vitesse < -10) {
|
||||||
|
vitesse = -10;
|
||||||
}
|
}
|
||||||
if (depY > 10) {
|
if (vitesse > 10) {
|
||||||
depY = 10;
|
vitesse = 10;
|
||||||
}
|
}
|
||||||
y += depY;
|
|
||||||
|
y += vitesse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recadre le cercle dans la ligne si il le dépasse
|
||||||
public void ResterDansLigne(Ligne li) {
|
public void ResterDansLigne(Ligne li) {
|
||||||
double collisionHautPos = y + rayon;
|
double collisionHautPos = y + rayon;
|
||||||
double collisionBasPos = y - rayon;
|
double collisionBasPos = y - rayon;
|
||||||
double yLigne = li.GetHauteurPointCercle();
|
double yLigne = li.GetHauteurPointCercle();
|
||||||
|
|
||||||
if (yLigne < collisionBasPos) {
|
if (yLigne < collisionBasPos) { // Dépassement par le bas
|
||||||
y = yLigne + rayon;
|
y = yLigne + rayon;
|
||||||
if (vitesse > 0)
|
if (vitesse > 0)
|
||||||
vitesse = 0;
|
vitesse = 0;
|
||||||
}
|
}
|
||||||
if (yLigne > collisionHautPos) {
|
if (yLigne > collisionHautPos) {// Dépassement par le haut
|
||||||
y = yLigne - rayon;
|
y = yLigne - rayon;
|
||||||
if (vitesse < 0)
|
if (vitesse < 0)
|
||||||
vitesse = 0;
|
vitesse = 0;
|
||||||
|
|||||||
39
src/GestionnaireFinDePartie.java
Normal file
39
src/GestionnaireFinDePartie.java
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package linea;
|
||||||
|
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
|
||||||
|
public class GestionnaireFinDePartie {
|
||||||
|
|
||||||
|
private boolean estGameOver = false;
|
||||||
|
private JLabel labGameOver;
|
||||||
|
private GestionnaireScore gestionnaireBDD;
|
||||||
|
private GestionnaireHistorique gestionnaireHistorique;
|
||||||
|
|
||||||
|
public GestionnaireFinDePartie(JLabel labGameOver, GestionnaireScore gestionnaireBDD, GestionnaireHistorique gestionnaireHistorique) {
|
||||||
|
this.labGameOver = labGameOver;
|
||||||
|
this.gestionnaireBDD = gestionnaireBDD;
|
||||||
|
this.gestionnaireHistorique = gestionnaireHistorique;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void declencherGameOver(ZoneDessin ecran, String pseudo, int score) {
|
||||||
|
estGameOver = true;
|
||||||
|
ecran.arreter(); // on fige tout, plus d'animation
|
||||||
|
labGameOver.setVisible(true);
|
||||||
|
|
||||||
|
// on enregistre dans le classement seulement si y'a un pseudo
|
||||||
|
if (pseudo != null && !pseudo.isEmpty()) {
|
||||||
|
gestionnaireBDD.sauvegarderScore(pseudo, score);
|
||||||
|
}
|
||||||
|
// score == durée en secondes (1 pt par seconde, voir Jeu.actionPerformed)
|
||||||
|
gestionnaireHistorique.sauvegarderPartie(pseudo, score, score);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean estGameOver() {
|
||||||
|
return estGameOver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reinitialiser() {
|
||||||
|
estGameOver = false;
|
||||||
|
labGameOver.setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
72
src/GestionnaireHistorique.java
Normal file
72
src/GestionnaireHistorique.java
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
package linea;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import javax.swing.table.DefaultTableModel;
|
||||||
|
|
||||||
|
public class GestionnaireHistorique {
|
||||||
|
|
||||||
|
private static final String URL = "jdbc:sqlite:linea_bdd.db";
|
||||||
|
|
||||||
|
public GestionnaireHistorique() {
|
||||||
|
try {
|
||||||
|
Class.forName("org.sqlite.JDBC");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// enregistre la partie peu importe si le joueur a mis un pseudo ou pas
|
||||||
|
public void sauvegarderPartie(String nom, int points, int duree) {
|
||||||
|
String pseudoFinal = (nom == null || nom.trim().isEmpty()) ? "Anonyme" : nom.trim();
|
||||||
|
String dateActuelle = new SimpleDateFormat("dd/MM/yyyy HH:mm").format(new Date());
|
||||||
|
String sql = "INSERT INTO historique(nom, points, date_partie, duree) VALUES(?, ?, ?, ?)";
|
||||||
|
|
||||||
|
try (Connection conn = DriverManager.getConnection(URL);
|
||||||
|
PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
|
||||||
|
pstmt.setString(1, pseudoFinal);
|
||||||
|
pstmt.setInt(2, points);
|
||||||
|
pstmt.setString(3, dateActuelle);
|
||||||
|
pstmt.setInt(4, duree);
|
||||||
|
pstmt.executeUpdate();
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.err.println("impossible de sauvegarder l historique");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DefaultTableModel getModeleTableau() {
|
||||||
|
// colonnes affichées dans la popup historique du menu
|
||||||
|
String[] nomsColonnes = { "Partie N°", "Date", "Pseudo", "Score", "Durée (s)" };
|
||||||
|
DefaultTableModel modele = new DefaultTableModel(nomsColonnes, 0);
|
||||||
|
// les plus récentes en haut
|
||||||
|
String sql = "SELECT id, date_partie, nom, points, duree FROM historique ORDER BY id DESC";
|
||||||
|
|
||||||
|
try (Connection conn = DriverManager.getConnection(URL);
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
ResultSet rs = stmt.executeQuery(sql)) {
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
|
String dateRecup = rs.getString("date_partie");
|
||||||
|
if (dateRecup == null)
|
||||||
|
dateRecup = "Inconnue";
|
||||||
|
|
||||||
|
Object[] ligne = {
|
||||||
|
rs.getInt("id"),
|
||||||
|
dateRecup,
|
||||||
|
rs.getString("nom"),
|
||||||
|
rs.getInt("points"),
|
||||||
|
rs.getInt("duree")
|
||||||
|
};
|
||||||
|
modele.addRow(ligne);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.err.println("erreur lecture historique");
|
||||||
|
}
|
||||||
|
|
||||||
|
return modele;
|
||||||
|
}
|
||||||
|
}
|
||||||
157
src/GestionnaireNiveau.java
Normal file
157
src/GestionnaireNiveau.java
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
package linea;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GestionnaireNiveau {
|
||||||
|
|
||||||
|
public static final int FRAMES_PAR_NIVEAU = 25 * 10; // 10 secondes
|
||||||
|
|
||||||
|
private final List<Niveau> niveaux = new ArrayList<>();
|
||||||
|
private int indexNiveau = 0;
|
||||||
|
private int framesDepuisDebut = 0;
|
||||||
|
private int framesDansNiveau = 0;
|
||||||
|
|
||||||
|
private static final int DUREE_FADE = 25 * 3; // 3 secondes
|
||||||
|
|
||||||
|
private static final String URL_BDD = "jdbc:sqlite:linea_bdd.db";
|
||||||
|
|
||||||
|
public GestionnaireNiveau() {
|
||||||
|
try {
|
||||||
|
//chargement driver
|
||||||
|
Class.forName("org.sqlite.JDBC");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
System.err.println("[BDD] Impossible de charger le driver SQLite.");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
chargerNiveaux();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void chargerNiveaux() {
|
||||||
|
String sql = "SELECT * FROM niveaux ORDER BY numero ASC";
|
||||||
|
|
||||||
|
try (Connection conn = DriverManager.getConnection(URL_BDD);
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
ResultSet rs = stmt.executeQuery(sql)) {
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
|
int numero = rs.getInt("numero");
|
||||||
|
int r = rs.getInt("couleur_r");
|
||||||
|
int g = rs.getInt("couleur_g");
|
||||||
|
int b = rs.getInt("couleur_b");
|
||||||
|
double vitesse = rs.getDouble("vitesse_scroll");
|
||||||
|
double freq = rs.getDouble("noise_frequence");
|
||||||
|
double rayon = rs.getDouble("rayon_cercle");
|
||||||
|
double haut = rs.getDouble("limite_haut");
|
||||||
|
double bas = rs.getDouble("limite_bas");
|
||||||
|
|
||||||
|
niveaux.add(new Niveau(numero, new Color(r, g, b), vitesse, freq, rayon, haut, bas));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.err.println("[BDD] Erreur lors du chargement des niveaux.");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (niveaux.isEmpty()) {
|
||||||
|
niveaux.add(new Niveau(1, new Color(112, 158, 251), 8, 1.0/80.0, 70, 100, 500));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean niveauVientDeChanger = false;
|
||||||
|
|
||||||
|
public void mettreAJour() {
|
||||||
|
framesDepuisDebut++;
|
||||||
|
framesDansNiveau++;
|
||||||
|
|
||||||
|
if (framesDansNiveau >= FRAMES_PAR_NIVEAU && indexNiveau < niveaux.size() - 1) {
|
||||||
|
indexNiveau++;
|
||||||
|
framesDansNiveau = 0;
|
||||||
|
niveauVientDeChanger = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean aChangeDeNiveau() {
|
||||||
|
if (niveauVientDeChanger) {
|
||||||
|
niveauVientDeChanger = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//transition smooth entre les niveau
|
||||||
|
|
||||||
|
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))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,47 +4,20 @@ import java.sql.*;
|
|||||||
|
|
||||||
public class GestionnaireScore {
|
public class GestionnaireScore {
|
||||||
|
|
||||||
private static final String URL = "jdbc:sqlite:linea_scores.db";
|
private static final String URL = "jdbc:sqlite:linea_bdd.db";
|
||||||
|
|
||||||
public GestionnaireScore() {
|
public GestionnaireScore() {
|
||||||
// 1) Charger explicitement le driver SQLite JDBC
|
|
||||||
try {
|
try {
|
||||||
|
//chargement driver SQLite
|
||||||
Class.forName("org.sqlite.JDBC");
|
Class.forName("org.sqlite.JDBC");
|
||||||
System.out.println("[BDD] Driver SQLite JDBC chargé correctement (org.sqlite.JDBC).");
|
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
System.err.println("[BDD] ERREUR : impossible de charger le driver SQLite JDBC (org.sqlite.JDBC).");
|
System.err.println("[BDD] Impossible de charger le driver SQLite.");
|
||||||
System.err.println("Vérifie que le fichier sqlite-jdbc-xxx.jar est bien présent dans le classpath.");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2) Créer / vérifier la table au démarrage
|
|
||||||
try (Connection conn = DriverManager.getConnection(URL)) {
|
|
||||||
if (conn == null) {
|
|
||||||
System.err.println("[BDD] ERREUR : connexion JDBC nulle lors de l'initialisation.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String sql = "CREATE TABLE IF NOT EXISTS scores (" +
|
|
||||||
"id INTEGER PRIMARY KEY AUTOINCREMENT," +
|
|
||||||
"nom TEXT NOT NULL," +
|
|
||||||
"points INTEGER NOT NULL" +
|
|
||||||
");";
|
|
||||||
|
|
||||||
try (Statement stmt = conn.createStatement()) {
|
|
||||||
stmt.execute(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("[BDD] Table 'scores' vérifiée/créée avec succès.");
|
|
||||||
} catch (SQLException e) {
|
|
||||||
System.err.println("[BDD] ERREUR SQL lors de la création ou vérification de la table 'scores'.");
|
|
||||||
System.err.println("Message SQL : " + e.getMessage());
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sauvegarderScore(String nom, int points) {
|
public void sauvegarderScore(String nom, int points) {
|
||||||
if (nom == null || nom.trim().isEmpty()) {
|
if (nom == null || nom.trim().isEmpty()) {
|
||||||
System.err.println("[BDD] Tentative d'enregistrer un score avec un nom vide. Opération annulée.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,15 +26,13 @@ public class GestionnaireScore {
|
|||||||
try (Connection conn = DriverManager.getConnection(URL);
|
try (Connection conn = DriverManager.getConnection(URL);
|
||||||
PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
|
||||||
|
//contre injection SQL
|
||||||
pstmt.setString(1, nom.trim());
|
pstmt.setString(1, nom.trim());
|
||||||
pstmt.setInt(2, points);
|
pstmt.setInt(2, points);
|
||||||
int lignes = pstmt.executeUpdate();
|
pstmt.executeUpdate();
|
||||||
|
|
||||||
System.out.println("[BDD] Score enregistré pour '" + nom + "' (" + points +
|
|
||||||
" points). Lignes affectées : " + lignes);
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
System.err.println("[BDD] ERREUR SQL lors de l'enregistrement du score.");
|
System.err.println("[BDD] Erreur lors de l'enregistrement du score.");
|
||||||
System.err.println("Message SQL : " + e.getMessage());
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,13 +60,9 @@ public class GestionnaireScore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
System.err.println("[BDD] ERREUR SQL lors de la lecture des scores.");
|
System.err.println("[BDD] Erreur lors de la lecture des scores.");
|
||||||
System.err.println("Message SQL : " + e.getMessage());
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
return "Erreur lors de la lecture des scores.";
|
||||||
return "Erreur lors de la lecture des scores.\n" +
|
|
||||||
"Détail : " + e.getMessage() + "\n" +
|
|
||||||
"Consulte la console pour la pile complète (stack trace).";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
|||||||
180
src/Jeu.java
180
src/Jeu.java
@@ -8,6 +8,8 @@ import java.awt.event.KeyEvent;
|
|||||||
import java.awt.event.KeyListener;
|
import java.awt.event.KeyListener;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
@@ -18,36 +20,39 @@ public class Jeu implements KeyListener, ActionListener, MouseListener {
|
|||||||
|
|
||||||
protected ZoneDessin ecran = new ZoneDessin();
|
protected ZoneDessin ecran = new ZoneDessin();
|
||||||
|
|
||||||
protected Cercle demiCercleAvant = new Cercle(90, -180); // celui qui est sur la ligne
|
protected GestionnaireNiveau gestionnaireNiveau = new GestionnaireNiveau();
|
||||||
protected Cercle demiCercleArriere = new Cercle(90, 180); // celui qui est derrière la ligne
|
protected Ligne lili = new Ligne(new NoiseGenerator(0), gestionnaireNiveau);
|
||||||
|
|
||||||
// A FAIRE : ajouter les objets graphiques manquants, s'il y en a
|
protected List<Joueur> joueurs = new ArrayList<>();
|
||||||
protected Ligne lili = new Ligne(new NoiseGenerator(0));
|
protected boolean deuxJoueurs = false;
|
||||||
|
|
||||||
protected Timer horloge;
|
protected Timer horloge;
|
||||||
|
|
||||||
protected double score = 1;
|
protected double score = 1;
|
||||||
protected JLabel labScore;
|
protected JLabel labScore;
|
||||||
protected int vies = 3;
|
|
||||||
|
|
||||||
protected GestionnaireScore gestionnaireBDD = new GestionnaireScore();
|
protected GestionnaireScore gestionnaireBDD = new GestionnaireScore();
|
||||||
|
|
||||||
|
// pour gestionnaire historique
|
||||||
|
protected GestionnaireHistorique gestionnaireHistorique = new GestionnaireHistorique();
|
||||||
|
|
||||||
|
protected GestionnaireFinDePartie gestionnaireFinDePartie;
|
||||||
|
|
||||||
protected int compteurFrames = 0;
|
protected int compteurFrames = 0;
|
||||||
protected boolean enCollision = false;
|
|
||||||
protected boolean estGameOver = false;
|
protected boolean estGameOver = false;
|
||||||
protected JLabel labGameOver;
|
protected JLabel labGameOver;
|
||||||
protected int compteurInvincible = 0;
|
|
||||||
|
|
||||||
protected String pseudo = "";
|
protected String pseudo = "";
|
||||||
protected JFrame fenetre;
|
protected JFrame fenetre;
|
||||||
protected MenuPrincipal menu;
|
protected MenuPrincipal menu;
|
||||||
|
|
||||||
|
public boolean cheatMode = false;
|
||||||
|
|
||||||
public Jeu() {
|
public Jeu() {
|
||||||
labScore = new JLabel();
|
labScore = new JLabel();
|
||||||
labScore.setForeground(Color.WHITE);
|
labScore.setForeground(Color.WHITE);
|
||||||
labScore.setText("<html><h3>" + (int) score + "</h3></html>");
|
labScore.setText("<html><h3>" + (int) score + "</h3></html>");
|
||||||
labScore.setBounds(20, 0, 200, 50);
|
labScore.setBounds(20, 0, 600, 50);
|
||||||
ecran.add(labScore);
|
ecran.add(labScore);
|
||||||
|
|
||||||
labGameOver = new JLabel("GAME OVER", SwingConstants.CENTER);
|
labGameOver = new JLabel("GAME OVER", SwingConstants.CENTER);
|
||||||
@@ -57,27 +62,37 @@ public class Jeu implements KeyListener, ActionListener, MouseListener {
|
|||||||
labGameOver.setVisible(false);
|
labGameOver.setVisible(false);
|
||||||
ecran.add(labGameOver);
|
ecran.add(labGameOver);
|
||||||
|
|
||||||
|
gestionnaireFinDePartie = new GestionnaireFinDePartie(labGameOver, gestionnaireBDD, gestionnaireHistorique);
|
||||||
|
|
||||||
ecran.addMouseListener(this);
|
ecran.addMouseListener(this);
|
||||||
ecran.traiterBoucleAnimation();
|
ecran.traiterBoucleAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Joueur creerJoueur1() {
|
||||||
|
return new Joueur(
|
||||||
|
new Color(0.0f, 0.5f, 0.0f), new Color(0.8f, 0.0f, 0.0f),
|
||||||
|
KeyEvent.VK_UP, KeyEvent.VK_DOWN
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Joueur creerJoueur2() {
|
||||||
|
return new Joueur(
|
||||||
|
new Color(0.0f, 0.3f, 0.8f), new Color(0.6f, 0.0f, 0.6f),
|
||||||
|
KeyEvent.VK_Z, KeyEvent.VK_S
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void keyPressed(KeyEvent e) {
|
public void keyPressed(KeyEvent e) {
|
||||||
int keyCode = e.getKeyCode();
|
for (Joueur joueur : joueurs) {
|
||||||
|
joueur.appliquerTouche(e.getKeyCode(), true);
|
||||||
if (keyCode == 38) { // flèche haut
|
|
||||||
demiCercleAvant.Monter();
|
|
||||||
demiCercleArriere.Monter();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void keyReleased(KeyEvent e) {
|
public void keyReleased(KeyEvent e) {
|
||||||
int keyCode = e.getKeyCode();
|
for (Joueur joueur : joueurs) {
|
||||||
|
joueur.appliquerTouche(e.getKeyCode(), false);
|
||||||
if (keyCode == 38) {
|
|
||||||
demiCercleAvant.ArreterMonter();
|
|
||||||
demiCercleArriere.ArreterMonter();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,15 +113,29 @@ public class Jeu implements KeyListener, ActionListener, MouseListener {
|
|||||||
fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void lancerPartie(String pseudoSaisi) {
|
public void lancerPartie(String pseudoSaisi, boolean modeDeuxJoueurs) {
|
||||||
pseudo = pseudoSaisi;
|
pseudo = pseudoSaisi;
|
||||||
|
deuxJoueurs = modeDeuxJoueurs;
|
||||||
|
|
||||||
|
joueurs.clear();
|
||||||
|
joueurs.add(creerJoueur1());
|
||||||
|
if (deuxJoueurs) {
|
||||||
|
joueurs.add(creerJoueur2());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Joueur joueur : joueurs) {
|
||||||
|
ecran.ajouterObjet(joueur.demiCercleArriere);
|
||||||
|
}
|
||||||
|
|
||||||
// A FAIRE : placer dans l'écran tous les objets graphiques nécessaires
|
|
||||||
ecran.ajouterObjet(demiCercleArriere);
|
|
||||||
ecran.ajouterObjet(lili);
|
ecran.ajouterObjet(lili);
|
||||||
ecran.ajouterObjet(demiCercleAvant);
|
|
||||||
demiCercleArriere.setCouleur(new Color(0.0f, 0.4f, 0.0f));
|
for (Joueur joueur : joueurs) {
|
||||||
demiCercleAvant.setCouleur(new Color(0.0f, 0.5f, 0.0f));
|
ecran.ajouterObjet(joueur.demiCercleAvant);
|
||||||
|
}
|
||||||
|
|
||||||
|
ecran.ajouterObjet(new Bonus(lili, joueurs, this));
|
||||||
|
ecran.ajouterObjet(new Malus(lili, joueurs, this));
|
||||||
|
ecran.ajouterObjet(new BonusTaille(lili, joueurs, this));
|
||||||
|
|
||||||
ecran.addKeyListener(this);
|
ecran.addKeyListener(this);
|
||||||
ecran.setFocusable(true);
|
ecran.setFocusable(true);
|
||||||
@@ -118,66 +147,81 @@ public class Jeu implements KeyListener, ActionListener, MouseListener {
|
|||||||
|
|
||||||
score = 1;
|
score = 1;
|
||||||
compteurFrames = 0;
|
compteurFrames = 0;
|
||||||
vies = 3;
|
|
||||||
enCollision = false;
|
|
||||||
estGameOver = false;
|
estGameOver = false;
|
||||||
compteurInvincible = 0;
|
gestionnaireNiveau.reinitialiser();
|
||||||
labGameOver.setVisible(false);
|
gestionnaireFinDePartie.reinitialiser();
|
||||||
|
|
||||||
|
double posY = deuxJoueurs ? 250 : 200;
|
||||||
|
for (int i = 0; i < joueurs.size(); i++) {
|
||||||
|
joueurs.get(i).reinitialiser(posY + i * 100);
|
||||||
|
}
|
||||||
|
|
||||||
ecran.demarrer();
|
ecran.demarrer();
|
||||||
|
|
||||||
if (horloge == null) {
|
if (horloge == null) {
|
||||||
|
// 40ms par frame, environ 25fps
|
||||||
horloge = new Timer(40, this);
|
horloge = new Timer(40, this);
|
||||||
}
|
}
|
||||||
horloge.start();
|
horloge.start();
|
||||||
|
|
||||||
// A FAIRE : donner la couleur des 2 demi-cercles
|
|
||||||
// demiCercleArriere.setCouleur(new Color(0.8f, 0.0f, 0.0f));
|
|
||||||
demiCercleArriere.setCouleur(new Color(0.8f, 0.0f, 0.0f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
if (estGameOver == true) {
|
if (estGameOver) return;
|
||||||
return;
|
|
||||||
|
gestionnaireNiveau.mettreAJour();
|
||||||
|
if (gestionnaireNiveau.aChangeDeNiveau()) {
|
||||||
|
for (Joueur joueur : joueurs) {
|
||||||
|
joueur.resetInvincibilite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ecran.setCouleurFond(gestionnaireNiveau.getCouleurFondInterpolee());
|
||||||
|
|
||||||
|
double rayonBase = gestionnaireNiveau.getRayonCercle();
|
||||||
|
|
||||||
|
for (Joueur joueur : joueurs) {
|
||||||
|
joueur.mettreAJourRayon(rayonBase);
|
||||||
|
joueur.mettreAJourInvincibilite();
|
||||||
|
if (!cheatMode) joueur.verifierCollisionLigne(lili); // si cheat mode activé : plus de perte de vie
|
||||||
|
joueur.resterDansLigne(lili);
|
||||||
}
|
}
|
||||||
|
|
||||||
ecran.traiterBoucleAnimation();
|
ecran.traiterBoucleAnimation();
|
||||||
|
|
||||||
compteurFrames = compteurFrames + 1;
|
compteurFrames++;
|
||||||
|
// 25 frames à 40ms = 1 seconde, donc score ≈ durée en secondes
|
||||||
if (compteurFrames >= 25) {
|
if (compteurFrames >= 25) {
|
||||||
score = score + 1;
|
score++;
|
||||||
compteurFrames = 0;
|
compteurFrames = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compteurInvincible < 75) {
|
boolean tousMotrs = true;
|
||||||
compteurInvincible = compteurInvincible + 1;
|
for (Joueur joueur : joueurs) {
|
||||||
} else {
|
if (!joueur.estMort) {
|
||||||
if (demiCercleArriere.VerifierCollision(lili)) {
|
tousMotrs = false;
|
||||||
if (enCollision == false) {
|
break;
|
||||||
vies = vies - 1; // La nouvelle logique : on perd 1 vie
|
|
||||||
enCollision = true;
|
|
||||||
compteurInvincible = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
enCollision = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vies <= 0) {
|
if (tousMotrs) {
|
||||||
vies = 0;
|
// tous les joueurs sont morts, on déclenche le game over
|
||||||
estGameOver = true;
|
estGameOver = true;
|
||||||
ecran.arreter();
|
gestionnaireFinDePartie.declencherGameOver(ecran, pseudo, (int) score);
|
||||||
labGameOver.setVisible(true);
|
|
||||||
|
|
||||||
if (pseudo != null && !pseudo.isEmpty()) {
|
|
||||||
gestionnaireBDD.sauvegarderScore(pseudo, (int) score);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
labScore.setText("<html><h3>Score : " + (int) score + " | Vies : " + vies + "</h3></html>");
|
mettreAJourLabel();
|
||||||
|
}
|
||||||
|
|
||||||
demiCercleArriere.ResterDansLigne(lili);
|
private void mettreAJourLabel() {
|
||||||
demiCercleAvant.ResterDansLigne(lili);
|
StringBuilder sb = new StringBuilder("<html><h3>Score : " + (int) score + " | ");
|
||||||
|
if (deuxJoueurs) {
|
||||||
|
sb.append("J1 : ").append(joueurs.get(0).vies).append(" | ");
|
||||||
|
sb.append("J2 : ").append(joueurs.get(1).vies).append(" | ");
|
||||||
|
} else {
|
||||||
|
sb.append("Vies : ").append(joueurs.get(0).vies).append(" | ");
|
||||||
|
}
|
||||||
|
sb.append("Niv. ").append(gestionnaireNiveau.getNumeroNiveau()).append("</h3></html>");
|
||||||
|
labScore.setText(sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void retourMenu() {
|
private void retourMenu() {
|
||||||
@@ -185,12 +229,10 @@ public class Jeu implements KeyListener, ActionListener, MouseListener {
|
|||||||
horloge.stop();
|
horloge.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
lili = new Ligne(new NoiseGenerator(0));
|
// on repart de zéro : nouvelle ligne, nouveaux joueurs
|
||||||
|
gestionnaireNiveau.reinitialiser();
|
||||||
demiCercleAvant.y = 200;
|
lili = new Ligne(new NoiseGenerator(0), gestionnaireNiveau);
|
||||||
demiCercleAvant.vitesse = -1.0;
|
joueurs.clear();
|
||||||
demiCercleArriere.y = 200;
|
|
||||||
demiCercleArriere.vitesse = -1.0;
|
|
||||||
|
|
||||||
ecran.viderObjets();
|
ecran.viderObjets();
|
||||||
menu.afficher(pseudo);
|
menu.afficher(pseudo);
|
||||||
@@ -202,7 +244,8 @@ public class Jeu implements KeyListener, ActionListener, MouseListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
if (estGameOver == true) {
|
// un clic n'importe où à la fin de la partie pour revenir au menu
|
||||||
|
if (estGameOver) {
|
||||||
retourMenu();
|
retourMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,7 +261,12 @@ public class Jeu implements KeyListener, ActionListener, MouseListener {
|
|||||||
@Override
|
@Override
|
||||||
public void mouseExited(MouseEvent e) {
|
public void mouseExited(MouseEvent e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public GestionnaireScore getGestionnaireBDD() {
|
public GestionnaireScore getGestionnaireBDD() {
|
||||||
return gestionnaireBDD;
|
return gestionnaireBDD;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public GestionnaireHistorique getGestionnaireHistorique() {
|
||||||
|
return gestionnaireHistorique;
|
||||||
|
}
|
||||||
|
}
|
||||||
190
src/Joueur.java
Normal file
190
src/Joueur.java
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
package linea;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
|
||||||
|
// Gère le fonctionnement du joueur (vie, collision, déplacement)
|
||||||
|
public class Joueur {
|
||||||
|
|
||||||
|
protected Cercle demiCercleAvant;
|
||||||
|
protected Cercle demiCercleArriere;
|
||||||
|
|
||||||
|
protected int vies = 3;
|
||||||
|
protected boolean enCollision = false;
|
||||||
|
protected int compteurInvincible = 0;
|
||||||
|
protected boolean invincibiliteRouge = false;
|
||||||
|
|
||||||
|
protected boolean bonusTailleActif = false;
|
||||||
|
protected int compteurBonusTaille = 0;
|
||||||
|
|
||||||
|
protected boolean estMort = false;
|
||||||
|
|
||||||
|
protected Color couleurAvant;
|
||||||
|
protected Color couleurArriere;
|
||||||
|
|
||||||
|
protected int toucheHaut;
|
||||||
|
protected int toucheBas;
|
||||||
|
|
||||||
|
public Joueur(Color couleurAvant, Color couleurArriere, int toucheHaut, int toucheBas) {
|
||||||
|
this.demiCercleAvant = new Cercle(90, -180);
|
||||||
|
this.demiCercleArriere = new Cercle(90, 180);
|
||||||
|
this.couleurAvant = couleurAvant;
|
||||||
|
this.couleurArriere = couleurArriere;
|
||||||
|
this.toucheHaut = toucheHaut;
|
||||||
|
this.toucheBas = toucheBas;
|
||||||
|
appliquerCouleurs();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gère les contrôles du joueur
|
||||||
|
public void appliquerTouche(int keyCode, boolean pressed) {
|
||||||
|
if (estMort) return;
|
||||||
|
|
||||||
|
if (keyCode == toucheHaut) {
|
||||||
|
if (pressed) {
|
||||||
|
demiCercleAvant.Monter();
|
||||||
|
demiCercleArriere.Monter();
|
||||||
|
} else {
|
||||||
|
demiCercleAvant.ArreterMonter();
|
||||||
|
demiCercleArriere.ArreterMonter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (keyCode == toucheBas) {
|
||||||
|
if (pressed) {
|
||||||
|
demiCercleAvant.Descendre();
|
||||||
|
demiCercleArriere.Descendre();
|
||||||
|
} else {
|
||||||
|
demiCercleAvant.ArreterDescendre();
|
||||||
|
demiCercleArriere.ArreterDescendre();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mettreAJourRayon(double rayonBase) {
|
||||||
|
double rayon = rayonBase;
|
||||||
|
if (bonusTailleActif) {
|
||||||
|
rayon += 30;
|
||||||
|
compteurBonusTaille--;
|
||||||
|
if (compteurBonusTaille <= 0) {
|
||||||
|
bonusTailleActif = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
demiCercleAvant.setRayon(rayon);
|
||||||
|
demiCercleArriere.setRayon(rayon);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Appelé chaque frame et permet d'avancer le timer d'invincibilité et de mettre à jour l'effet visuel
|
||||||
|
public void mettreAJourInvincibilite() {
|
||||||
|
if (estMort) {
|
||||||
|
demiCercleAvant.setCouleur(new Color(0, 0, 0, 0));
|
||||||
|
demiCercleArriere.setCouleur(new Color(0, 0, 0, 0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compteurInvincible < 75) {
|
||||||
|
compteurInvincible++;
|
||||||
|
|
||||||
|
if (compteurInvincible % 10 < 5) {
|
||||||
|
if (invincibiliteRouge) {
|
||||||
|
demiCercleArriere.setCouleur(new Color(1f, 0f, 0f));
|
||||||
|
demiCercleAvant.setCouleur(new Color(1f, 0f, 0f));
|
||||||
|
} else {
|
||||||
|
demiCercleArriere.setCouleur(new Color(255, 255, 255, 150));
|
||||||
|
demiCercleAvant.setCouleur(new Color(255, 255, 255, 150));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
appliquerCouleurs();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
appliquerCouleurs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean estInvincible() {
|
||||||
|
return compteurInvincible < 75;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void verifierCollisionLigne(Ligne li) {
|
||||||
|
if (estMort || estInvincible()) return;
|
||||||
|
|
||||||
|
if (demiCercleArriere.VerifierCollision(li)) {
|
||||||
|
if (!enCollision) {
|
||||||
|
vies--;
|
||||||
|
enCollision = true;
|
||||||
|
compteurInvincible = 0;
|
||||||
|
invincibiliteRouge = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
enCollision = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vies <= 0) {
|
||||||
|
vies = 0;
|
||||||
|
estMort = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean verifierCollisionCollectible(double itemX, double itemY, double itemTaille, double vitesseLigne) {
|
||||||
|
if (estMort) return false;
|
||||||
|
double centreX = itemX + (itemTaille / 2.0);
|
||||||
|
if (centreX <= demiCercleAvant.x && centreX > demiCercleAvant.x - vitesseLigne) {
|
||||||
|
double hautCercle = demiCercleAvant.y - demiCercleAvant.getRayon();
|
||||||
|
double basCercle = demiCercleAvant.y + demiCercleAvant.getRayon();
|
||||||
|
return itemY > hautCercle && (itemY + itemTaille) < basCercle;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resterDansLigne(Ligne li) {
|
||||||
|
if (estMort) return;
|
||||||
|
demiCercleArriere.ResterDansLigne(li);
|
||||||
|
demiCercleAvant.ResterDansLigne(li);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void activerBonusTaille() {
|
||||||
|
bonusTailleActif = true;
|
||||||
|
compteurBonusTaille = 150;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ajouterVie() {
|
||||||
|
vies++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void retirerVie() {
|
||||||
|
vies--;
|
||||||
|
invincibiliteRouge = true;
|
||||||
|
compteurInvincible = 0;
|
||||||
|
if (vies <= 0) {
|
||||||
|
vies = 0;
|
||||||
|
estMort = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetInvincibilite() {
|
||||||
|
compteurInvincible = 0;
|
||||||
|
invincibiliteRouge = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void appliquerCouleurs() {
|
||||||
|
demiCercleArriere.setCouleur(couleurArriere);
|
||||||
|
demiCercleAvant.setCouleur(couleurAvant);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ajouterDansEcran(ZoneDessin ecran) {
|
||||||
|
ecran.ajouterObjet(demiCercleArriere);
|
||||||
|
ecran.ajouterObjet(demiCercleAvant);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reinitialiser(double posY) {
|
||||||
|
vies = 3;
|
||||||
|
enCollision = false;
|
||||||
|
compteurInvincible = 0;
|
||||||
|
invincibiliteRouge = false;
|
||||||
|
bonusTailleActif = false;
|
||||||
|
compteurBonusTaille = 0;
|
||||||
|
estMort = false;
|
||||||
|
demiCercleAvant.y = posY;
|
||||||
|
demiCercleAvant.vitesse = -1.0;
|
||||||
|
demiCercleArriere.y = posY;
|
||||||
|
demiCercleArriere.vitesse = -1.0;
|
||||||
|
appliquerCouleurs();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,40 +8,47 @@ import java.util.ArrayList;
|
|||||||
|
|
||||||
public class Ligne extends ObjetGraphique {
|
public class Ligne extends ObjetGraphique {
|
||||||
|
|
||||||
protected int nbSegments = 400;
|
protected int nbSegments = 50;
|
||||||
protected Segment SegCourant;
|
protected Segment SegCourant;
|
||||||
|
|
||||||
protected ArrayList<Segment> listeSegments = new ArrayList<Segment>();
|
protected ArrayList<Segment> listeSegments = new ArrayList<Segment>();
|
||||||
|
|
||||||
protected double limiteHaut = 50;
|
|
||||||
protected double limiteBas = 550;
|
|
||||||
|
|
||||||
protected Segment dernierSegment;
|
protected Segment dernierSegment;
|
||||||
private double decalageXDernierSegment = 0;
|
private double decalageXDernierSegment = 0;
|
||||||
|
|
||||||
protected double noiseFrequence = 1/50f;
|
|
||||||
|
|
||||||
private NoiseGenerator noiseGenerator;
|
private NoiseGenerator noiseGenerator;
|
||||||
|
private GestionnaireNiveau gestionnaireNiveau;
|
||||||
|
|
||||||
private double xActuel;
|
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;
|
double x = 0;
|
||||||
|
|
||||||
this.noiseGenerator = noiseGenerator;
|
this.noiseGenerator = noiseGenerator;
|
||||||
for (int i = 0; i < nbSegments; i++) {
|
this.gestionnaireNiveau = gestionnaireNiveau;
|
||||||
|
|
||||||
Segment s = CreerSegment(x);
|
double dx = GetLargeurSegment();
|
||||||
|
|
||||||
|
for (int i = 0; i < nbSegments; i++) {
|
||||||
|
double noiseStep = getNoiseStep();
|
||||||
|
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);
|
listeSegments.add(s);
|
||||||
|
noiseCurseur += noiseStep;
|
||||||
|
|
||||||
if (i == nbSegments - 1)
|
if (i == nbSegments - 1) {
|
||||||
{
|
|
||||||
dernierSegment = s;
|
dernierSegment = s;
|
||||||
xActuel = x + s.xLong;
|
xActuel = x + dx;
|
||||||
}
|
}
|
||||||
|
|
||||||
x += s.xLong;
|
x += dx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,26 +56,35 @@ public class Ligne extends ObjetGraphique {
|
|||||||
return (double)ZoneDessin.largeur / nbSegments;
|
return (double)ZoneDessin.largeur / nbSegments;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Segment CreerSegment(double x){
|
private double getNoiseStep() {
|
||||||
double dx = GetLargeurSegment();
|
return GetLargeurSegment() / gestionnaireNiveau.getNoiseFrequence();
|
||||||
double y = CalculerY(x);
|
}
|
||||||
double dy = CalculerY(x + dx) - y;
|
|
||||||
|
|
||||||
Segment s = new Segment(x, y, dx, dy);
|
// Quand un segment sort de l'écran, génère un nouveau segment à la fin de la ligne.
|
||||||
|
protected Segment CreerSegmentSuivant(){
|
||||||
|
double noiseStep = getNoiseStep();
|
||||||
|
|
||||||
|
double yDebut = CalculerY(noiseCurseur);
|
||||||
|
double yFin = CalculerY(noiseCurseur + noiseStep);
|
||||||
|
|
||||||
|
noiseCurseur += noiseStep;
|
||||||
|
|
||||||
|
Segment s = new Segment(0, yDebut, GetLargeurSegment(), yFin - yDebut);
|
||||||
s.setCouleur(new Color(0.2f, 0.2f, 0.2f));
|
s.setCouleur(new Color(0.2f, 0.2f, 0.2f));
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected double CalculerY(double x){
|
// Calcule la hauteur de la ligne à un point X.
|
||||||
|
protected double CalculerY(double noisePos){
|
||||||
|
double limiteHaut = gestionnaireNiveau.getLimiteHaut();
|
||||||
|
double limiteBas = gestionnaireNiveau.getLimiteBas();
|
||||||
double hauteur = limiteBas - limiteHaut;
|
double hauteur = limiteBas - limiteHaut;
|
||||||
|
|
||||||
double bruit = noiseGenerator.noise(x * noiseFrequence);
|
double bruit = noiseGenerator.noise(noisePos, 1);
|
||||||
bruit = (bruit + 1) / 2;
|
double normalise = (bruit + 1) / 2;
|
||||||
|
|
||||||
return limiteBas - bruit * hauteur;
|
return limiteBas - normalise * hauteur;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -94,14 +110,17 @@ public class Ligne extends ObjetGraphique {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void Animer() {
|
public void Animer() {
|
||||||
|
double vitesse = gestionnaireNiveau.getVitesseScroll();
|
||||||
|
|
||||||
for (Segment s : listeSegments) {
|
for (Segment s : listeSegments) {
|
||||||
s.Animer();
|
s.Animer();
|
||||||
s.x -= 10;
|
s.x -= vitesse;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateSegments();
|
UpdateSegments();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Permet de réutiliser les segments sortis de l'écran au debut
|
||||||
private void UpdateSegments(){
|
private void UpdateSegments(){
|
||||||
|
|
||||||
if (dernierSegment == null) throw new RuntimeException("dernierSegment n'existe pas");
|
if (dernierSegment == null) throw new RuntimeException("dernierSegment n'existe pas");
|
||||||
@@ -109,8 +128,8 @@ public class Ligne extends ObjetGraphique {
|
|||||||
for (int i = 0; i < listeSegments.size(); i++) {
|
for (int i = 0; i < listeSegments.size(); i++) {
|
||||||
|
|
||||||
Segment s = listeSegments.get(i);
|
Segment s = listeSegments.get(i);
|
||||||
if (s.x + s.xLong < 0) {
|
if (s.x + s.xLong < 0) { // le segment est ENTIEREMENT hors de l'écran
|
||||||
Segment nouveauSegment = CreerSegment(xActuel);
|
Segment nouveauSegment = CreerSegmentSuivant();
|
||||||
nouveauSegment.x = dernierSegment.x + dernierSegment.xLong;
|
nouveauSegment.x = dernierSegment.x + dernierSegment.xLong;
|
||||||
listeSegments.set(i, nouveauSegment);
|
listeSegments.set(i, nouveauSegment);
|
||||||
|
|
||||||
@@ -120,9 +139,10 @@ public class Ligne extends ObjetGraphique {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Renvoie la hauteur à laquelle doit etre le cercle. Utilisé pour la collision
|
||||||
public double GetHauteurPointCercle(){
|
public double GetHauteurPointCercle(){
|
||||||
double t = (400 - SegCourant.x) / SegCourant.xLong;
|
double t = (400 - SegCourant.x) / SegCourant.xLong;
|
||||||
|
|
||||||
return SegCourant.y + SegCourant.yLong * t;
|
return SegCourant.y + SegCourant.yLong * t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
36
src/Malus.java
Normal file
36
src/Malus.java
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package linea;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Malus extends ObjetCollectible {
|
||||||
|
|
||||||
|
|
||||||
|
public Malus(Ligne l, List<Joueur> joueurs, Jeu j) {
|
||||||
|
super(l, joueurs, j);
|
||||||
|
this.taille = 10;
|
||||||
|
this.couleur = Color.RED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override protected int getSeuilActivation() { return 250; }
|
||||||
|
|
||||||
|
@Override protected Color getCouleurCapture() { return Color.BLACK; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected double calculerY(double hauteurLigne) {
|
||||||
|
if (Math.random() > 0.5) return hauteurLigne - 75 - (Math.random() * 30); // position du malus
|
||||||
|
else return hauteurLigne + 75 + (Math.random() * 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void appliquerEffet(Joueur joueur) {
|
||||||
|
// On ne punit pas si le joueur est en cheat mode ou en période d'invincibilité (clignotement)
|
||||||
|
if (!monJeu.cheatMode && !joueur.estInvincible()) joueur.retirerVie();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void dessiner(Graphics g) {
|
||||||
|
g.fillRect((int)Math.round(x), (int)Math.round(y), (int)taille, (int)taille);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package linea;
|
package linea;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
import java.awt.FlowLayout;
|
import java.awt.FlowLayout;
|
||||||
import java.awt.GridLayout;
|
import java.awt.GridLayout;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
@@ -10,10 +11,12 @@ import javax.swing.JFrame;
|
|||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTable;
|
||||||
import javax.swing.JTextField;
|
import javax.swing.JTextField;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.table.DefaultTableModel;
|
||||||
|
|
||||||
// Classe qui représente le menu principal du jeu (affiché au lancement).
|
|
||||||
public class MenuPrincipal {
|
public class MenuPrincipal {
|
||||||
|
|
||||||
private JFrame fenetre;
|
private JFrame fenetre;
|
||||||
@@ -25,37 +28,64 @@ public class MenuPrincipal {
|
|||||||
this.jeu = jeu;
|
this.jeu = jeu;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construit et affiche le panneau du menu dans la fenêtre
|
|
||||||
public void afficher(String pseudoActuel) {
|
public void afficher(String pseudoActuel) {
|
||||||
|
|
||||||
JPanel panneau = new JPanel(new GridLayout(6, 1, 10, 10));
|
JPanel panneau = new JPanel(new GridLayout(9, 1, 10, 10));
|
||||||
|
|
||||||
JLabel titre = new JLabel("LINEA", SwingConstants.CENTER);
|
JLabel titre = new JLabel("LINEA", SwingConstants.CENTER);
|
||||||
champPseudo = new JTextField(pseudoActuel, 15);
|
champPseudo = new JTextField(pseudoActuel, 15);
|
||||||
|
|
||||||
JButton boutonJouer = new JButton("Jouer");
|
JButton bouton1Joueur = new JButton("1 Joueur");
|
||||||
|
JButton bouton2Joueurs = new JButton("2 Joueurs");
|
||||||
JButton boutonClassement = new JButton("Classement");
|
JButton boutonClassement = new JButton("Classement");
|
||||||
|
JButton boutonHistorique = new JButton("Historique");
|
||||||
JButton boutonQuitter = new JButton("Quitter");
|
JButton boutonQuitter = new JButton("Quitter");
|
||||||
|
JButton boutonCheat = new JButton("Cheat Mode : OFF");
|
||||||
|
|
||||||
boutonJouer.addActionListener(new ActionListener() {
|
bouton1Joueur.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
jeu.lancerPartie(champPseudo.getText());
|
jeu.lancerPartie(champPseudo.getText(), false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bouton2Joueurs.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
jeu.lancerPartie(champPseudo.getText(), true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
boutonClassement.addActionListener(new ActionListener() {
|
boutonClassement.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
|
||||||
// 1. On récupère les scores depuis la BDD via l'objet 'jeu'
|
|
||||||
String scores = jeu.getGestionnaireBDD().getTopScores();
|
String scores = jeu.getGestionnaireBDD().getTopScores();
|
||||||
|
|
||||||
// 2. On affiche le résultat dans la petite fenêtre popup
|
|
||||||
JOptionPane.showMessageDialog(fenetre, scores, "Meilleurs Scores", JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.showMessageDialog(fenetre, scores, "Meilleurs Scores", JOptionPane.INFORMATION_MESSAGE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
boutonHistorique.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
// pour le modele de tableau
|
||||||
|
DefaultTableModel modele = jeu.getGestionnaireHistorique().getModeleTableau();
|
||||||
|
|
||||||
|
JTable tableau = new JTable(modele);
|
||||||
|
|
||||||
|
// pour ne pas pouvoir modifier le tableau
|
||||||
|
tableau.setDefaultEditor(Object.class, null);
|
||||||
|
// pour ne pas faire bouger les collones
|
||||||
|
tableau.getTableHeader().setReorderingAllowed(false);
|
||||||
|
|
||||||
|
// pour le scroll
|
||||||
|
JScrollPane scrollPane = new JScrollPane(tableau);
|
||||||
|
scrollPane.setPreferredSize(new Dimension(400, 300));
|
||||||
|
|
||||||
|
// afficher la fenetre pop up
|
||||||
|
JOptionPane.showMessageDialog(fenetre, scrollPane, "Historique des parties", JOptionPane.PLAIN_MESSAGE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
boutonQuitter.addActionListener(new ActionListener() {
|
boutonQuitter.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
@@ -63,18 +93,28 @@ public class MenuPrincipal {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
boutonCheat.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
jeu.cheatMode = !jeu.cheatMode;
|
||||||
|
boutonCheat.setText(jeu.cheatMode ? "Cheat Mode : ON" : "Cheat Mode : OFF");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
panneau.add(titre);
|
panneau.add(titre);
|
||||||
panneau.add(champPseudo);
|
panneau.add(champPseudo);
|
||||||
panneau.add(boutonJouer);
|
panneau.add(bouton1Joueur);
|
||||||
|
panneau.add(bouton2Joueurs);
|
||||||
panneau.add(boutonClassement);
|
panneau.add(boutonClassement);
|
||||||
|
panneau.add(boutonHistorique);
|
||||||
|
panneau.add(boutonCheat);
|
||||||
panneau.add(boutonQuitter);
|
panneau.add(boutonQuitter);
|
||||||
|
|
||||||
// panneau centré dans la fenêtre
|
JPanel conteneur = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 110));
|
||||||
JPanel conteneur = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 150));
|
|
||||||
conteneur.add(panneau);
|
conteneur.add(panneau);
|
||||||
|
|
||||||
fenetre.setContentPane(conteneur);
|
fenetre.setContentPane(conteneur);
|
||||||
fenetre.revalidate();
|
fenetre.revalidate();
|
||||||
fenetre.repaint();
|
fenetre.repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
25
src/Niveau.java
Normal file
25
src/Niveau.java
Normal file
@@ -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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -109,11 +109,28 @@ public class NoiseGenerator {
|
|||||||
return value / initialSize;
|
return value / initialSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Seule fonction publique utilisée, génère une valeur de -1 à 1 à un point x.
|
||||||
|
public double noise(double x, int octaves) {
|
||||||
|
double value = 0.0;
|
||||||
|
double size = default_size;
|
||||||
|
double weightSum = 0;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
while (size >= 1 && count < octaves) {
|
||||||
|
value += smoothNoise((x / size), 0.7, 0.3) * size;
|
||||||
|
weightSum += size;
|
||||||
|
size /= 2.0;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value / weightSum;
|
||||||
|
}
|
||||||
|
|
||||||
public double smoothNoise(double x, double y, double z) {
|
public double smoothNoise(double x, double y, double z) {
|
||||||
// Offset each coordinate by the seed value
|
// Offset each coordinate by the seed value
|
||||||
x += this.seed;
|
x += this.seed;
|
||||||
y += this.seed;
|
y += this.seed;
|
||||||
x += this.seed;
|
z += this.seed;
|
||||||
|
|
||||||
int X = (int) Math.floor(x) & 255; // FIND UNIT CUBE THAT
|
int X = (int) Math.floor(x) & 255; // FIND UNIT CUBE THAT
|
||||||
int Y = (int) Math.floor(y) & 255; // CONTAINS POINT.
|
int Y = (int) Math.floor(y) & 255; // CONTAINS POINT.
|
||||||
|
|||||||
81
src/ObjetCollectible.java
Normal file
81
src/ObjetCollectible.java
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package linea;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
// Classe de base pour tous les objets qu'on peut ramasser (bonus, malus...)
|
||||||
|
// Elle gère toute la logique commune : apparition, déplacement, collision
|
||||||
|
|
||||||
|
public abstract class ObjetCollectible extends ObjetGraphique {
|
||||||
|
|
||||||
|
protected double taille;
|
||||||
|
protected boolean actif = false;
|
||||||
|
protected int compteurFrames = 0;
|
||||||
|
protected boolean dejaCapture = false;
|
||||||
|
|
||||||
|
protected Ligne maLigne;
|
||||||
|
protected List<Joueur> joueurs;
|
||||||
|
protected Jeu monJeu;
|
||||||
|
|
||||||
|
public ObjetCollectible(Ligne l, List<Joueur> joueurs, Jeu j) {
|
||||||
|
this.maLigne = l;
|
||||||
|
this.joueurs = joueurs;
|
||||||
|
this.monJeu = j;
|
||||||
|
}
|
||||||
|
// Chaque sous-classe décide quand elle apparaît, où, quel effet elle a et comment elle se dessine
|
||||||
|
|
||||||
|
protected abstract int getSeuilActivation();
|
||||||
|
protected abstract double calculerY(double hauteurLigne);
|
||||||
|
|
||||||
|
protected abstract void appliquerEffet(Joueur joueur);
|
||||||
|
|
||||||
|
protected abstract Color getCouleurCapture();
|
||||||
|
|
||||||
|
protected abstract void dessiner(Graphics g);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void Afficher(Graphics g) {
|
||||||
|
if (actif) {
|
||||||
|
g.setColor(dejaCapture ? getCouleurCapture() : this.couleur);
|
||||||
|
dessiner(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void Animer() {
|
||||||
|
if (!actif) compteurFrames++;
|
||||||
|
|
||||||
|
if (compteurFrames >= getSeuilActivation() && !actif) {
|
||||||
|
// Quand on a attendu assez longtemps, l'objet spawn à droite de l'écran
|
||||||
|
|
||||||
|
actif = true;
|
||||||
|
dejaCapture = false;
|
||||||
|
x = 800;
|
||||||
|
double hauteurLigne = 300;
|
||||||
|
if (maLigne.dernierSegment != null)
|
||||||
|
hauteurLigne = maLigne.dernierSegment.y;
|
||||||
|
y = calculerY(hauteurLigne);
|
||||||
|
if (y < 20) y = 20;
|
||||||
|
if (y > 550) y = 550;
|
||||||
|
compteurFrames = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actif) {
|
||||||
|
double vitesseLigne = monJeu.gestionnaireNiveau.getVitesseScroll();
|
||||||
|
x -= vitesseLigne; // l'objet suit la vitesse du niveau
|
||||||
|
|
||||||
|
if (!dejaCapture) {
|
||||||
|
for (Joueur joueur : joueurs) {
|
||||||
|
if (joueur.verifierCollisionCollectible(x, y, taille, vitesseLigne)) {
|
||||||
|
appliquerEffet(joueur); // délégué à la sous-classe
|
||||||
|
dejaCapture = true; // évite d'appliquer l'effet plusieurs fois
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (x + taille < 0) actif = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -21,10 +21,17 @@ public class ZoneDessin extends JPanel {
|
|||||||
public static int largeur = 800;
|
public static int largeur = 800;
|
||||||
public static int hauteur = 600;
|
public static int hauteur = 600;
|
||||||
|
|
||||||
|
private Color couleurFond = new Color(0, 73, 220);
|
||||||
|
|
||||||
public ZoneDessin() {
|
public ZoneDessin() {
|
||||||
setLayout(new BorderLayout());
|
setLayout(new BorderLayout());
|
||||||
setPreferredSize(new Dimension(largeur, hauteur));
|
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) {
|
public void ajouterObjet(ObjetGraphique unObjet) {
|
||||||
|
|||||||
Reference in New Issue
Block a user