Bonjour,

Je rencontre un problème dans l’exécution du code de mon jeu de type tower-defense.

Mon problème est que lorsque je compile mon code, les cases ne s'affichent pas automatiquement. Je suis obligé de déplacer mon curseur sur chaque case pour les afficher, de même lorsqu'une fenêtre de dialogue s'affiche, les cases derrières elles partent et je dois redéplacer le curseur sur elles pour les afficher.

J'ai tenté plusieurs choses en essayant d’intégrer un invokelater pour voir si le problème venait du temps de chargement, j'ai utilisé des fonctions repaint() et modifié l'ordre de mon code, mais rien n'y fait j'ai toujours ce problème.

Quelqu'un saurait-il m'indiquer comment procéder ?

Voici les classes qui semblent poser problème :

Classe Fenetre :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
import java.awt.*;
 
import javax.swing.*;
 
import java.awt.event.*;
 
public class Fenetre extends JFrame
{
    private static final long serialVersionUID = 1L;
 
    public static Case[][] cases;
    public static boolean treve = false;
    public static char vie = 'a';
    JMenuBar menuBar = new JMenuBar();
    JMenu menu = new JMenu("Menu");
    JMenuItem aide = new JMenuItem("Aide");
    JMenuItem fermer = new JMenuItem("Fermer");
 
