Problem bei Quaxlis Tutorial(Nachtrag Teil1)

CelticWolf

Mitglied
Hallo!

Ich habe den ersten Teil von Quaxlis "Tutorial für Java Spiele" durchgearbeitet und das spiel funktioniert wie beschrieben. Doch erscheint während dem Spiel oft die Fehlermeldung Exception in thread "Thread-5" java.util.ConcurrentModificationException.
Soweit so gut, denn im Nachtrag wird auf dieses Problem eingegangen und eine Lösung nachgereicht.

Allerdings verstehe ich nicht so recht was ich genau ändern muss. Wenn ich die in der doLogic()-Methode dieForeach Schleife auskommentiere und und ersetze, dann wird der helikopter nicht ausgeblendet und die explosionsanimation loopt ständig.



hier der Lösungsvorschlag des Tutorials;
JavaConcurrentModificationException
Von Lesern dieses Tutorials wurde mir immer wieder berichtet, daß ihr Programm
eine JavaConcurrentModificationException wirft. Seltsamerweise tut das mein hier
gezeigtes Programm nicht, während ich den gleichen Effekt bei Programmen
beobachten kann, die mir zugesendet wurden.
Obwohl ich einige Zeit investiert habe, ist es mir bisher nicht gelungen den genauen
Unterschied heraus zu finden.
Nichtsdestotrotz möchte ich hier aber eine Lösung für das Problem nachreichen:
Der Fehler wird geworfen, wenn mehrere Threads (GameLoop- & „Fenster“-Thread)
gleichzeitig auf den Vector zugreifen bzw. wenn einer der beiden Threads etwas am
Vector ändert, während der andere auf die Objekte darin zugreift bwz. darüber
iteriert.
Zwar ist die Klasse Vector lt. API eigentlich thread-safe, das foreach-Konstrukt ist es
aber offensichtlich nicht.
Die Lösung des Problems besteht daher darin, die Art und Weise, mit der über den
Vector iteriert wird zu ändern.
Daher sollten alle Zugriffe, die über den Vector „nudeln“ wie folgt geändert werden:
Zeile 153 – 155: Die foreach-Schleife wird auskommentiert.
Zeile 157 – 159: Stattdessen iterieren wir selbst über die Objekte des Vectors. Das
Prinzip ist gleich geblieben, der Methodenaufruf prinzipiell auch, wir rufen diese nur
ein bisschen anders auf. 
Mit dieser Modifikation, angewendet auf alle foreach-Schleifen, sollte das Problem
dann erledigt sein. (Sobald ich herausbekomme, warum dies in meiner Version, bei
mir nicht geschieht, reiche ich die Lösung nach).



Java:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.swing.*;



public class GamePanel extends JPanel implements Runnable, KeyListener, ActionListener{	
	private static final long serialVersionUID = 1L;
	boolean game_running = true;
	boolean started = false;
	boolean once = false;
	
	long delta = 0;
	long last = 0;
	long fps = 0;
	long gameover = 0;
	
	
	long timepass;
	int level = 1;
	int rdel = 1500;
	int x = 1;
	
	Heli copter;
	Vector<Sprite> actors;
	
	boolean up		= false;
	boolean down	= false;
	boolean left	= false;
	boolean right	= false;
	int speed = 200;
	
	Timer timer;
	Timer rtime;
	BufferedImage[] rocket;
	BufferedImage background;
	BufferedImage[] explosion;
	
	
	
	SoundLib slib;
	
	public static void main(String[] args){
		new GamePanel(1000,600);
	}
	
	
	
public GamePanel(int w, int h)
	{
		this.setPreferredSize(new Dimension(w, h));
		this.setBackground(Color.DARK_GRAY);
		JFrame frame = new JFrame("GameDemo");
		frame.setLocation(100,100);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.addKeyListener(this);
		frame.add(this);
		frame.pack();
		frame.setVisible(true);
		doInitializations();
	}
	
