commit f4091183d83b9a03b4ca9c943f0b54f080729286 Author: Constant Date: Fri Mar 13 11:07:07 2026 +0100 Intégration de projet_linea dans le dépôt principal diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ca91737 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "java.project.sourcePaths": [ + "projet_linea/lib", + "projet_linea/src" + ], + "java.project.referencedLibraries": [] +} \ No newline at end of file diff --git a/DOCUMENTS INSTRUCTIONS/Cadre.pdf b/DOCUMENTS INSTRUCTIONS/Cadre.pdf new file mode 100644 index 0000000..ca850d4 Binary files /dev/null and b/DOCUMENTS INSTRUCTIONS/Cadre.pdf differ diff --git a/DOCUMENTS INSTRUCTIONS/Prototype - mise en route.pdf b/DOCUMENTS INSTRUCTIONS/Prototype - mise en route.pdf new file mode 100644 index 0000000..f4932c4 Binary files /dev/null and b/DOCUMENTS INSTRUCTIONS/Prototype - mise en route.pdf differ diff --git a/projet_linea/.vscode/settings.json b/projet_linea/.vscode/settings.json new file mode 100644 index 0000000..e112a70 --- /dev/null +++ b/projet_linea/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "java.project.sourcePaths": ["src"], + "java.project.outputPath": "bin", + "java.project.referencedLibraries": [ + "lib/**/*.jar" + ] +} diff --git a/projet_linea/Niveaux.db b/projet_linea/Niveaux.db new file mode 100644 index 0000000..38c8221 Binary files /dev/null and b/projet_linea/Niveaux.db differ diff --git a/projet_linea/README.md b/projet_linea/README.md new file mode 100644 index 0000000..7c03a53 --- /dev/null +++ b/projet_linea/README.md @@ -0,0 +1,18 @@ +## Getting Started + +Welcome to the VS Code Java world. Here is a guideline to help you get started to write Java code in Visual Studio Code. + +## Folder Structure + +The workspace contains two folders by default, where: + +- `src`: the folder to maintain sources +- `lib`: the folder to maintain dependencies + +Meanwhile, the compiled output files will be generated in the `bin` folder by default. + +> If you want to customize the folder structure, open `.vscode/settings.json` and update the related settings there. + +## Dependency Management + +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). diff --git a/projet_linea/bin/BonusMalus.class b/projet_linea/bin/BonusMalus.class new file mode 100644 index 0000000..b44426d Binary files /dev/null and b/projet_linea/bin/BonusMalus.class differ diff --git a/projet_linea/bin/Cercle.class b/projet_linea/bin/Cercle.class new file mode 100644 index 0000000..7bb7888 Binary files /dev/null and b/projet_linea/bin/Cercle.class differ diff --git a/projet_linea/bin/GestionBDD.class b/projet_linea/bin/GestionBDD.class new file mode 100644 index 0000000..fa345fc Binary files /dev/null and b/projet_linea/bin/GestionBDD.class differ diff --git a/projet_linea/bin/Jeu$1.class b/projet_linea/bin/Jeu$1.class new file mode 100644 index 0000000..4308d58 Binary files /dev/null and b/projet_linea/bin/Jeu$1.class differ diff --git a/projet_linea/bin/Jeu.class b/projet_linea/bin/Jeu.class new file mode 100644 index 0000000..31a7eb4 Binary files /dev/null and b/projet_linea/bin/Jeu.class differ diff --git a/projet_linea/bin/Ligne.class b/projet_linea/bin/Ligne.class new file mode 100644 index 0000000..5455744 Binary files /dev/null and b/projet_linea/bin/Ligne.class differ diff --git a/projet_linea/bin/LineaAppli.class b/projet_linea/bin/LineaAppli.class new file mode 100644 index 0000000..527e120 Binary files /dev/null and b/projet_linea/bin/LineaAppli.class differ diff --git a/projet_linea/bin/Niveau.class b/projet_linea/bin/Niveau.class new file mode 100644 index 0000000..b7f0f89 Binary files /dev/null and b/projet_linea/bin/Niveau.class differ diff --git a/projet_linea/bin/NiveauxDataConnect.class b/projet_linea/bin/NiveauxDataConnect.class new file mode 100644 index 0000000..15b6ec8 Binary files /dev/null and b/projet_linea/bin/NiveauxDataConnect.class differ diff --git a/projet_linea/bin/ObjetGraphique.class b/projet_linea/bin/ObjetGraphique.class new file mode 100644 index 0000000..5843ecf Binary files /dev/null and b/projet_linea/bin/ObjetGraphique.class differ diff --git a/projet_linea/bin/Segment.class b/projet_linea/bin/Segment.class new file mode 100644 index 0000000..7a930f0 Binary files /dev/null and b/projet_linea/bin/Segment.class differ diff --git a/projet_linea/bin/ZoneDessin.class b/projet_linea/bin/ZoneDessin.class new file mode 100644 index 0000000..e600c09 Binary files /dev/null and b/projet_linea/bin/ZoneDessin.class differ diff --git a/projet_linea/bin/bddInit.class b/projet_linea/bin/bddInit.class new file mode 100644 index 0000000..22b4134 Binary files /dev/null and b/projet_linea/bin/bddInit.class differ diff --git a/projet_linea/bin/images/ciel.jpeg b/projet_linea/bin/images/ciel.jpeg new file mode 100644 index 0000000..c1b95ae Binary files /dev/null and b/projet_linea/bin/images/ciel.jpeg differ diff --git a/projet_linea/bin/images/espace.jpg b/projet_linea/bin/images/espace.jpg new file mode 100644 index 0000000..faca99a Binary files /dev/null and b/projet_linea/bin/images/espace.jpg differ diff --git a/projet_linea/bin/images/montagnes.jpg b/projet_linea/bin/images/montagnes.jpg new file mode 100644 index 0000000..a68840a Binary files /dev/null and b/projet_linea/bin/images/montagnes.jpg differ diff --git a/projet_linea/bin/images/volcan.jpg b/projet_linea/bin/images/volcan.jpg new file mode 100644 index 0000000..3d9bd0c Binary files /dev/null and b/projet_linea/bin/images/volcan.jpg differ diff --git a/projet_linea/lib/sqlite-jdbc-3.51.2.0.jar b/projet_linea/lib/sqlite-jdbc-3.51.2.0.jar new file mode 100644 index 0000000..822a5c1 Binary files /dev/null and b/projet_linea/lib/sqlite-jdbc-3.51.2.0.jar differ diff --git a/projet_linea/score.db b/projet_linea/score.db new file mode 100644 index 0000000..047f29d Binary files /dev/null and b/projet_linea/score.db differ diff --git a/projet_linea/src/BonusMalus.java b/projet_linea/src/BonusMalus.java new file mode 100644 index 0000000..0932b83 --- /dev/null +++ b/projet_linea/src/BonusMalus.java @@ -0,0 +1,48 @@ +import java.awt.Color; +import java.awt.Graphics; + +public class BonusMalus extends ObjetGraphique { + + public boolean estBonus; + public boolean actif = true; // Permet de le faire disparaître une fois ramassé + public int taille = 15; + + public BonusMalus(double startX, double startY, boolean bonus) { + this.x = startX; + this.y = startY; + this.estBonus = bonus; + } + + @Override + void Afficher(Graphics g) { + if (!actif) return; // S'il a été ramassé, on ne le dessine plus + + if (estBonus) { + g.setColor(Color.green); // Carré jaune (Bonus) + g.fillRect((int)x, (int)y - taille / 2, taille, taille); + } else { + g.setColor(Color.red); // Triangle rouge (Malus) + int[] xPoints = {(int)x, (int)x + taille / 2, (int)x + taille}; + int[] yPoints = {(int)y + taille / 2, (int)y - taille / 2, (int)y + taille / 2}; + g.fillPolygon(xPoints, yPoints, 3); + } + } + + @Override + void Animer() { + this.x -= 5; // Il se déplace vers la gauche à la même vitesse que la ligne + } + + // Vérifie si le joueur touche l'objet + public boolean estTouche(Cercle c) { + if (!actif) return false; + + // Calcul de la distance entre le centre de l'objet et le centre du joueur + double centreItemX = x + taille / 2.0; + double centreItemY = y; + double distance = Math.sqrt(Math.pow(centreItemX - c.x, 2) + Math.pow(centreItemY - c.y, 2)); + + // Si la distance est inférieure au rayon du joueur, c'est touché ! + return distance < (c.getRayon() + taille / 2.0); + } +} \ No newline at end of file diff --git a/projet_linea/src/Cercle.java b/projet_linea/src/Cercle.java new file mode 100644 index 0000000..36a7cec --- /dev/null +++ b/projet_linea/src/Cercle.java @@ -0,0 +1,148 @@ +import java.awt.BasicStroke; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.geom.Arc2D; + +public class Cercle extends ObjetGraphique{ // il s'agit plutôt d'arcs de cercle + // Hérite de la classe ObjetGraphique + // Ne pas oublier qu'il y a des propriétés et méthodes reçues par l'héritage + + + //------------------------------------------------------------------------- + // PROPRIETES + //------------------------------------------------------------------------- + protected double rayon = 30; + protected double depY = 0; // déplacement + + // début et fin de l'arc, en degrés + protected double debut = 0; + protected double fin = 360; + + // Est-ce que le joueur est en train d'appuyer sur "up" + protected boolean montee = false; + + // Vitesse du cercle + protected double vitesse = -1.0; + + // Un pas pour l'application des forces, permet de régler + // un peu la jouabilité + protected double pas = 0.2; + + // Valeur de la force (norme) appliquée lorsque le joueur appuie sur up + protected double impulsion = 25; + + //plafond du cercle + protected static final double plafond = 0; + + //sol du cercle + protected double sol = 600; + //------------------------------------------------------------------------- + // METHODES + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // Constructeurs de la classe + //------------------------------------------------------------------------- + public Cercle(){ + x=400; + y=200; + } + + public Cercle(double debutArc, double finArc){ + x=400; + y=200; + debut = debutArc; + fin = finArc; + } + + + //------------------------------------------------------------------------- + // Méthode d'accès en lecture au rayon, peut être utile + // par exemple pour la classe qui vérifiera si la ligne passe dans le + // cercle + //------------------------------------------------------------------------- + public double getRayon(){ + return rayon; + } + + //------------------------------------------------------------------------- + // Méthode qui retourne la position du cercle en y + // (utile pour la classe qui vérifiera si la ligne passe dans le cercle) + //------------------------------------------------------------------------- + @Override + public double getY(){ + return y; + } + + //------------------------------------------------------------------------- + // Méthode qui note que up a été appuyée + // -> le booléen permet de ne plus être tributaire + // de la vitesse de répétition du clavier + //------------------------------------------------------------------------- + public void Monter(){ + montee = true; + } + + + //------------------------------------------------------------------------- + // Méthode qui note que up a été relâchée + //------------------------------------------------------------------------- + public void ArreterMonter(){ + montee = false; + } + + + + //------------------------------------------------------------------------- + // Redéfinition de la méthode Afficher, spécifiquement pour la classe + //------------------------------------------------------------------------- + @Override + void Afficher(Graphics g) { + // choix de la couleur et de l'épaisseur + Graphics2D g2D = (Graphics2D) g; + g2D.setStroke(new BasicStroke(5.0f)); + g.setColor(this.couleur); + + // dessin de l'arc + g2D.draw(new Arc2D.Double(x-rayon/2, y-rayon, rayon, rayon*2, debut, fin, Arc2D.OPEN)); + } + + + //------------------------------------------------------------------------- + // Redéfinition de la méthode Animer, spécifiquement pour la classe + //------------------------------------------------------------------------- + @Override + void Animer() { + // pas est à prendre comme un "delta t" + + // chute libre + vitesse = vitesse + 9.81 * pas; + + // impulsion + if (montee==true) { + vitesse = vitesse - impulsion *pas; + } + + depY = 1/2 * 9.81 + vitesse * pas; + + if (depY<-10) { + depY=-10; + } + if (depY>10){ + depY =10; + } + + y+=depY; + verification_cercle_out(); + } + + // Méthode pour mettre un plafond et un sol au cercle + public void verification_cercle_out(){ + if(y < plafond || (y + rayon) >= sol ) { + vitesse = -vitesse; + } + } + + + +} diff --git a/projet_linea/src/GestionBDD.java b/projet_linea/src/GestionBDD.java new file mode 100644 index 0000000..4cf46fb --- /dev/null +++ b/projet_linea/src/GestionBDD.java @@ -0,0 +1,94 @@ +import java.sql.*; +import java.util.ArrayList; +import java.util.List; + +public class GestionBDD { + + private static final String URL = "jdbc:sqlite:score.db"; + + //connexion bdd + private static Connection connecter() throws SQLException { + return DriverManager.getConnection(URL); + } + + //creation de la table score a ca premiere execution + public static void creerTableSiAbsente() { + + String sql = """ + CREATE TABLE IF NOT EXISTS scores ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + score INTEGER NOT NULL, + date TEXT NOT NULL + ); + """; + + try (Connection connexion = connecter(); + Statement statement = connexion.createStatement()) { + + statement.execute(sql); + + } catch (SQLException e) { + e.printStackTrace(); + } + } + + // Ajouter un score a la fin de la partie + public static void ajouterScore(int score) { + + String sql = "INSERT INTO scores(score, date) VALUES(?, ?)"; + + try (Connection connexion = connecter(); + PreparedStatement requete = connexion.prepareStatement(sql)) { + + requete.setInt(1, score); + requete.setString(2, java.time.LocalDate.now().toString()); + + requete.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + } + + // Récupérer tous les scores + public static List recupererTousLesScores() { + + List listeScores = new ArrayList<>(); + + String sql = "SELECT score FROM scores ORDER BY date DESC"; + + try (Connection connexion = connecter(); + Statement statement = connexion.createStatement(); + ResultSet resultat = statement.executeQuery(sql)) { + + while (resultat.next()) { + listeScores.add(resultat.getInt("score")); + } + + } catch (SQLException e) { + e.printStackTrace(); + } + + return listeScores; + } + + // Récupérer le meilleur score + public static int recupererMeilleurScore() { + + String sql = "SELECT MAX(score) AS meilleur FROM scores"; + + try (Connection connexion = connecter(); + Statement statement = connexion.createStatement(); + ResultSet resultat = statement.executeQuery(sql)) { + + if (resultat.next()) { + return resultat.getInt("meilleur"); + } + + } catch (SQLException e) { + e.printStackTrace(); + } + + return 0; + } +} diff --git a/projet_linea/src/Jeu.java b/projet_linea/src/Jeu.java new file mode 100644 index 0000000..4ad8c5b --- /dev/null +++ b/projet_linea/src/Jeu.java @@ -0,0 +1,255 @@ +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.SwingUtilities; +import javax.swing.Timer; + +public class Jeu implements KeyListener, ActionListener{ + //------------------------------------------------------------------------- + // PROPRIETES + //------------------------------------------------------------------------- + + // Ecran : instance de ZoneDessin, qui contiendra tous les objets graphiques + // et les animera + protected ZoneDessin ecran = new ZoneDessin(); + + // Le cercle : en fait 2 demis-cercles, un qui passera sous la ligne + // un qui passera dessus + protected Cercle demiCercleAvant = new Cercle(90,-180); // celui qui est sur la ligne + protected Cercle demiCercleArriere = new Cercle(90,180); // celui qui est derrière la ligne + + // A FAIRE : ajouter les objets graphiques manquants, s'il y en a + protected Ligne laLigne = new Ligne(); // Ligne infinie du jeu + + // Timer : un objet qui émet des événements à un intervalle choisi, + // il sert à donner le pas de l'animation + protected Timer horloge; + + // Une variable qui contiendra le score + protected double score=0; + + // un label qui servira à afficher le score + protected JLabel labScore; + + protected JLabel labTriche; + + protected boolean jeuCommence = false; + + protected boolean modeTriche = false; + + //------------------------------------------------------------------------- + // METHODES + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // Constructeur de la classe + //------------------------------------------------------------------------- + public Jeu(){ + // Gestion du score : a réactiver en fin de TP, inutile au début + ecran.setLayout(null); + + labScore = new JLabel(); + labScore.setText("

