package linea; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.Timer; public class Jeu implements KeyListener, ActionListener, MouseListener { // ------------------------------------------------------------------------- // 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 lili = new Ligne(); // 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 = 1; // un label qui servira à afficher le score protected JLabel labScore; protected int compteurFrames = 0; protected boolean enCollision = false; protected boolean estGameOver = false; protected JLabel labGameOver; protected int compteurInvincible = 0; // menu et fenetre protected JFrame fenetre; protected JPanel panneauMenu; protected JTextField champPseudo; protected String pseudo = ""; // ------------------------------------------------------------------------- // METHODES // ------------------------------------------------------------------------- // ------------------------------------------------------------------------- // Constructeur de la classe // ------------------------------------------------------------------------- public Jeu() { // Gestion du score : a réactiver en fin de TP, inutile au début labScore = new JLabel(); labScore.setForeground(Color.WHITE); labScore.setText("

" + (int) score + "

"); labScore.setBounds(20, 0, 200, 50); ecran.add(labScore); labGameOver = new JLabel("GAME OVER", SwingConstants.CENTER); labGameOver.setForeground(Color.WHITE); labGameOver.setFont(new Font("Arial", Font.BOLD, 40)); labGameOver.setBounds(0, 200, 800, 100); labGameOver.setVisible(false); ecran.add(labGameOver); // ecoute les clics de souris (pour le game over) ecran.addMouseListener(this); ecran.traiterBoucleAnimation(); } // ------------------------------------------------------------------------- // 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(); } } // ------------------------------------------------------------------------- // 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 fenetre = new JFrame("Linea"); // on affiche le menu en premier afficherMenu(); fenetre.setSize(800, 600); fenetre.setResizable(false); fenetre.setLocationRelativeTo(null); // centre la fenetre sur l'ecran fenetre.setVisible(true); fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } private void afficherMenu() { panneauMenu = new JPanel(); panneauMenu.setLayout(new BoxLayout(panneauMenu, BoxLayout.Y_AXIS)); panneauMenu.setBackground(new Color(15, 15, 35)); panneauMenu.setPreferredSize(new Dimension(800, 600)); // espace en haut panneauMenu.add(Box.createVerticalStrut(80)); // titre du jeu JLabel titre = new JLabel("LINEA"); titre.setAlignmentX(JLabel.CENTER_ALIGNMENT); titre.setForeground(new Color(0, 180, 255)); titre.setFont(new Font("Arial", Font.BOLD, 80)); panneauMenu.add(titre); // petit sous-titre JLabel sousTitre = new JLabel("esquive la ligne"); sousTitre.setAlignmentX(JLabel.CENTER_ALIGNMENT); sousTitre.setForeground(new Color(120, 120, 160)); sousTitre.setFont(new Font("Arial", Font.PLAIN, 18)); panneauMenu.add(sousTitre); panneauMenu.add(Box.createVerticalStrut(40)); // label pseudo JLabel labPseudo = new JLabel("pseudo"); labPseudo.setAlignmentX(JLabel.CENTER_ALIGNMENT); labPseudo.setForeground(new Color(180, 180, 200)); labPseudo.setFont(new Font("Arial", Font.PLAIN, 14)); panneauMenu.add(labPseudo); panneauMenu.add(Box.createVerticalStrut(8)); // champ de texte pour le pseudo champPseudo = new JTextField(15); champPseudo.setText(pseudo); // garde le pseudo prérempli s'il y en a un champPseudo.setMaximumSize(new Dimension(250, 40)); champPseudo.setFont(new Font("Arial", Font.PLAIN, 16)); champPseudo.setHorizontalAlignment(JTextField.CENTER); champPseudo.setBackground(new Color(30, 30, 60)); champPseudo.setForeground(Color.WHITE); champPseudo.setCaretColor(Color.WHITE); champPseudo.setBorder(BorderFactory.createLineBorder(new Color(0, 180, 255), 2, true)); champPseudo.setAlignmentX(JTextField.CENTER_ALIGNMENT); panneauMenu.add(champPseudo); panneauMenu.add(Box.createVerticalStrut(40)); // bouton jouer JButton boutonJouer = new JButton("JOUER"); styleBouton(boutonJouer, new Color(0, 130, 255)); boutonJouer.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { lancerPartie(); } }); panneauMenu.add(boutonJouer); panneauMenu.add(Box.createVerticalStrut(15)); // bouton classement JButton boutonClassement = new JButton("CLASSEMENT"); styleBouton(boutonClassement, new Color(100, 100, 150)); boutonClassement.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(fenetre, "TOP SCORES", "Classement", JOptionPane.INFORMATION_MESSAGE); } }); panneauMenu.add(boutonClassement); panneauMenu.add(Box.createVerticalStrut(15)); // bouton quitter JButton boutonQuitter = new JButton("QUITTER"); styleBouton(boutonQuitter, new Color(200, 50, 50)); boutonQuitter.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.exit(0); } }); panneauMenu.add(boutonQuitter); fenetre.setContentPane(panneauMenu); fenetre.revalidate(); fenetre.repaint(); } private void styleBouton(JButton btn, Color fond) { btn.setAlignmentX(JButton.CENTER_ALIGNMENT); btn.setFont(new Font("Arial", Font.BOLD, 18)); btn.setForeground(Color.WHITE); btn.setBackground(fond); btn.setFocusPainted(false); btn.setBorderPainted(false); btn.setCursor(new Cursor(Cursor.HAND_CURSOR)); btn.setMaximumSize(new Dimension(200, 45)); } private void lancerPartie() { // on recupere le pseudo pseudo = champPseudo.getText(); // A FAIRE : // placer dans l'instance de l'écran tous les objets graphiques nécessaires // par exemple : ecran.ajouterObjet(demiCercleArriere); ecran.ajouterObjet(lili); ecran.ajouterObjet(demiCercleAvant); demiCercleArriere.setCouleur(new Color(0.0f, 0.4f, 0.0f)); demiCercleAvant.setCouleur(new Color(0.0f, 0.5f, 0.0f)); // on indique que c'est le jeu qui traitera les appuis sur une touche ecran.addKeyListener(this); ecran.setFocusable(true); // on remplace le menu par l'ecran de jeu fenetre.setContentPane(ecran); fenetre.revalidate(); fenetre.repaint(); ecran.requestFocusInWindow(); // on reinitialise les valeurs de jeu score = 1; compteurFrames = 0; enCollision = false; estGameOver = false; compteurInvincible = 0; labGameOver.setVisible(false); ecran.demarrer(); // Démarrage du timer, qui rythmera l'animation if (horloge == null) { horloge = new Timer(40, this); } horloge.start(); // A FAIRE : demiCercleArriere.setCouleur(new Color(0.8f, 0.0f, 0.0f)); // donner la couleur des 2 demi-cercles, par exemple : // demiCerleArriere.setCouleur(new Color(0.8f,0.0f,0.0f)); } // ------------------------------------------------------------------------- // Méthode appelée lorsqu'un événement timer se produit // ------------------------------------------------------------------------- @Override public void actionPerformed(ActionEvent e) { // si c'est game over, on arrete juste l'animation et on attend le clic if (estGameOver == true) { return; } ecran.traiterBoucleAnimation(); compteurFrames = compteurFrames + 1; if (compteurFrames >= 25) { score = score + 1; compteurFrames = 0; } if (compteurInvincible < 75) { compteurInvincible = compteurInvincible + 1; } else { if (demiCercleArriere.VerifierCollision(lili)) { if (enCollision == false) { score = score - 5; enCollision = true; } } else { enCollision = false; } } if (score <= 0) { score = 0; estGameOver = true; ecran.arreter(); labGameOver.setVisible(true); } labScore.setText("

" + (int) score + "

"); demiCercleArriere.ResterDansLigne(lili); demiCercleAvant.ResterDansLigne(lili); } private void retourMenu() { // on arrete le timer du jeu if (horloge != null) { horloge.stop(); } // on recrée une nouvelle ligne propre pour la prochaine partie lili = new Ligne(); demiCercleAvant.y = 200; demiCercleAvant.vitesse = -1.0; demiCercleArriere.y = 200; demiCercleArriere.vitesse = -1.0; ecran.viderObjets(); // on retourne au menu principal afficherMenu(); } // ------------------------------------------------------------------------- // événements souris (pour revenir au menu apres game over) // ------------------------------------------------------------------------- @Override public void mouseClicked(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { if (estGameOver == true) { retourMenu(); } } @Override public void mouseReleased(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } }