Compare commits

...

3 Commits

Author SHA1 Message Date
684c0d2f07 add README and finish MVP product 2026-03-28 13:30:40 +01:00
3d9ba13bff add level sound 2026-03-28 11:59:04 +01:00
67f76876a6 add gestion sound level 2026-03-28 11:56:55 +01:00
40 changed files with 208 additions and 32 deletions

Binary file not shown.

View File

@@ -1,18 +1,78 @@
## Getting Started
🚀 ZENITH FLUX — Montez plus haut
Welcome to the VS Code Java world. Here is a guideline to help you get started to write Java code in Visual Studio Code.
ZENITH FLUX est un jeu dadresse et de précision développé en Java dans le cadre du module Projet Dev - CPI2 2026.
Le joueur doit maintenir un anneau en lévitation le long dune trajectoire en mouvement, en défiant la gravité pour atteindre le score le plus élevé.
## Folder Structure
🎯 Concept du jeu
The workspace contains two folders by default, where:
Le gameplay repose sur un principe simple mais exigeant :
- `src`: the folder to maintain sources
- `lib`: the folder to maintain dependencies
⚖️ Gravité constante : lanneau est continuellement attiré vers le bas
🚀 Impulsion verticale : le joueur doit compenser cette chute avec précision
🎯 Suivi de trajectoire : rester aligné avec une ligne brisée en mouvement
📈 Progression : difficulté croissante à travers plusieurs niveaux (stages)
Meanwhile, the compiled output files will be generated in the `bin` folder by default.
👉 Le défi : tenir le plus longtemps possible sans sortir de la trajectoire
> If you want to customize the folder structure, open `.vscode/settings.json` and update the related settings there.
🎮 Fonctionnalités
✔️ Gameplay dynamique basé sur la physique
✔️ Système de niveaux configurables
✔️ Sauvegarde des performances (score, durée, progression)
✔️ Interface simple et immersive
✔️ Expérience complète : introduction, montée en difficulté, fin de partie
👥 Équipe de développement
## Dependency Management
Projet réalisé par :
The `JAVA PROJECTS` view allows you to manage your dependencies. More details can be found [here](https://github.com/microsoft/vscode-java-dependency#manage-dependencies).
Constant Eloundou
Lucas Lample
Ismaël Boubacar
Théo Mouniapin
🛠️ Technologies utilisées
Langage : Java (Programmation Orientée Objet)
Architecture : UML (Diagrammes de classes, séquences, activités)
Base de données : SQLite
💾 Persistance des données
📊 Historique des parties :
Date
Durée
Score
Niveau atteint
🧩 Configuration des niveaux :
Paramétrage dynamique des stages
Modification possible sans recompiler le jeu
📦 Contenu du dépôt
Ce dépôt contient :
📁 Code source Java (documenté avec JavaDoc)
📊 Diagrammes UML complets
📝 Rapport de projet (organisation, tâches, contributions)
▶️ Exécutable (.jar) prêt à être lancé
📖 Guide utilisateur (installation et commandes)
🚀 Installation et lancement
🔧 Prérequis
Java JDK/JRE 17 ou supérieur
📥 Cloner le projet
git clone https://github.com/votre-repo/zenith-flux.git
cd zenith-flux
▶️ Lancer le jeu
java -jar ZenithFlux.jar
📅 Planning de développement
Semaine Objectif
1 - 2 Prise en main du projet + prototype
3 - 5 Développement intensif + fonctionnalités avancées
6 Finalisation, optimisation et soutenance
🧠 Points forts du projet
Architecture propre et modulaire
Séparation claire entre logique, données et affichage
Utilisation concrète dune base de données
Projet complet : de la conception à la livraison
⚖️ Licence
Projet réalisé dans un cadre pédagogique (CPI2 2026).
Usage académique uniquement.
❤️ Remerciements
Merci à tous les encadrants et contributeurs du projet.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 815 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -27,6 +27,10 @@ public class CadreDeConnexion extends JFrame {
// S'assure que la structure de la base existe même avant la connexion/création de compte
GestionBDD.creerTableUtilisateurSiAbsente();
GestionBDD.creerTableScoreSiAbsente();
String musiqueZENITH = "musiques/son_ZENITH_FLUX.wav";
GestionAudio.jouerMusique(musiqueZENITH);
// Image de fond de la page de connexion
Background panelBackground = null;

View File

@@ -0,0 +1,72 @@
//---------------------------------------------------------------------------------
// Cette classe peremt de gérer la lecture, l'arrêt et la répétition(loop)
//---------------------------------------------------------------------------------
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
public class GestionAudio {
// Clip est une interface qui hérite de DataLine
private static Clip clip;
//Propriété de la musique actuelle
private static String musiqueActuelle = "";
//------------------------------------------------------------------------------
// Méthode pour jouer la musique
//------------------------------------------------------------------------------
public static void jouerMusique(String cheminDansSrc){
if (cheminDansSrc == null || cheminDansSrc.isEmpty()) {
return;
}
// Si la musique demandée joue déjà, on ne fait rien
if(cheminDansSrc.equals(musiqueActuelle)){
return;
}
// On arrête la musique précédente
stop();
// Sinon, on met la bonne musique
try {
// On récupère l'audio depuis src
URL urlSound = GestionAudio.class.getResource("/" + cheminDansSrc);
// On vérifie si on a bien récupéré une musique
// Si c'est le cas
if(urlSound != null){
// On transforme le fichier URL du fichier en flux audio lisible ar JAVA
// Autrement dit: On prépare le fichier pour la lecture sonore
try (AudioInputStream ais = AudioSystem.getAudioInputStream(urlSound)) {
// Création d'un objet Clip permettant de jouer du son court en mémoire
clip = AudioSystem.getClip();
// On charge le flux audio dans le clip
// Le son est prêt à être joué
clip.open(ais);
clip.loop(Clip.LOOP_CONTINUOUSLY); // On fait jouer en boucle infinie
clip.start(); // On démarre l'audio
musiqueActuelle = cheminDansSrc; // Notre musique actuelle a déjà une valeur
}
}
} catch (Exception e) {
System.err.println("Erreur Audio: " + e.getMessage());
}
}
//------------------------------------------------------------------------------
// Méthode pour arrêter la musique
//------------------------------------------------------------------------------s
private static void stop() {
if(clip != null){
clip.stop();
clip.close();
clip = null;
musiqueActuelle = "";
}
}
}

View File

@@ -2,7 +2,9 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;
import java.sql.Connection;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
@@ -79,8 +81,21 @@ public class Jeu implements KeyListener, ActionListener{
// Créer les tables de la base de données si elles n'existent pas
GestionBDD.creerTableUtilisateurSiAbsente();
GestionBDD.creerTableScoreSiAbsente();
JFrame fenetre = new JFrame();
try {
String cheminRessource = "/images/icone.png";
URL url = getClass().getResource(cheminRessource);
if (url != null) {
java.awt.Image img = ImageIO.read(url);
fenetre.setIconImage(img);
} else {
System.err.println("Ressource introuvable : " + cheminRessource);
}
} catch (Exception e) {
System.err.println("Erreur chargement image : " + e.getMessage());
}
this.utilisateurId = utilisateurId;
@@ -214,6 +229,19 @@ public class Jeu implements KeyListener, ActionListener{
JFrame fenetre = new JFrame();
this.fenetrePrincipale = fenetre; // On sauvegarde la fenêtre principale de la partie en cours dans une variable. Cela nous permettra de la fermer proprement (avec la méthode .dispose()) quand le joueur voudra lancer une nouvelle partie.
try {
String cheminRessource = "/images/icone.png";
URL url = getClass().getResource(cheminRessource);
if (url != null) {
java.awt.Image img = ImageIO.read(url);
fenetre.setIconImage(img);
} else {
System.err.println("Ressource introuvable : " + cheminRessource);
}
} catch (Exception e) {
System.err.println("Erreur chargement image : " + e.getMessage());
}
// A FAIRE :
// placer dans l'instance de l'écran tous les objets graphiques nécessaires
// par exemple : ecran.ajouterObjet(demiCerleArriere);
@@ -328,12 +356,14 @@ public class Jeu implements KeyListener, ActionListener{
// On corse le jeu avec son ID
//On applique les paramètres aux options de jeu
this.laLigne.generer(niveauEnCours.getNbSegments(), niveauEnCours.getId());
this.laLigne.setVitesseLigne(niveauEnCours.getVitesseLigne()); // On modifie la vitesse de déplacement
this.demiCercleAvant.setCouleur(niveauEnCours.getCouleurCercle());
this.demiCercleArriere.setCouleur(niveauEnCours.getCouleurCercle());
this.ecran.changerImageFond(niveauEnCours.getImage());
this.itemCourant.vitesse = niveauEnCours.getVitesseLigne();
GestionAudio.jouerMusique(niveauEnCours.getMusiqueNiveau());
}else{

View File

@@ -12,7 +12,7 @@ public class Ligne extends ObjetGraphique{// Hérite de la classe ObjetGraphique
//-------------------------------------------------------------------------
// nb de Segments qui composent la ligne
protected int nbSegments = 400;
protected int nbSegments = 1500;
// position du cercle, pour déterminer quel est le segment courant
protected double xCercle = 400; // à modifier

View File

@@ -7,9 +7,10 @@ public class Niveau {
private String image;
private int multiplicateurScore;
private String couleurCercle;
private String musqiueNiveau;
// Constructeur de la classe Niveau
public Niveau(int id, String nom, int vitesseLigne, int nbSegments, String image, int multiplicateurScore, String couleurCercle) {
public Niveau(int id, String nom, int vitesseLigne, int nbSegments, String image, int multiplicateurScore, String couleurCercle, String musiqueNiveau) {
this.id = id;
this.nom = nom;
this.vitesseLigne = vitesseLigne;
@@ -17,6 +18,7 @@ public class Niveau {
this.image = image;
this.multiplicateurScore = multiplicateurScore;
this.couleurCercle = couleurCercle;
this.musqiueNiveau = musiqueNiveau;
}
// Getters pour les propriétés du niveau
@@ -47,5 +49,9 @@ public class Niveau {
public String getCouleurCercle() {
return couleurCercle;
}
public String getMusiqueNiveau(){
return musqiueNiveau;
}
}

View File

@@ -102,7 +102,8 @@ public class NiveauxDataConnect {
+ "nb_segments INTEGER NOT NULL, " /*nombre de segments à faire passer au joueur pour réussir le niveau*/
+ "image TEXT NOT NULL, " /*image du niveau*/
+ "multiplicateur_score INTEGER, " /*multiplier le score en fonction du niveau*/
+ "couleur_cercle TEXT NOT NULL " /*Couleur du cercle en fonctiond du niveau */
+ "couleur_cercle TEXT NOT NULL, " /*Couleur du cercle en fonctiond du niveau */
+ "musique_theme TEXT NOT NULL" /*Musique du thème du niveau */
+");" ;
try (Statement stmt = conn.createStatement()) {
@@ -123,25 +124,27 @@ public class NiveauxDataConnect {
// dans la base de données pour éviter de les insérer à chaque fois que
// le jeu est lancé
// Pour corser le jeu, on utilisera l'id du niveau qui nous servira de difficulté
// --------------------------------Niveau 1 --------------------------------
// nom = "Facile", vitesse_ligne = 5, nb_segments = 50, image = "images\ciel.jpeg", multiplicateur_score = 10, couleur_cercle = "bleu"
// --------------------------------Niveau 2 --------------------------------
// nom = "intermédaire", vitesse_ligne = 7, nb_segments = 100, image = "images\montagnes.jpg", multiplicateur_score = 20, couleur_cercle = "gris"
// --------------------------------Niveau 3 --------------------------------
// nom = "Difficile", vitesse_ligne = 9, nb_segments = 100, image = "images\volcan.jpg", multiplicateur_score = 30, couleur_cercle = "marron"
// --------------------------------Niveau 4 --------------------------------
// nom = "Ultime", vitesse_ligne = 10, nb_segments = 150, image = "images\espace.jpg", multiplicateur_score = 50, couleur_cercle = "violet"
// -------------------------------------------------------------------------
// --------------------------------Niveau 1 ---------------------------------------------------------------------------------------------------------------------------------------------------
// nom = "Facile", vitesse_ligne = 5, nb_segments = 150, image = "images\ciel.jpeg", multiplicateur_score = 10, couleur_cercle = "bleu", musique = "musiques\musique_theme_ciel.wav"
// --------------------------------Niveau 2 ---------------------------------------------------------------------------------------------------------------------------------------------------
// nom = "intermédaire", vitesse_ligne = 7, nb_segments = 250, image = "images\montagnes.jpg", multiplicateur_score = 20, couleur_cercle = "gris", musique = "musiques\musique_theme_montagnes.wav"
// --------------------------------Niveau 3 ---------------------------------------------------------------------------------------------------------------------------------------------------
// nom = "Difficile", vitesse_ligne = 9, nb_segments = 250, image = "images\volcan.jpg", multiplicateur_score = 30, couleur_cercle = "marron", musique = "musiques\musique_theme_volcan.wav"
// --------------------------------Niveau 4 ---------------------------------------------------------------------------------------------------------------------------------------------------
// nom = "Ultime", vitesse_ligne = 10, nb_segments = 200, image = "images\espace.jpg", multiplicateur_score = 50, couleur_cercle = "violet", musique = "musiques\musique_theme_espace.wav"
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
public static void insererNiveau(Connection conn) {
String query1 = "INSERT INTO niveau(nom, vitesse_ligne, nb_segments, image, multiplicateur_score, couleur_cercle) "
+ "VALUES('Facile', 5, 50, 'images/ciel.jpeg', 10, '#0000FF');";
String query1 = "INSERT INTO niveau(nom, vitesse_ligne, nb_segments, image, multiplicateur_score, couleur_cercle, musique_theme) "
+ "VALUES('Facile', 5, 150, 'images/ciel.jpeg', 10, '#0000FF', 'musiques/musique_theme_ciel.wav');";
String query2 = "INSERT INTO niveau(nom, vitesse_ligne, nb_segments, image, multiplicateur_score, couleur_cercle) "
+ "VALUES('Intermédiaire', 7, 100, 'images/montagnes.jpg', 20, '#808080');";
String query3 = "INSERT INTO niveau(nom, vitesse_ligne, nb_segments, image, multiplicateur_score, couleur_cercle) "
+ "VALUES('Difficile', 9, 100, 'images/volcan.jpg', 30, '#8B4513');";
String query4 = "INSERT INTO niveau(nom, vitesse_ligne, nb_segments, image, multiplicateur_score, couleur_cercle) "
+ "VALUES('Ultime', 10, 150, 'images/espace.jpg', 50, '#9400D3');";
String query2 = "INSERT INTO niveau(nom, vitesse_ligne, nb_segments, image, multiplicateur_score, couleur_cercle, musique_theme) "
+ "VALUES('Intermédiaire', 7, 250, 'images/montagnes.jpg', 20, '#808080', 'musiques/musique_theme_montagnes.wav');";
String query3 = "INSERT INTO niveau(nom, vitesse_ligne, nb_segments, image, multiplicateur_score, couleur_cercle, musique_theme) "
+ "VALUES('Difficile', 9, 250, 'images/volcan.jpg', 30, '#8B4513', 'musiques/musique_theme_volcan.wav');";
String query4 = "INSERT INTO niveau(nom, vitesse_ligne, nb_segments, image, multiplicateur_score, couleur_cercle, musique_theme) "
+ "VALUES('Ultime', 10, 200, 'images/espace.jpg', 50, '#9400D3', 'musiques/musique_theme_espace.wav');";
try (Statement stmt = conn.createStatement()) {
stmt.execute(query1);
@@ -175,7 +178,8 @@ public class NiveauxDataConnect {
String image = rs.getString("image");
int multiplicateur_score = rs.getInt("multiplicateur_score");
String couleur_cercle = rs.getString("couleur_cercle");
niveauRecup = new Niveau(id1, nom, vitesse_ligne, nb_segments, image, multiplicateur_score, couleur_cercle);
String musique_niveau = rs.getString("musique_theme");
niveauRecup = new Niveau(id1, nom, vitesse_ligne, nb_segments, image, multiplicateur_score, couleur_cercle, musique_niveau);
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.