Nochmal Quaxli Spieletutorial ;)

Ruderer1993

Aktives Mitglied
Hey, hatte heute Mittag schon mal eine Frage zu Quaxlis Spieletutorial und dort konntet ihr mir schon super helfen, daher hoffe ich das ihr mir auch dieses mal so toll helfen könnt ;)

Ich bekomme immer die folgende Excpetion nach kurzer Spieldauer:
Java:
Exception in thread "Thread-3" java.util.ConcurrentModificationException
	at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
	at java.util.AbstractList$Itr.next(AbstractList.java:343)
	at GamePanel.doLogic(GamePanel.java:198)
	at GamePanel.run(GamePanel.java:252)
	at java.lang.Thread.run(Thread.java:680)

Wieso ? Ich verstehe das nicht, das muss irgendwann mit dem ListIterator bzw der for each Schleife zu tun haben, glaube ich.

Hier mal die GamePanel Klasse (wenn ihr mehr braucht sagt bescheid, steht ja aber quasi auch alles im Tutorial:
Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ListIterator;
import java.util.Vector;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;


public class GamePanel extends JPanel implements Runnable, KeyListener,ActionListener {
	private static final long serialVersionUID = 1L;
	JFrame f;
	
	long delta; //Zeit des letzten Durchgangs
	long fps;   //Bildrate
	long last;  //letzte Systemzeit
	int time;
	long gameover = 0;
	
	Heli heroObject;
	Vector <Sprite> actors;
	Vector <Sprite> painter;
	
	boolean up;
	boolean down;
	boolean left;
	boolean right;
	boolean started;
	int speed = 75;
	
	SoundLib soundLib;
	
	
	BufferedImage[] rocket;
	BufferedImage[] explosion;
	Timer timer;
	Timer timeScore;
	BufferedImage background;
	
	public static void main(String[] args) {
		new GamePanel(800,600);
	}
	
	public GamePanel(int w, int h) {
		this.setPreferredSize(new Dimension(w,h));
		this.setBackground(Color.blue);
		
		f = new JFrame("JEscape");
		f.setLocation(100,100);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.add(this);
		f.addKeyListener(this);
		f.pack();
		f.setVisible(true);
				
		Thread th = new Thread(this); //Spielschleife in eigenem Thread
		th.start();
	}
	
	private void doInitializations() { //Methode für "einmalige Aktionen" - Laden von Images etc..
		last = System.nanoTime();
		gameover = 0;
		
		BufferedImage[] hero = loadPics("pics/hero.gif",4);
		rocket = loadPics("pics/rocket.gif",8);
	    background = loadPics("pics/background.jpg",1)[0];
	    explosion = loadPics("pics/explosion.gif",5);
	    
	    soundLib = new SoundLib();
	    soundLib.loadSound("bumm", "sound/boom.wav");
	    soundLib.loadSound("background", "sound/background.wav");
	    soundLib.loadSound("gameover", "sound/gameover.wav");
		
		actors = new Vector<Sprite> ();
		painter = new Vector<Sprite> ();
		heroObject = new Heli(hero,400,300,100,this);
		actors.add(heroObject);
		
		createClouds();
		
		timer = new Timer(1000,this);
		timer.start();
		
		timeScore = new Timer(1000,this);
		timeScore.start();
		started = true;
	}
	
	private void computeDelta() { //Errechnung des Schleifendurchlaufes
		delta = System.nanoTime()-last;
		last = System.nanoTime();
		fps = ((long) 1e9)/delta;
	}
	
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawImage(background, 0, 0,this);
		g.setColor(Color.white);
		g.drawString("FPS: "+Long.toString(fps), 20, 10);
	    g.drawString("Zeit: "+time,730,10);
		if(!started) {
			return;
			}
		
		for(ListIterator<Sprite> it = painter.listIterator();it.hasNext();) {
			Sprite r = it.next();
			r.drawObjects(g);
		}
	}
	
	public void createClouds() {
		BufferedImage[] bi = loadPics("pics/cloud.gif",1);
		
		for(int y=10;y<getHeight();y+=50) {
			int x = (int)(Math.random()*getWidth());
			Cloud cloud = new Cloud(bi,x,y,1000,this);
			actors.add(cloud);
		}
	}
	
	public void createExplosion(int x, int y) {
		ListIterator<Sprite> it = actors.listIterator();
		it.add(new Explosion(explosion,x,y,100,this));
		soundLib.playSound("bumm");
	}
	
	
	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(100);
		} else {
			rock.setHorizontalSpeed(-100);
		}
		
		ListIterator<Sprite> it = actors.listIterator();
		it.add(rock);
	
	
		
		
	}
	
	
	private void checkKeys() {
		if(up) {
			heroObject.setVerticalSpeed(-speed);
		}
		
		if(down) {
			heroObject.setVerticalSpeed(speed);
		}
		
		if(left) {
			heroObject.setHorizontalSpeed(-speed);
		}
		
		if(right) {
			heroObject.setHorizontalSpeed(speed);
		}
		
		if(!up&&!down) {
			heroObject.setVerticalSpeed(0);
		}
		
		if(!left&&!right) {
			heroObject.setHorizontalSpeed(0);
		}
	}
	
	private void doLogic() {
		for(ListIterator<Sprite> it = actors.listIterator(); it.hasNext();) {
			Sprite r = it.next();
			r.doLogic(delta);
			
			if(r.remove) {
				it.remove();
			}
		}
		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);
			}
		}
		
		if (heroObject.remove && gameover == 0) {
			gameover = System.currentTimeMillis();
		}
		
		if(gameover > 0) {
			if(System.currentTimeMillis()-gameover>3000) {
				stopGame();
			}
		}
	}
	
	private void stopGame() {
		timer.stop();
		setStarted(false);
		soundLib.playSound("gameover");
		soundLib.stopLoopingSound();
	}
	
	private void startGame() {
		doInitializations();
		setStarted(true);
		soundLib.loopSound("background");
	}
	
	private void moveObjects() {
		for(ListIterator<Sprite> it = actors.listIterator(); it.hasNext();) {
			Sprite r = it.next();
			r.move(delta);
		}
	}
	
	
	@Override
	public void run() {
		while(f.isVisible()) {
			computeDelta(); 
			
		if(isStarted()) {
			checkKeys();
			doLogic();
			moveObjects();
			cloneVectors();
		}
			repaint();
			
			try {
				Thread.sleep(10);
			} catch(InterruptedException e) {}
		}
		
	}
	@SuppressWarnings("unchecked")
	private void cloneVectors() {
		painter = (Vector<Sprite>) actors.clone();
	}
	
     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) {System.out.println("Argh..."); e.printStackTrace();}
		
		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;
     }
     
    @Override
    public void actionPerformed(ActionEvent e)
    {
    	if(isStarted() && e.getSource().equals(timer)) {
    		createRocket();
    	}
    	
    	if(isStarted() && e.getSource().equals(timeScore)) {
    		time = time +1;
    	}
    }
	@Override
	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;
		}
		
		
	}

	@Override
	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()) {
                startGame();				
			}
		}
		
		if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {
			if(isStarted()) {
				setStarted(false);
				timer.stop();
				stopGame();
			} else {
				
			   // f.dispose();
			}
		}
	}

	@Override
	public void keyTyped(KeyEvent e) {
		
	}
     
     

}