	private void doInitializations(){
		
		BufferedImage[] heli = this.loadPics("pics/heli.png", 4);
		rocket = loadPics("pics/rocket.gif",8);
		background = loadPics("pics/background.jpg",1)[0];
		explosion = loadPics("Pics/explosion.gif",5);
		
		slib = new SoundLib();
		slib.loadSound("heli","sound/heli.wav");
		slib.loadSound("bumm","sound/boom.wav");
		slib.loadSound("rocket", "sound/rocket_start.wav");
		
		
		last = System.nanoTime();
		gameover = 0;
		
		actors = new Vector<Sprite>();
		copter = new Heli(heli,400,300,100,this);
		actors.add(copter);
		
		if(isStarted()){
			slib.loopSound("heli");
		}
		
		createClouds();
		
		
		
		timer = new Timer(3000,this);
		timer.start();
		
		rtime = new Timer(10000,this);
		rtime.start();
		
		if(!once){
			once = true;
			Thread t = new Thread(this);
			t.start();
		}
	}
	
	
	private void createClouds(){
		
		BufferedImage[] ci = this.loadPics("pics/cloudr.png", 1);
	
		for(int y=10;y<getHeight();y+=50){
			int x = (int)(Math.random()*getWidth());
			Cloud cloud = new Cloud(ci,x,y,1000,this);
			actors.add(cloud);
		}
	
	}
	
	public void createExplosion(int x, int y){
		
		Explosion ex = new Explosion(explosion,x,y,100,this);
		actors.add(ex);
		slib.playSound("bumm");
		
		
	}
	

	
	public void run(){
		
		while(game_running){
			
			computeDelta();
			if(isStarted()){
			checkKeys();
			doLogic();
			moveObjects();
			
			
			}
			
			repaint ();
			
			try {
				Thread.sleep(10);
			}catch (InterruptedException e) {}
		
		}
	}

	private void checkKeys(){
		
		if(up){
			copter.setVerticalSpeed(-speed);
		}
		
		if(down){
			copter.setVerticalSpeed(speed);
		}
		
		if(right){
			copter.setHorizontalSpeed(speed);
		}
		
		if(left){
			copter.setHorizontalSpeed(-speed);
		}
		
		if(!up&&!down){
			copter.setVerticalSpeed(0);
		}
		
		if(!left&&!right){
			copter.setHorizontalSpeed(0);
		}
	}
	
	private void doLogic(){
		
		Vector<Sprite> trash = new Vector<Sprite>();
	
		
		
		/*for(Movable mov:actors){
			mov.doLogic(delta);
			Sprite check = (Sprite)mov;
			if(check.remove){
				trash.add(check);
			}
		}
		
		*/
			
		
		for(int i = 0;i < actors.size();i++){
			actors.get(i).doLogic(delta);
			Sprite check = (Sprite)actors.get(i);
			if(check.remove){
				trash.add(check);
			}
			for(int n = i+1; n<actors.size();n++){
				Sprite s1 = actors.elementAt(i);
				Sprite s2 = actors.elementAt(n);
				s1.collidedWith(s2);
				
			}
			
		}
		
		if(trash.size()>0){
			for(Sprite s: trash){
				trash.clear();
			}
		}
		if(gameover>0){
			
			if(System.currentTimeMillis()-gameover>3000){
				stopGame();
			}
		}
		
	}
	
	private void stopGame(){
		timer.stop();
		rtime.stop();
		slib.stopLoopingSound();
		setStarted(false);
		
	}

	private void moveObjects(){
		for(Movable mov:actors){
			mov.move(delta);
			}
		
		
	}
	
	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		
		g.drawImage(background, 0, 0, this);
	
		g.setColor(Color.white);
		g.setFont( new Font( "Trebuchet MS", Font.BOLD, 12 ) );
		g.drawString("FPS: " + Long.toString(fps), 20, 10);
		g.drawString("Level  " + level, 750, 10);
		
		if(!isStarted()){
			return;
		}
		
		if(actors !=null){
			for(Drawable draw:actors){
				draw.drawObjects(g);
			}
		}
	}
	
	private void computeDelta(){
		
		delta = System.nanoTime() - last;
		last = System.nanoTime();
		
		fps = ((long) 1e9)/delta;
	}
	
	
	private BufferedImage[] loadPics(String path, int pics){
		
		BufferedImage[] anim = new BufferedImage[pics];
		BufferedImage source = null;
		
		URL pic_url = getClass().getClassLoader().getResource(path);
		
		try{
			source = ImageIO.read(pic_url);
			} catch (IOException e) {}
			
			for(int x=0;x<pics;x++){
				anim[x] = source.getSubimage(x*source.getWidth()/pics, 0, 
						source.getWidth()/pics, source.getHeight());
			}
			
			return anim;
	}
	
	public boolean isStarted() {
		return started;
	}
	
	public void setStarted(boolean started) {
		this.started = started;
	}


	