score : 0

"); + labScore.setBounds(20, 0, 200, 50); + ecran.add(labScore); + + labTriche = new JLabel(); + labTriche.setText("

Mode de triche activé

"); + labTriche.setBounds(600, 0, 200, 50); // Placé en haut à droite (la fenêtre fait 800 de large) + labTriche.setVisible(false); // Caché par défaut au lancement + ecran.add(labTriche); + } + + + //------------------------------------------------------------------------- + // Méthodes qu'il faut implémenter pour être + // conforme à un KeyListener + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // Appui sur une touche + // -> l'événement est émis lorsqu'on appuie, puis selon le rythme de + // répétition du clavier + //------------------------------------------------------------------------- + @Override + public void keyPressed(KeyEvent e){ + // keyCode 38 : up + // keyCode 40 : down + int keyCode = e.getKeyCode(); + + if (keyCode==38){ // touche "flèche vers le haut" + // On demande aux deux demi-cercle de "monter" + demiCercleAvant.Monter(); + demiCercleArriere.Monter(); + } + + if(keyCode==32){//touche espace + modeTriche =!modeTriche; + labTriche.setVisible(modeTriche); //afficher ou cacher le label + } + } + + //------------------------------------------------------------------------- + // Relâchement de la touche + //------------------------------------------------------------------------- + @Override + public void keyReleased(KeyEvent e){ + // keyCode 38 : up + // keyCode 40 : down + int keyCode = e.getKeyCode(); + + if (keyCode==38){ + // On demande aux deux demi-cercle "d'arrêter de monter" + demiCercleAvant.ArreterMonter(); + demiCercleArriere.ArreterMonter(); + } + } + + //------------------------------------------------------------------------- + // Une méthode que nous n'utilisons pas + //------------------------------------------------------------------------- + @Override + public void keyTyped(KeyEvent e) { + // TODO Auto-generated method stub + + } + + //------------------------------------------------------------------------- + // Démarrage du jeu : + // création de diverses instances et + //------------------------------------------------------------------------- + public void demarrer(){ + // Création d'une fenêtre + JFrame fenetre = new JFrame(); + + // A FAIRE : + // placer dans l'instance de l'écran tous les objets graphiques nécessaires + // par exemple : ecran.ajouterObjet(demiCerleArriere); + this.ecran.ajouterObjet(demiCercleArriere); + this.ecran.ajouterObjet(laLigne); + this.ecran.ajouterObjet(demiCercleAvant); + + + // on indique que c'est le jeu qui traitera les appuis sur une touche + ecran.addKeyListener(this); + ecran.setFocusable(true); + fenetre.setContentPane(ecran); + fenetre.pack(); + fenetre.setLocation(100, 100); + fenetre.setVisible(true); + // s'assurer que l'écran reçoit le focus clavier + ecran.requestFocusInWindow(); + fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // 🔹 Création du bouton Voir Scores + javax.swing.JButton boutonScores = new javax.swing.JButton("Voir mes scores"); + boutonScores.setBackground(Color.BLACK); // Couleur fond + boutonScores.setForeground(Color.WHITE); // Couleur texte + //boutonScores.setFont(new Font("Arial", Font.BOLD, 14)); // Police + + // Position du bouton + boutonScores.setBounds(300, 20, 160, 30); + + // Action quand on clique + boutonScores.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + + java.util.List scores = GestionBDD.recupererTousLesScores(); + int meilleurScore = GestionBDD.recupererMeilleurScore(); + + StringBuilder message = new StringBuilder(); + message.append("Meilleur score : ").append(meilleurScore).append("\n\n"); + message.append("Tous les scores :\n"); + + for (int score : scores) { + message.append(score).append("\n"); + } + + javax.swing.JOptionPane.showMessageDialog( + fenetre, + message.toString(), + "Mes Scores", + javax.swing.JOptionPane.INFORMATION_MESSAGE + ); + } + }); + + // affichier le bouton à l'écran + ecran.setLayout(null); + ecran.add(boutonScores); + + // Création du timer + horloge = new Timer(40, this); + + //propriétés dont on aura besoin pour utiliser NiveauxDataConnect + //--------------------------------------------------------------------------------- + // C'est ici qu'on appelle NiveauxDataConnect pour initialiser la connexion à la base de données des niveaux + // On fera une synchronisation pour éviter que le jeu se fige + // pendant l'initialisation de la base de données, qui peut prendre un peu de temps + // On utilise un thread synchrone pour ne pas bloquer le thread principal du jeu + //-------------------------------------------------------------------------------- + // Initialisation de la BDD dans un thread séparé ; + // démarrer le timer quoiqu'il arrive pour ne pas figer l'UI + new Thread(() -> { + try { + NiveauxDataConnect niveau = new NiveauxDataConnect(); + System.out.println("Connexion réussie !!!"); + // démarrer le timer sur l'EDT même si l'initialisation BDD a échoué + SwingUtilities.invokeLater(() -> { + if (horloge != null && !horloge.isRunning()) { + horloge.start(); + } + }); + } catch (Exception ex) { + ex.printStackTrace(); + System.err.println("Erreur lors de l'initialisation de la connexion à la base de données : " + ex.getMessage()); + } + }).start(); + + + // A FAIRE : + // donner la couleur des 2 demi-cercles, par exemple : demiCerleArriere.setCouleur(new Color(0.8f,0.0f,0.0f)); + demiCercleArriere.setCouleur(new Color(26, 95, 161)); + demiCercleAvant.setCouleur(new Color(26, 95, 161)); + } + + + //------------------------------------------------------------------------------------------------ + // Méthode appelée lorsqu'un événement timer se produit + // -> C'est ici que la loqique et l'animation du jeu sont traitées + // -> C'est ici que la vérification de la collision entre la ligne et le cercle doit être faite + //------------------------------------------------------------------------------------------------ + @Override + public void actionPerformed(ActionEvent e) { + this.ecran.traiterBoucleAnimation(); + boolean verification = this.laLigne.estDansCercle(this.demiCercleAvant); + + if(verification){ + // Ajouter les points continuellement tant que le segment est vert (cyan) + this.score += 5; + this.jeuCommence = true; + }else{ + //------------------------------------------------------------------------------------------------------------------- + // A FAIRE: Le jeu peut s'arrêter si la ligne n'est pas dans le cercle + // NB: Le jeu commence quand la ligne est dans le cercle + // Au début le ligne n'est pas dans le cercle car la ligne est à droite du cercle, et elle se déplace vers la gauche + //------------------------------------------------------------------------------------------------------------------- + if (this.laLigne.getSegCourant()!=null && !this.modeTriche) { // Le jeu s'arrête si le joueur n'a pas traversé la première ligne + this.horloge.stop(); // 1. Arrêter le temps + this.ecran.partiePerdue = true; // 2. Signaler à l'écran + this.ecran.repaint(); // 3. Forcer l'affichage du texte + + GestionBDD.ajouterScore((int)this.score);// enregistrement du score dans la base de donne + } + } + + labScore.setText("

score : " + this.score + "

"); + + } + +} diff --git a/projet_linea/src/Ligne.java b/projet_linea/src/Ligne.java new file mode 100644 index 0000000..93d9bfa --- /dev/null +++ b/projet_linea/src/Ligne.java @@ -0,0 +1,134 @@ +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.util.ArrayList; + +public class Ligne extends ObjetGraphique{// Hérite de la classe ObjetGraphique + // Ne pas oublier qu'il y a des propriétés et méthodes reçues par l'héritage + + //------------------------------------------------------------------------- + // PROPRIETES + //------------------------------------------------------------------------- + + // nb de Segments qui composent la ligne + protected int nbSegments = 400; + + // position du cercle, pour déterminer quel est le segment courant + protected double xCercle = 400; // à modifier + + // segment qui se trouve au niveau du cercle : on le mémorise pour accélérer les traitements + protected Segment SegCourant; + + // Propriété listes de segements: Une ligne est constitué de plusieurs segments. + // Stockage des segments afin de pouvoir les afficher et les animer plus tard + protected ArrayList listeSegments = new ArrayList<>(); + + + //------------------------------------------------------------------------- + // METHODES + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // Constructeur de la classe + //------------------------------------------------------------------------- + public Ligne(){ + // Valeurs initiales pour la position de la Ligne + double x = 800; + double y = 200; + double dx,dy; + + // Création de la liste de segments qui composent la ligne + Segment s; + for (int i=0; i= s.x) && ( xCercle <= (s.x + s.xLong) ) ){ + this.SegCourant = s; + } + }else{ + if( (this.SegCourant.x + this.SegCourant.xLong) < xCercle ){ + if( (s.x <= xCercle) && ((s.x + s.xLong) >= xCercle) ){ + this.SegCourant = s; + } + } + } + } + + } + + //------------------------------------------------------------------------- + // Redéfinition de la méthode Animer, spécifiquement pour la classe Ligne + //------------------------------------------------------------------------- + @Override + public void Animer() { + + // Principe : + // on parcourt tous les segments et on décale chacun de 10 pixels (par exemple) + // vers la gauche + // On modifiera cette méthode en fonction du niveau de jeu + for(Segment s: this.listeSegments){ + s.x -= 5; + } + + } + + //------------------------------------------------------------------------- + // Méthode qui vérifie si la ligne est dans le cercle + // Principe: + // 1- On détermine la hauteur du point du segment qui se trouve au niveau du cercle + // 2- On calcule la distane entre ce point et le centre du cercle + // 3- On compare cette distance avec le rayon du cercle + //------------------------------------------------------------------------- + public boolean estDansCercle(Cercle c){ + boolean dansCercle = false; + if(this.SegCourant != null){ + // 1- On détermine la hauteur du point du segment qui se trouve au niveau du cercle + // En utilisant la formule de Thales + // Ce point se touve à la position xPoint = xCercle + double yPoint = this.SegCourant.y + (this.SegCourant.yLong / this.SegCourant.xLong) * (this.xCercle - this.SegCourant.x); + double xPoint = this.xCercle; + + // 2- On calcule la distance entre ce point et le centre du cercle + double distance = Math.sqrt(Math.pow(xPoint - c.x, 2) + Math.pow(yPoint - c.y, 2)); + + // 3- On compare cette distance avec le rayon du cercle + if(distance <= c.rayon){ + this.SegCourant.setCouleur(Color.GREEN); + dansCercle = true; + }else{ + this.SegCourant.setCouleur(Color.RED); + dansCercle = false; + + } + } + return dansCercle; + } + public Segment getSegCourant() { + return this.SegCourant; + } +} diff --git a/projet_linea/src/LineaAppli.java b/projet_linea/src/LineaAppli.java new file mode 100644 index 0000000..9c8ee13 --- /dev/null +++ b/projet_linea/src/LineaAppli.java @@ -0,0 +1,16 @@ + +public class LineaAppli { + //------------------------------------------------------------------------- + // Classe de base de l'application, rien à modifier ici + //------------------------------------------------------------------------- + public static void main(String[] arg) { + + GestionBDD.creerTableSiAbsente(); + + Jeu jeu = new Jeu(); + + jeu.demarrer(); + + } + +} diff --git a/projet_linea/src/Niveau.java b/projet_linea/src/Niveau.java new file mode 100644 index 0000000..59c7c94 --- /dev/null +++ b/projet_linea/src/Niveau.java @@ -0,0 +1,51 @@ +public class Niveau { + // Propriétés d'un niveau + private int id; + private String nom; + private int vitesseLigne; + private int nbSegments; + private String image; + private int multiplicateurScore; + private String couleurCercle; + + // Constructeur de la classe Niveau + public Niveau(int id, String nom, int vitesseLigne, int nbSegments, String image, int multiplicateurScore, String couleurCercle) { + this.id = id; + this.nom = nom; + this.vitesseLigne = vitesseLigne; + this.nbSegments = nbSegments; + this.image = image; + this.multiplicateurScore = multiplicateurScore; + this.couleurCercle = couleurCercle; + } + + // Getters pour les propriétés du niveau + public int getId() { + return id; + } + + public String getNom() { + return nom; + } + + public int getVitesseLigne() { + return vitesseLigne; + } + + public int getNbSegments() { + return nbSegments; + } + + public String getImage() { + return image; + } + + public int getMultiplicateurScore() { + return multiplicateurScore; + } + + public String getCouleurCercle() { + return couleurCercle; + } + +} diff --git a/projet_linea/src/NiveauxDataConnect.java b/projet_linea/src/NiveauxDataConnect.java new file mode 100644 index 0000000..59739f1 --- /dev/null +++ b/projet_linea/src/NiveauxDataConnect.java @@ -0,0 +1,160 @@ +import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + + +// Cette classe est celle qui gère la connexion à la base de données Niveaux.db +public class NiveauxDataConnect { + //Création d'une variable de connexion à la base de données + private static final String url = "jdbc:sqlite:Niveaux.db"; + private static boolean tablesCreees = false; // Variable pour vérifier si les tables ont été créées + + + + // ------------- Constructeur de la classe ------------------------ + // Il initialise la connexion à la base de données + // Il crée la table niveau si elle n'existe pas déjà + // Il insérer les niveaux dans la table niveau directement + // Pour éviter à le faire à chaque fois que le jeu est lancé + // NB : Le fichier de la base de donnée est dans le .jar + // Il est nécessaire de l'initialiser afin de pouvoir le lire et écrire dessus + // Car dans la .jar il est en lecture seule + // Il faut donc le copier dans un endroit où il peut être modifié, par exemple dans le dossier du projet + // ---------------------------------------------------------------- + public NiveauxDataConnect() throws ClassNotFoundException, SQLException { + // Initialisation de la connexion à la base de données + Connection conn = getConnection(); + if (conn != null) { + System.out.println("Connexion à la base de données réussie !"); + } else { + System.out.println("Connexion échouée !"); + } + } + + + // ------------------------------------------------------------------------- + // Méthode de connexion à la base de données Niveaux.db + // ------------------------------------------------------------------------- + public static Connection getConnection(){ + // On vérifiera si la BDD est déjà créé et possède déjà des données à l'intérieur + // On devra ainsi l'extraire depuis le .jar + boolean baseExiste = bddInit.init(); + try{ + Connection conn = DriverManager.getConnection(url); + System.out.println("Connexion à la base de données réussie !"); + if(!baseExiste){ + // Vérifier si les tables ont déjà été créées pour éviter de les recréer à chaque connexion + if (!tablesCreees) { + // Créer la table niveau si elle n'existe pas déjà + CreerTableNiveaux(conn); + tablesCreees = true; // Marquer les tables comme créées + // Insérer les niveaux dans la table niveau + insererNiveau(conn); + } + } + + return conn; + }catch(Exception e){ + e.printStackTrace(); + } + + return null; + } + + + // ------------------------------------------------------------------------- + // Méthode pour créer la table Niveaux si elle n'existe pas déjà + // ------------------------------------------------------------------------- + private static void CreerTableNiveaux(Connection conn) { + + String sql = "CREATE TABLE IF NOT EXISTS niveau( " + + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + + "nom TEXT NOT NULL, " /*nom du niveau*/ + + "vitesse_ligne INTEGER NOT NULL, " /*vitesse de la ligne*/ + + "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 */ + +");" ; + + try (Statement stmt = conn.createStatement()) { + stmt.execute(sql); + stmt.close(); + } catch (SQLException e) { + System.err.println("Erreur lors de la création de la table Niveaux : " + e.getMessage()); + System.out.println("Connexion échouée !"); + e.printStackTrace(); + } + + } + + + // ------------------------------------------------------------------------- + // Méthode pour insérer les niveaux dans la base de données + // Les niveaux sont connus à l'avance et sont insérés directement + // dans la base de données pour éviter de les insérer à chaque fois que + // le jeu est lancé + // --------------------------------Niveau 1 -------------------------------- + // nom = "Facile", vitesse_ligne = 5, nb_segments = 50, image = "images\ciel.jpeg", multiplicateur_score = 1, couleur_cercle = "bleu" + // --------------------------------Niveau 2 -------------------------------- + // nom = "intermédaire", vitesse_ligne = 7, nb_segments = 100, image = "images\montagnes.jpg", multiplicateur_score = 2, couleur_cercle = "gris" + // --------------------------------Niveau 3 -------------------------------- + // nom = "Difficile", vitesse_ligne = 9, nb_segments = 100, image = "images\volcan.jpg", multiplicateur_score = 3, couleur_cercle = "marron" + // --------------------------------Niveau 4 -------------------------------- + // nom = "Ultime", vitesse_ligne = 10, nb_segments = 150, image = "images\espace.jpg", multiplicateur_score = 4, couleur_cercle = "violet" + // ------------------------------------------------------------------------- + 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', 1, '#0000FF');"; + + String query2 = "INSERT INTO niveau(nom, vitesse_ligne, nb_segments, image, multiplicateur_score, couleur_cercle) " + + "VALUES('Intermédiaire', 7, 100, 'images/montagnes.jpg', 2, '#808080');"; + String query3 = "INSERT INTO niveau(nom, vitesse_ligne, nb_segments, image, multiplicateur_score, couleur_cercle) " + + "VALUES('Difficile', 9, 100, 'images/volcan.jpg', 3, '#8B4513');"; + String query4 = "INSERT INTO niveau(nom, vitesse_ligne, nb_segments, image, multiplicateur_score, couleur_cercle) " + + "VALUES('Ultime', 10, 150, 'images/espace.jpg', 4, '#9400D3');"; + + try (Statement stmt = conn.createStatement()) { + stmt.execute(query1); + stmt.execute(query2); + stmt.execute(query3); + stmt.execute(query4); + tablesCreees = true ; + stmt.close(); + } catch (SQLException e) { + System.err.println("Erreur lors de l'insertion des niveaux : " + e.getMessage()); + } + } + + // ------------------------------------------------------------------------- + // Méthode pour récupérer les niveaux depuis la base de données + // Elle retourne un niveau en fonction de son id + // ------------------------------------------------------------------------- + public static Niveau recupererNiveau(Connection conn, int id) { + Niveau niveauRecup = null; + String sql = "SELECT * FROM niveau WHERE id = ?;"; + + try (Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(sql)) { + while (rs.next()) { + int id1 = rs.getInt("id"); + String nom = rs.getString("nom"); + int vitesse_ligne = rs.getInt("vitesse_ligne"); + int nb_segments = rs.getInt("nb_segments"); + 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); + } + + } catch (SQLException e) { + System.err.println("Erreur lors de la récupération des niveaux : " + e.getMessage()); + } + return niveauRecup; + } + + +} diff --git a/projet_linea/src/ObjetGraphique.java b/projet_linea/src/ObjetGraphique.java new file mode 100644 index 0000000..6e2a0df --- /dev/null +++ b/projet_linea/src/ObjetGraphique.java @@ -0,0 +1,54 @@ +import java.awt.Color; +import java.awt.Graphics; + +//------------------------------------------------------------------------- +// ObjetGraphique : +// classe abstraite, qui ne peut donc pas être instanciée +//------------------------------------------------------------------------- +abstract class ObjetGraphique { + //------------------------------------------------------------------------- + // PROPRIETES + //------------------------------------------------------------------------- + + // Position + protected double x; + protected double y; + + protected Color couleur = new Color(0.0f,0.2f,0.2f); + + + //------------------------------------------------------------------------- + // METHODES + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // Constructeur : rien à faire + //------------------------------------------------------------------------- + public ObjetGraphique(){ + + } + + //------------------------------------------------------------------------- + // Les méthodes d'affichage et d'animation : abstraites + //------------------------------------------------------------------------- + abstract void Afficher(Graphics g); + abstract void Animer(); + + + + //------------------------------------------------------------------------- + // Quelques méthodes d'accès + //------------------------------------------------------------------------- + public double getX(){ + return x; + } + + public double getY(){ + return y; + } + + + public void setCouleur(Color c){ + couleur = c; + } +} diff --git a/projet_linea/src/Segment.java b/projet_linea/src/Segment.java new file mode 100644 index 0000000..9dd6abf --- /dev/null +++ b/projet_linea/src/Segment.java @@ -0,0 +1,56 @@ +import java.awt.Graphics; + +public class Segment extends ObjetGraphique { // Hérite de la classe ObjetGraphique + // Ne pas oublier qu'il y a des propriétés et méthodes reçues par l'héritage + + //------------------------------------------------------------------------- + // PROPRIETES + //------------------------------------------------------------------------- + + protected double xLong; + protected double yLong; + + + //------------------------------------------------------------------------- + // METHODES + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // Constructeurs de la classe + //------------------------------------------------------------------------- + public Segment(){ + x = 0; + y = 0; + xLong = 50; + yLong = 50; + } + + public Segment(double xx, double yy, double xxLong, double yyLong){ + x = xx; + y = yy; + xLong = xxLong; + yLong = yyLong; + } + + //------------------------------------------------------------------------- + // Redéfinition de la méthode Afficher, spécifiquement pour la classe + //------------------------------------------------------------------------- + @Override + void Afficher(Graphics g) { + // on définit la couleur + g.setColor(this.couleur); + + // on dessine le segment (on pourrait faire mieux...) + g.drawLine((int)Math.round(x), (int)Math.round(y), (int)Math.round(x + xLong), (int)Math.round(y+yLong)); + } + + //------------------------------------------------------------------------- + // Redéfinition de la méthode Animer, spécifiquement pour la classe + //------------------------------------------------------------------------- + @Override + void Animer() { + + } + + +} diff --git a/projet_linea/src/ZoneDessin.java b/projet_linea/src/ZoneDessin.java new file mode 100644 index 0000000..93f2740 --- /dev/null +++ b/projet_linea/src/ZoneDessin.java @@ -0,0 +1,114 @@ +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.util.ArrayList; +import javax.swing.JPanel; + +public class ZoneDessin extends JPanel { // hérite d'une classe du frameWork standard + + private static final long serialVersionUID = 1L; + + //------------------------------------------------------------------------- + // PROPRIETES + //------------------------------------------------------------------------- + public boolean partiePerdue = false; + // un booleen qui permet d'arreter l'animation (suspendre) + protected boolean estArrete = false; + + // Une liste d'objets graphique + // Pour permettre à traiterBoucleAnimation() de parcourir les objets sans distinction pour les animer + protected ArrayList listeObjets = new ArrayList<>(); + + //------------------------------------------------------------------------- + // METHODES + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // Constructeur de la classe + //------------------------------------------------------------------------- + public ZoneDessin(){ + // on prépare la zone d'affichage + setLayout(new BorderLayout()); + setPreferredSize(new Dimension(800, 600)); + setBackground(new Color(220,170,0)); + } + + + //------------------------------------------------------------------------- + // Ajout d'un objet graphique à la zonde de dessin + //------------------------------------------------------------------------- + public void ajouterObjet(ObjetGraphique unObjet) { + this.listeObjets.add(unObjet); + } + + + //------------------------------------------------------------------------- + // Mettre en pause et redémarrer + //------------------------------------------------------------------------- + public void arreter(){ + estArrete = true; + } + + public void demarrer(){ + estArrete = false; + } + + + //------------------------------------------------------------------------- + // Boucle d'animation : + // - appelée par exemple 25 fois par seconde + // - à chaque appel : + // - on anime (déplace) chaque objet + // - on redessine tout : appel à paintComponent, déclenché par repaint + //------------------------------------------------------------------------- + public void traiterBoucleAnimation(){ + if (estArrete==true) { + return; + } + + // 1. on déplace chaque objet graphique + // A FAIRE : décommenter lorsque cela devienda exécutable, et compléter + + for (ObjetGraphique obj : listeObjets){ + // A FAIRE : demander à obj de s'animer + obj.Animer(); + } + + + + // 2. on demande à redessiner, ce qui déclenchera automatiquement + // l'appel à la méthode paintComponent, qui est ci-dessous + repaint(); + } + + + //------------------------------------------------------------------------- + // Dessin, déclenché par le repaint() de la méthode ci-dessus + //------------------------------------------------------------------------- + public void paintComponent(Graphics g) { + // On demande à la super-classe (JPanel) de se redessiner + super.paintComponent(g); + + // Puis on ajoute ce qui est spécifique à la classe + + // on indique qu'il faut de l'antialiasing + Graphics2D g2D = (Graphics2D) g; + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); + + // à compléter + for(ObjetGraphique obj: listeObjets){ + obj.Afficher(g); //Chaque objet se dessine lui-même + } + if (this.partiePerdue) { + g.setColor(Color.RED); + g.setFont(new java.awt.Font("Arial", java.awt.Font.BOLD, 50)); + g.drawString("GAME OVER", 250, 300); + } + } + +} + + diff --git a/projet_linea/src/bddInit.class b/projet_linea/src/bddInit.class new file mode 100644 index 0000000..7ed680e Binary files /dev/null and b/projet_linea/src/bddInit.class differ diff --git a/projet_linea/src/bddInit.java b/projet_linea/src/bddInit.java new file mode 100644 index 0000000..23a5419 --- /dev/null +++ b/projet_linea/src/bddInit.java @@ -0,0 +1,31 @@ + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; + +// Cette classe permet d'extraire la base de données depuis le .jar si elle existe déjà +public class bddInit { + public static boolean init(){ + boolean existe = false; + File dbSource = new File("Niveaux.db"); // base de données originales + File dbDest = new File("./Niveaux.db"); // Copie dans le répertoire courant + + try { + if(dbSource.exists()){ + System.out.println("Base existante trouvée"); + // Copie et écrase de l'ancienne si elle existe + Files.copy(dbSource.toPath(), dbDest.toPath(), StandardCopyOption.REPLACE_EXISTING ); + System.out.println("Base copiée dans le répertoire courant."); + existe = true; + }else{ + System.out.println("Base inexistante. Elle sera créée"); + existe = false; + } + } catch (IOException e) { + e.printStackTrace(); + } + return existe; + + } +} diff --git a/projet_linea/src/images/ciel.jpeg b/projet_linea/src/images/ciel.jpeg new file mode 100644 index 0000000..c1b95ae Binary files /dev/null and b/projet_linea/src/images/ciel.jpeg differ diff --git a/projet_linea/src/images/espace.jpg b/projet_linea/src/images/espace.jpg new file mode 100644 index 0000000..faca99a Binary files /dev/null and b/projet_linea/src/images/espace.jpg differ diff --git a/projet_linea/src/images/montagnes.jpg b/projet_linea/src/images/montagnes.jpg new file mode 100644 index 0000000..a68840a Binary files /dev/null and b/projet_linea/src/images/montagnes.jpg differ diff --git a/projet_linea/src/images/volcan.jpg b/projet_linea/src/images/volcan.jpg new file mode 100644 index 0000000..3d9bd0c Binary files /dev/null and b/projet_linea/src/images/volcan.jpg differ diff --git a/projet_linea/src/tempCodeRunnerFile.java b/projet_linea/src/tempCodeRunnerFile.java new file mode 100644 index 0000000..e69de29