    public Fenetre()
    {    
        super("Tower Defense");    
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JFrame.setDefaultLookAndFeelDecorated(true);
        this.setPreferredSize(new Dimension(1200, 800));
        this.setResizable(false);
        this.menu.add(fermer);
        this.menu.add(aide);
        this.menuBar.add(menu);
        this.setJMenuBar(menuBar);
        fermer.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0) {
              System.exit(0);
            }        
          });
        aide.addActionListener(new ActionListener(){
            @SuppressWarnings("static-access")
            public void actionPerformed(ActionEvent arg0) {
              JOptionPane regle = new JOptionPane();
              regle.showMessageDialog(null,  "Caracteristiques des Defenseurs:\n\n- Ravageur: a une grande porté de dégat.\n- Saboteur: Donne des malus aux ennemies.\n- Attaquant: a un grand taux de dégat.\n\n\nCaracteristiques des Assaillants:\n\n- Mage Blanc: Peut se régénérer.\n- Mercenaire: Assailant standard avec plus de points de vie.\n- Ninja: Se déplace plus rapidement.\n ", "Aide", JOptionPane.INFORMATION_MESSAGE);
            }        
          });
        JPanel panBoutons = new JPanel();
        GridLayout gl = new GridLayout(13, 7);
        panBoutons.setLayout(gl);
        Fenetre.cases = TerrainDeJeu.creationTerrain();
        TerrainDeJeu.afficheTerrain(Fenetre.cases, panBoutons);
        this.add(panBoutons, BorderLayout.CENTER);
        JPanel goPan = new JPanel();
        JButton goBouton = new JButton("Commencer");
        goBouton.addActionListener(new ActionListener(){
            @SuppressWarnings("static-access")
            public void actionPerformed(ActionEvent arg0)
            {
                final int XP = 2;
                Fenetre.treve = false;
 
                if(Defenseur.temps == -1)
                {
                    ((JButton)arg0.getSource()).setText("Suivant");
                    JOptionPane jop1 = new JOptionPane();
                    jop1.showMessageDialog(null, "                             Bienvenue dans Tower Defense!\n Il vous faut placer deux défenseurs sur le terrain avant de commencer.\n      Veuillez cliquer sur un case du terrain pour ajouter un défenseur.", "Lancement du jeu", JOptionPane.INFORMATION_MESSAGE);
                }
 
                else
                {
                    if(Defenseur.temps %25 == 0 && Defenseur.temps != 0)
                    {
                        Fenetre.vie += 2  ; // grosse augmentation du niveau de vie des assaillants tous les 25 tours
                    }
 
                    if(Assaillant.assaillant.isEmpty())
                    {
                        // on remplit l'ArrayList D'assaillants = création d'une nouvelle vague
 
                        Fenetre.vie += 1;
                        Assaillant.numeroZero(); // sert à réinitialiser la variable statique 'numero' (et donc la variable id) de la classe Assaillant ---> sert pour plus loin dans le code...
 
                        for(int i = 0; i < 4; i++)
                        {
                            double type = Math.random();
 
                            if(type < 0.33)
                            {
                                Mercenaire mercenaire = new Mercenaire(Fenetre.vie);
                                Assaillant.assaillant.add(mercenaire);
                            }
 
                            if(type > 0.33 && type < 0.66)
                            {
                                MageBlanc mageBlanc = new MageBlanc(Fenetre.vie);
                                Assaillant.assaillant.add(mageBlanc);
                            }
 
                            if(type > 0.66)
                            {
                                Ninja ninja = new Ninja(Fenetre.vie);
                                Assaillant.assaillant.add(ninja);
                            }
                        }
 
                        if(Defenseur.temps != 0)
                        {
                            Fenetre.treve = true;
                            JOptionPane pause = new JOptionPane();
                            pause.showMessageDialog(null, "Phase de trève, vous possédez " + Defenseur.getBourse() + " gils, vous pouvez au choix:\n Acheter un défenseur (200 gils)\n Augmenter le niveau d'un défenseur (100 gils)\n Déblayer une case encombrée (100 gils)\n\n Pour reprendre le jeu, il vous suffit de cliquer sur 'suivant'", "Trève", JOptionPane.INFORMATION_MESSAGE);
                        }
                    }    
 
                    if(Fenetre.treve == false) // sinon, si ArrayList non vide,
                    {
                        Assaillant assFin = Assaillant.assaillantFin(Assaillant.assaillant, Fenetre.cases); // on regarde si un Assaillant s'apprête à se trouver sur la sortie lors du prochain déplacement.
 
                        if(Assaillant.assaillant.contains(assFin)) // si oui,
                        {
                            Fenetre.cases[assFin.getAbsX()][assFin.getOrdY()].setText(" "); // on met un "espace libre" à la place du caractère vie de l'assaillant,
                            Assaillant.assaillant.remove(assFin); // on le supprime de l'ArrayList,
                            Defenseur.ptsDeVieJoueur -= 1; // et on retire 1 point de vie au joueur.
                            if(Defenseur.ptsDeVieJoueur <= 0) // si plus de points de vie, on sort la boucle de condition 'tant que points de vie joueur > 0'
                            {
                                JOptionPane perdu = new JOptionPane();
                                perdu.showMessageDialog(null, "   Vous avez perdu!", "Game Over", JOptionPane.INFORMATION_MESSAGE);
                                System.exit(0);
                            }
                        }
 
                        for(Assaillant assaillant : Assaillant.assaillant) 
                        {
                            int timedeplace = 0;
                            int vitDeplace = assaillant.getVitDeplace(); // retourne la vitesse de déplacement de l'assaillant en question
                            if(assaillant instanceof Ninja)
                            {
                                if(assaillant.getEtat() != "boulet")
                                {
                                    vitDeplace *= 2;
                                }
                            }
 
                            while(vitDeplace > timedeplace) // cette condition est nécessaire car elle évite des déplacements hors zone ou des "colisions" entre deux vagues d'assaillants de type différent. 
                            {                                // car la variable vitDeplace va varier plus tard selon le type d'assaillants
 
                                assaillant.changeDirection(); // on vérifie si l'assaillant doit changer de direction de déplacement
 
                                if(Fenetre.cases[assaillant.getAbsX() + assaillant.getVecteurX()][assaillant.getOrdY() + assaillant.getVecteurY()].getText() == " ") // vérifie qu'il n'y a pas un autre assaillant devant lui
                                {
                                    if(Fenetre.cases[assaillant.getAbsX()][assaillant.getOrdY()].getText() != "+") // pour ne pas effacer le '+' du terrain, les assaillants apparaissent véritablement sur la 2nde case de déplacement
                                    {
                                        Fenetre.cases[assaillant.getAbsX()][assaillant.getOrdY()].setText(" "); // mets un espace là où l'assaillant se trouve
                                    }
 
                                    assaillant.deplaceAssaillant(); // déplace l'assaillant
                                    if(assaillant instanceof Mercenaire)
                                    {
                                        Fenetre.cases[assaillant.getAbsX()][assaillant.getOrdY()].setText("Mercenaire (" + Character.toString(assaillant.vieAssaillant()) + ")"); // place l'assaillant (son caractère) sur la terrain (tableau de caractères)
                                    }
                                    if(assaillant instanceof MageBlanc)
                                    {
                                        Fenetre.cases[assaillant.getAbsX()][assaillant.getOrdY()].setText("Mage Blanc (" + Character.toString(assaillant.vieAssaillant()) + ")"); // place l'assaillant (son caractère) sur la terrain (tableau de caractères)
                                    }
                                    if(assaillant instanceof Ninja)
                                    {
                                        Fenetre.cases[assaillant.getAbsX()][assaillant.getOrdY()].setText("Ninja (" + Character.toString(assaillant.vieAssaillant()) + ")"); // place l'assaillant (son caractère) sur la terrain (tableau de caractères)
                                    }
                                }
 
                                vitDeplace--; // décrémentation jusqu'à atteindre 0;
                            }
                        }
 
                        for(Defenseur defenseur : Defenseur.defenseur)
                        {
                            int latence = defenseur.getLatence(); // récupère la latence du défenseur
 
                            Assaillant choixAssaillant = defenseur.bonChoix(Assaillant.assaillant); // retourne les caractéristiques de l'assaillant à attaquer (ou assaillant(' ') si aucun assaillant à portée)
 
                            if((choixAssaillant.vieAssaillant() == ' ') || (latence > 0)) // s'il n'y pas d'assaillants à portée du défenseur, ou si le temps de latence n'est pas arrivé à 0
                            {    
                                defenseur.setLatenceDown(); // on diminue le temps de latence
                                continue; // et on passe directement à l'autre défenseur
                            }
 
                            int objet = 0;
                            for(Assaillant assaillant : Assaillant.assaillant)
                            {
                                if(assaillant == choixAssaillant)
                                {
                                    Assaillant.assaillant.set(objet, choixAssaillant); // on change le bon assaillant par choixAssaillant,
                                    break; // et on quitte la boucle dès qu'on a trouvé le bon assaillant
                                }
                                objet++;
                            }
 
                            defenseur.attaqueAssaillant(Fenetre.cases, choixAssaillant); // attaque le bon assaillant
                            defenseur.setLatenceUp(); // on remet le temps de latence à 2 (fixe...)
 
                            if(choixAssaillant.tue())
                            {
                                Defenseur.gagneArgent(); // le joueur gagne 50 gils,
                                defenseur.modifExp(XP); // le défenseur qui a tué l'assailant gagne 2 points d'expérience,
                                Fenetre.cases[choixAssaillant.getAbsX()][choixAssaillant.getOrdY()].setText(" "); // on met un espace là où se trouve l'assaillant,
                                Assaillant.assaillant.remove(choixAssaillant); // et on le supprime de l'ArrayList Assaillant.
                            }
                        }
 
                        if(Defenseur.temps >= 199) // si le joueur tient 200 tours (pour info, il faut environ 15 tours pour qu'un assaillant puisse atteindre la sortie et donc réduire les points de vie de 1)
                        {
                            JOptionPane gagne = new JOptionPane();
                            gagne.showMessageDialog(null, "Bravo! Vous avez gagne!", "Felicitations!", JOptionPane.INFORMATION_MESSAGE); // alors il a gagné!
                            System.exit(0);
                        }
                    }    
                }
 
            Defenseur.temps++; // incrémentation du tour de jeu
        }
    });
 
    goPan.add(goBouton);
    this.add(goPan, BorderLayout.PAGE_END);
    this.pack();
    this.setVisible(true);
 
    }
}
Classe Case:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import java.awt.Color;
 
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
 