private void createRocket(){
		
		int x = 0;
		int y = (int)(Math.random()*getHeight());
		int hori = (int)(Math.random()*2);
		
		if(hori==0){
			x = -30;
		}else{
			x = getWidth()+30;
		}
		
		
		Rocket rock = new Rocket(rocket,x,y,100,this);
		if(x<0){
			rock.setHorizontalSpeed(300);
		}else{
			rock.setHorizontalSpeed(-300);
		}
		actors.add(rock);
		//slib.playSound("rocket");
		
	}




	
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode()==KeyEvent.VK_UP){
			up		=	true;
		}
		
		if(e.getKeyCode()==KeyEvent.VK_DOWN){
			down	=	true;
		}
		
		if(e.getKeyCode()==KeyEvent.VK_LEFT){
			left	=	true;
		}
		
		if(e.getKeyCode()==KeyEvent.VK_RIGHT){
			right = true;
		}

	}
	
	
	
	public void keyTyped(KeyEvent e) {
		
	
		
	}


	public void keyReleased(KeyEvent e) {
		
		if(e.getKeyCode()==KeyEvent.VK_UP){
			up		=	false;
		}
		if(e.getKeyCode()==KeyEvent.VK_DOWN){
			down	=	false;
		}
		if(e.getKeyCode()==KeyEvent.VK_LEFT){
			left	=	false;
		}
		if(e.getKeyCode()==KeyEvent.VK_RIGHT){
			right	=	false;
		}
		if(e.getKeyCode()==KeyEvent.VK_ENTER){
			if(!isStarted()){
				doInitializations();
				setStarted(true);
				level = 1;
			}
		}
		if(e.getKeyCode()==KeyEvent.VK_ESCAPE){
			if(isStarted()){
				stopGame();
			}else{
				setStarted(false);
				System.exit(0);
			}
		}
		
		
		}
	public void actionPerformed(ActionEvent e){
	
		if(isStarted() && e.getSource().equals(timer)){
			createRocket();
		}
		if(isStarted() && e.getSource().equals(rtime)){
			level++;
			timer.setDelay(3000/level);
		}
	
		
	}
	
	}
 
Nimm anstatt eines Vektors eine CopyOnWriteArrayList.
Edit:
Die ConcurrentModificationException wird geworfen, wenn über die List iteriert und zugleich die List geändert wird.
 
Zuletzt bearbeitet:
@Quaxli: Ich finde es schade, dass DAS Spieletutorial hier aus dem Forum so einen Flaw hat. Falls du mal dazu kommst, das ganze nach dem letzten Stand zu einer kompletten (z.B. Eclipse-importierbaren) ZIP zusammenzupacken (vielleicht mit einer Änderung, wo das Problem auftritt) würde ich versuchen, mal die Zeit zu finden, dem nachzugehen, so dass ggf. auch der Text angepasst werden könnte, und das nicht mit so einem "Nachtrag" ausgebügelt werden müßte...
 
Hmm aber wie erstellt man so eine CopyOnWriteArrayList??

im Nachtrag stehen noch folgende Zeilen: (Bei mir ist die Methode doLogic() auf zeile 182)
Java:
private void doLogic(){

 /*for (Movable mov:actors) {
 mov.doLogic(delta);
}*/

for(int i=0;i<actors.size() ; i++) {   //neu eingefügt
actors.get(i).doLogic(delta);
}

if (time == 300) {
createRocket();
time= 0;
}else {
time++;
}
}

doch die ist anders als die do l
 
Hmm aber wie erstellt man so eine CopyOnWriteArrayList??

im Nachtrag stehen noch folgende Zeilen: (Bei mir ist die Methode doLogic() auf zeile 182)
Java:
private void doLogic(){

 /*for (Movable mov:actors) {
 mov.doLogic(delta);
}*/

for(int i=0;i<actors.size() ; i++) {   //neu eingefügt
actors.get(i).doLogic(delta); //neu eingefügt
} //neu eingefügt

if (time == 300) {
createRocket();
time= 0;
}else {
time++;
}
}

Doch die ist anders als die doLogic Methode von mir.
Bei mir und gemäss der Anleitung sieht der Code so aus

