Bonjour, je suis actuellement entrain de coder un petit jeu et j'essaye de bien utiliser les threads mais rien à faire j'ai toujours des erreurs.. :/
En gros, j'ai un vaisseau que je déplace latéralement avec la souris et qui peux tirer sur des astéroïdes qui se déplacent verticalement, pour l'instant c'est tout ce que j'essaye de faire.
J'ai donc fait une classe que j'ai appelée "aireJeux" que j'ai ajouter à mon container de ma fenêtre et j'essaye de la réafficher toutes les x millisecondes avec une thread.
Alors voici au début ce que j'ai fait :
Tout d'abord il faut savoir que j'ai déclaré ma liste d'astéroïdes comme ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 private ArrayList <Asteroide> arrayAsteroide = new ArrayList <Asteroide> (); private List <Asteroide> asteroides = Collections.synchronizedList(arrayAsteroide);La thread d'affichage :
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 public AireJeux () { this.setBounds(0, 0, WIDTHECRAN, HEIGHTECRAN); vaisseau = new Vaisseau("IMAGES/vaisseau.png", 305, 405); this.addKeyListener(new clavierListener()); this.addMouseListener(new sourisListener()); this.addMouseMotionListener(new bougeSourisListener()); threadAffichage = new ThreadAffichage(this); Thread tAff = new Thread(threadAffichage); tAff.start(); threadPopAsteroide = new ThreadPopAsteroide(asteroides); Thread tPop = new Thread(threadPopAsteroide); tPop.start(); } @Override public void paint (Graphics g) { super.paint(g); vaisseau.updateHitBox(); g.drawImage(fond.getImage(), 0, 0, this); g.drawImage(vaisseau.getImage().getImage(), vaisseau.getPositionX(), vaisseau.getPositionY(), this); for(Tir tir : tirs) { g.drawImage(tir.getImage().getImage(), tir.getPositionX(), tir.getPositionY(), this); tir.setPositionY(tir.getPositionY() - tir.getVitesse()); if(tir.getPositionY() < 0) tirs.remove(tir); } for(Asteroide asteroide : asteroides) { asteroide.updateHitBox(); g.drawImage(asteroide.getImage().getImage(), asteroide.getPositionX(), asteroide.getPositionY(), asteroideRef.getIconWidth()/asteroide.getZoom(), asteroideRef.getIconHeight()/asteroide.getZoom(), this); asteroide.setPositionY(asteroide.getPositionY() + asteroide.getVitesse()); if(asteroide.getPositionY() > HEIGHTECRAN || asteroide.collision(vaisseau.getTabHitBox()) == true) { asteroides.remove(asteroide); } } }
Et la thread de pop :
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 @Override public void run () { while(continuer == true) { try { Thread.sleep(15); } catch(Exception e) { System.out.println(e.getMessage()); } aireJeux.repaint(); } }
Je pouvais jouer sans interruption mais j'avais cette erreur qui s'affichait en boucle :
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 @Override public void run () { while(continuer == true) { try { Thread.sleep((long)(50 + (Math.random() * 450))); } catch(Exception e) { System.out.println(e.getMessage()); } if(asteroides.size() < 15) asteroides.add(new Asteroide("IMAGES/asteroid.png", ((int)(0 + (Math.random() * 800))), -100, 4, (int)(1 + (Math.random() * 10)))); } }
Alors je me suis dit que même si ma liste était synchroniser les threads n'arrivaient pas à travailler sur la même liste en même temps..Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)
at View.AireJeux.paint(AireJeux.java:56)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5221)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1512)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1443)
at javax.swing.RepaintManager.paint(RepaintManager.java:1236)
at javax.swing.JComponent._paintImmediately(JComponent.java:5169)
at javax.swing.JComponent.paintImmediately(JComponent.java:4980)
at javax.swing.RepaintManager$3.run(RepaintManager.java:796)
at javax.swing.RepaintManager$3.run(RepaintManager.java:784)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:784)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:757)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:706)
at javax.swing.RepaintManager.access$1000(RepaintManager.java:62)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1651)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:688)
at java.awt.EventQueue$3.run(EventQueue.java:686)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:697)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
J'ai donc essayer de faire ceci :
J'ai supprimer la thread "popAsteroide" pour l'inclure dans la thread d'affichage et j'ai enlever le remove() de ma fonction paint mais je l'ai placé dans ma thread d'affichage aussi..
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 @Override public void paint (Graphics g) { super.paint(g); vaisseau.updateHitBox(); g.drawImage(fond.getImage(), 0, 0, this); g.drawImage(vaisseau.getImage().getImage(), vaisseau.getPositionX(), vaisseau.getPositionY(), this); for(Tir tir : tirs) { g.drawImage(tir.getImage().getImage(), tir.getPositionX(), tir.getPositionY(), this); tir.setPositionY(tir.getPositionY() - tir.getVitesse()); if(tir.getPositionY() < 0) tirs.remove(tir); } for(Asteroide asteroide : asteroides) { asteroide.updateHitBox(); g.drawImage(asteroide.getImage().getImage(), asteroide.getPositionX(), asteroide.getPositionY(), asteroideRef.getIconWidth()/asteroide.getZoom(), asteroideRef.getIconHeight()/asteroide.getZoom(), this); asteroide.setPositionY(asteroide.getPositionY() + asteroide.getVitesse()); if(asteroide.getPositionY() > HEIGHTECRAN || asteroide.collision(vaisseau.getTabHitBox()) == true) { asteroide.setAAficher(true); } } }Mais ici tout fonctionne sauf une fois qu'il y-à une collision. Là le jeu se bloque et m'affiche cette erreur :
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 @Override public void run () { while(continuer == true) { try { Thread.sleep(15); } catch(Exception e) { System.out.println(e.getMessage()); } if((Math.random() * 100) <= 5) aireJeux.getListAsteroide().add(new Asteroide("IMAGES/asteroid.png", ((int)(0 + (Math.random() * 800))), -100, 4, (int)(1 + (Math.random() * 10)))); for(Asteroide asteroide : aireJeux.getListAsteroide()) { if(asteroide.getPositionY() > HEIGHTECRAN || asteroide.collision(aireJeux.getVaisseau().getTabHitBox()) == true) { aireJeux.getListAsteroide().remove(asteroide); } } aireJeux.repaint(); } }
Alors si quelqu'un pouvait m'aider et me dire laquelle des 2 façons est la meilleure ou bien si il faut que je change complétement de façon de faire et comment résoudre mon problème..? Merci d'avance :/Exception in thread "Thread-1" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)
at vaisseaujava.ThreadAffichage.run(ThreadAffichage.java:33)
at java.lang.Thread.run(Thread.java:722)
Partager