public class Case extends JButton implements ActionListener
{
    private static final long serialVersionUID = 1L;
    private int x;
    private int y;
    public Case(String s, int x, int y, Color color)
    {
        super(s);
        this.x = x;
        this.y = y;
        addActionListener(this);
        setBackground(color);
    }
 
    public int getX()
    {
        return x;
    }
 
    public int getY()
    {
        return y;
    }
 
    public String toString()
    {
        return "Case de coordonnees (" + x + ", " + y + ")";
    }
 
    @SuppressWarnings("static-access")
    public void actionPerformed(ActionEvent e) 
    {
        if(Fenetre.treve == true || Defenseur.temps == 0)
        {
            if(Defenseur.bourse >= 100) 
            {    
                if(((Case) e.getSource()).getText() == ".")
                {
                    if(Defenseur.bourse >= 200)
                    {    
                        int x = ((Case) e.getSource()).getX();
                        int y = ((Case) e.getSource()).getY();
                        String[] type = {"Attaquant", "Ravageur", "Saboteur"};
                        JOptionPane jopType = new JOptionPane();
                        String nom = (String)jopType.showInputDialog(null, "Veuillez indiquer le type du défenseur", "Choix du type", JOptionPane.QUESTION_MESSAGE, null, type, type[0]);
                        if(nom == "Attaquant")
                        {
                            Attaquant attaquant0 = new Attaquant(x, y);
                            ((Case) e.getSource()).setText("Attaquant Niveau" + attaquant0.niveauDefenseur());
                            Defenseur.bourse -= 200;
                            Defenseur.defenseur.add(attaquant0);
                            jopType.showMessageDialog(null, "Vous venez de créer un " + nom + "!", "Et hop!", JOptionPane.INFORMATION_MESSAGE);
                        }
 
                        if(nom == "Ravageur")
                        {
                            Ravageur ravageur0 = new Ravageur(x, y);
                            ((Case) e.getSource()).setText("Ravageur Niveau" + ravageur0.niveauDefenseur());
                            Defenseur.bourse -= 200;
                            Defenseur.defenseur.add(ravageur0);
                            jopType.showMessageDialog(null, "Vous venez de créer un " + nom + "!", "Et hop!", JOptionPane.INFORMATION_MESSAGE);
                        }
 
                        if(nom == "Saboteur")
                        {
                            Saboteur saboteur0 = new Saboteur(x, y);
                            ((Case) e.getSource()).setText("Saboteur Niveau" + saboteur0.niveauDefenseur());
                            Defenseur.bourse -= 200;
                            Defenseur.defenseur.add(saboteur0);
                            jopType.showMessageDialog(null, "Vous venez de créer un " + nom + "!", "Et hop!", JOptionPane.INFORMATION_MESSAGE);
                        }
                    }
 
                    else
                    {
                        JOptionPane jop = new JOptionPane();
                        jop.showMessageDialog(null, "Bourse insuffisante pour effectuer cette action", "Erreur", JOptionPane.ERROR_MESSAGE);
                    }
                }
 
                else
                {
                    if(((Case) e.getSource()).getText() == "#")
                    {
                        if(Defenseur.temps > 0)
                        {
                            ((Case) e.getSource()).setText(".");
                            ((Case) e.getSource()).setBackground(Color.ORANGE);
                            Defenseur.bourse -= 100;
                        }
                    }
 
                    else
                    {
                        if(Defenseur.temps > 0)
                        {
                            int x = ((Case) e.getSource()).getX();
                            int y = ((Case) e.getSource()).getY();
                            if(Fenetre.cases[x][y].getText() != "$" && Fenetre.cases[x][y].getText() != "#" && Fenetre.cases[x][y].getText() != " " && Fenetre.cases[x][y].getText() != ".")
                            {
                                Defenseur defenseur1 = new Defenseur(x, y);
                                Defenseur.numero --;
                                for(Defenseur def: Defenseur.defenseur)
                                {
                                    if(def.getAbsX() == defenseur1.getAbsX() && def.getOrdY() == defenseur1.getOrdY())
                                    {
                                        if(def.getExperience() >= 6)
                                        {
 
                                            if(def instanceof Attaquant)
                                            {
                                                def.monteeNiveau();
                                                ((Case) e.getSource()).setText("Attaquant Niveau" + def.niveauDefenseur());
                                            }
                                            if(def instanceof Ravageur)
                                            {
                                                def.monteeNiveau();
                                                ((Case) e.getSource()).setText("Ravageur Niveau" + def.niveauDefenseur());
                                            }
                                            if(def instanceof Saboteur)
                                            {
                                                ((Case) e.getSource()).setText("Saboteur Niveau" + def.niveauDefenseur());
                                            }
                                            break;
                                        }
                                        else
                                        {
                                            JOptionPane jop0 = new JOptionPane();
                                            jop0.showMessageDialog(null, "Votre défenseur n'a pas assez d'expérience pour augmenter de niveau", "Erreur", JOptionPane.ERROR_MESSAGE);
                                        }
                                    }
                                }
                            }
                        }
 
                        else
                        {
 
                            JOptionPane jop1 = new JOptionPane();
                            jop1.showMessageDialog(null, "action de votre part non valable", "Erreur", JOptionPane.ERROR_MESSAGE);
                        }
                    }
                }
            }
 
            else
            {
                    JOptionPane jop2 = new JOptionPane();
                    jop2.showMessageDialog(null, "Bourse insufisante ou action de votre part non valable", "Erreur", JOptionPane.ERROR_MESSAGE);
            }
        }
 
        else
        {
                JOptionPane jop3 = new JOptionPane();
                jop3.showMessageDialog(null, "action de votre part non valable", "Erreur", JOptionPane.ERROR_MESSAGE);
        }
    }
}
Classe Test:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import javax.swing.SwingUtilities;
 
public class Test 
{
    static Runnable tache = new Runnable()
    {
        @SuppressWarnings("unused")
        public void run()
        {
            Fenetre fen = new Fenetre();
        }
    };
 
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(tache);
    }
}
Merci d'avance pour votre aide.