Java:
private void doLogic(){
		
Vector<Sprite> trash = new Vector<Sprite>();
		
		for(Movable mov:actors){
			mov.doLogic(delta);
			Sprite check = (Sprite)mov;
			if(check.remove){
				trash.add(check);
			}
		}

		
		
		for(int i = 0;i < actors.size();i++){
      for(int n = i+1; n<actors.size(); n++){
    
         Sprite s1 = actors.elementAt(i);
         Sprite s2 = actors.elementAt(n);
         
         s1.collidedWith(s2);
				
			}
			
		}


wie muss ich diesen teil nun anpassen?

und muss man sonst auch noch etwas verändern?
 
Es sollte reichen, wenn du den Typ des Vectors, der die Exception ausgelöst hat in CopyOnWriteArrayList änderst. Die ist gleich zu bedienen wie ein Vectorobjekt.
 
Ich habe den Code nun geändert und das Spiel funktioniert. Allerdings kommen während dem Spiel (nicht von Anfang an, aber spätestens bei einer Kollision mit einer Bombe) folgende Fehlermeldungen:

Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at GamePanel.paintComponent(GamePanel.java:268)
at javax.swing.JComponent.paint(JComponent.java:1029)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1479)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1410)
at javax.swing.RepaintManager.paint(RepaintManager.java:1224)
at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:785)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at GamePanel.paintComponent(GamePanel.java:268)
at javax.swing.JComponent.paint(JComponent.java:1029)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1479)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1410)
at javax.swing.RepaintManager.paint(RepaintManager.java:1224)
at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:785)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at GamePanel.paintComponent(GamePanel.java:268)
at javax.swing.JComponent.paint(JComponent.java:1029)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1479)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1410)
at javax.swing.RepaintManager.paint(RepaintManager.java:1224)
at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:785)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at GamePanel.paintComponent(GamePanel.java:268)
at javax.swing.JComponent.paint(JComponent.java:1029)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1479)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1410)
at javax.swing.RepaintManager.paint(RepaintManager.java:1224)
at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:785)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at GamePanel.paintComponent(GamePanel.java:268)
at javax.swing.JComponent.paint(JComponent.java:1029)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1479)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1410)
at javax.swing.RepaintManager.paint(RepaintManager.java:1224)
at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:785)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at GamePanel.paintComponent(GamePanel.java:268)
at javax.swing.JComponent.paint(JComponent.java:1029)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1479)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1410)
at javax.swing.RepaintManager.paint(RepaintManager.java:1224)
at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:785)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at GamePanel.paintComponent(GamePanel.java:268)
at javax.swing.JComponent.paint(JComponent.java:1029)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1479)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1410)
at javax.swing.RepaintManager.paint(RepaintManager.java:1224)
at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:785)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at GamePanel.paintComponent(GamePanel.java:268)
at javax.swing.JComponent.paint(JComponent.java:1029)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1479)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1410)
at javax.swing.RepaintManager.paint(RepaintManager.java:1224)
at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:785)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)



Der Geänderte Code sieht so aus:

Java:
private void doLogic(){
		
Vector<Sprite> trash = new Vector<Sprite>();
		
	/*	for(Movable mov:actors){
			mov.doLogic(delta);
			Sprite check = (Sprite)mov;
			if(check.remove){
				trash.add(check);
			}
		}

		*/
for(int i=0;i<actors.size() ; i++) { 
	actors.get(i).doLogic(delta);
	Sprite check = (Sprite)actors.get(i);
	if(check.remove){
		trash.add(check);
	}
	}

Java:
	private void moveObjects(){
		/*for(Movable mov:actors){
			mov.move(delta);
			}
		*/
		
		for(int i=0;i<actors.size() ; i++) {  
			actors.get(i).move(delta);     
			}
		
	}
 
Poste doch den Code wo der Fehler aufgetreten ist, und zwar in GamePanel in Zeile 268. Da wird sicher noch irgendwie ein Iterator über eine synchronisierte Collection verwendet.
 
Dankee !
Nun funktioniert das Spiel einwandfrei !

Ich habe nun den Drawable Vektor auf Zeile 268 auch in eine CopyOnWriteArrayList umgewandelt. Habe den völlig übersehen.

Hier sind nochmals alle Codezeilen die geändert werden müssen um das Problem zu beheben:


Java:
private void doLogic(){
		
Vector<Sprite> trash = new Vector<Sprite>();
		
	/*	for(Movable mov:actors){
			mov.doLogic(delta);
			Sprite check = (Sprite)mov;
			if(check.remove){
				trash.add(check);
			}
		}

		*/
for(int i=0;i<actors.size() ; i++) { 
	actors.get(i).doLogic(delta);
	Sprite check = (Sprite)actors.get(i);
	if(check.remove){
		trash.add(check);
	}
	}

Java:
private void moveObjects(){
		/*for(Movable mov:actors){
			mov.move(delta);
			}
		*/
		
		for(int i=0;i<actors.size() ; i++) {  
			actors.get(i).move(delta);     
			}
		
	}

Java:
if(actors !=null){
			/*for(Drawable draw:actors){
				draw.drawObjects(g);
			} */
			
			for(int i=0;i<actors.size();i++){
				actors.get(i).drawObjects(g);
			}
			
			
		}
 

Neue Themen


Zurück
Oben