Vielen Vielen Dank !
 

Cola_Colin

Top Contributor
Irgendwo wird während des Durchlaufs in der Schleife die Liste abgeändert. Dann knallt es.

Vom Code her würde ich folgenden Ablauf vermuten:

Thread A führt Spiellogik aus, entfernt ein Objekt während Thread B, der EDT, die Spielobjekte durchläuft um diese zu zeichnen.
Die einfachste Lösung wäre es den Zugriff auf die Liste zu synchronisieren.
 

hdi

Top Contributor
Ohne den Code angesehen zu haben, d.h. Pseudo-Code:

Java:
// Thread A:
synchronized(liste){
     // manipulieren
}

// Thread B: (vermutlich EDT, also zB in der paint-Component)
synchronized(liste){
    // zugriff
}
 

hdi

Top Contributor
PS:

Danke gerade hinzugefügt und es scheint zu funktionieren, nochmals danke
Spar dir den Text, klick statt dessen auf den "Danke" Button unter meinem Beitrag, darüber freu ich mich mehr :D (Aber bitte :))

PPS: Bitte klicke oben im Topic auf "Thema als erledigt markieren" wenn du keine weiteren Fragen hast.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
W Nochmal das Decorator - Mit der abstrakten Klasse möglich? Java Basics - Anfänger-Themen 10
Ostkreuz Wieso wird die Methode nochmal aufgerufen? Java Basics - Anfänger-Themen 5
E nochmal synchronisierte Methoden Java Basics - Anfänger-Themen 5
J Hinzufügen eines Objekts in eine Liste, um später dann nochmal auf das Objekt zugreifen zu können Java Basics - Anfänger-Themen 8
B Unique ID nochmal Unique machen Java Basics - Anfänger-Themen 20
X Wenn Exception dann nochmal try. Java Basics - Anfänger-Themen 7
V Nochmal Hilfe - Replace Methode Java Basics - Anfänger-Themen 2
T Override klappt nochmal wie? Java Basics - Anfänger-Themen 3
Haubitze_Broese Methode am ende nochmal startet? Java Basics - Anfänger-Themen 8
D Ausgabe sauber formatieren *bitte nochmal reinschaun* Java Basics - Anfänger-Themen 7
D C0 und C1 Test nochmal Java Basics - Anfänger-Themen 9
B könnte nochmal jemand über mein Projekt schauen? Java Basics - Anfänger-Themen 4
C Nochmal zu lokale Einstellungen Java Basics - Anfänger-Themen 2
G nach Thread.start(); nochmal start(); aufrufen geht nicht Java Basics - Anfänger-Themen 4
S Fehler durch Exception beheben und nochmal versuchen Java Basics - Anfänger-Themen 4
U Nochmal was zum Date(); Java Basics - Anfänger-Themen 23
F nochmal Array Declaration Java Basics - Anfänger-Themen 2
G Nochmal vereinfacht - hoffe mer kanns nachvollziehen Java Basics - Anfänger-Themen 9
F Referenz Pointer oder doch nochmal neu suchen ? Java Basics - Anfänger-Themen 2
G Nochmal zweidimensionaler Vector Java Basics - Anfänger-Themen 10
ven000m Char einlesen, wie ging das nochmal? Java Basics - Anfänger-Themen 9
D Nochmal zu den dummen Eingaben über Tastatur Java Basics - Anfänger-Themen 15
B Nochmal ich/ Graphik wird nicht angezeigt ? Java Basics - Anfänger-Themen 12
G Nochmal Problem mit Kommunikation zwischen Klassen Java Basics - Anfänger-Themen 3
B nochmal ich / jdk1.5 Java Basics - Anfänger-Themen 5
S nochmal Taschenrechner ;) Java Basics - Anfänger-Themen 16
B Nochmal NoClassDefFoundError Java Basics - Anfänger-Themen 3
megachucky nochmal JDBC. komme nicht weiter. Java Basics - Anfänger-Themen 4
K nochmal Jtable Java Basics - Anfänger-Themen 5
IamArctic Quaxli Tutorial, Rotorblätter bewegen sich nicht mehr Java Basics - Anfänger-Themen 4
R Quaxli Tutorial - Bild nicht sichtbar Java Basics - Anfänger-Themen 4
K java.util.ConcurrentModificationException problem in der Logik? Quaxli-Tutorial Java Basics - Anfänger-Themen 9

Ähnliche Java Themen

Neue Themen


Oben