# Kugeln schießen



## Guest (26. Apr 2008)

Hallo,

ich versuche gerade ein Spiel zu schreiben, bei dem man mit Kugeln schießen kann.

Ich habe eine Klasse Kugel definiert.


```
import java.awt.Color;
import java.awt.Graphics;

public class Kugel {

	private int x,y;

	public Kugel(int x,int y)
	{
		setPosition(x,y);
	}



	public void anzeigen(Graphics g)
	{
		g.setColor(Color.BLUE);

		g.fillOval(x, y, 10, 10);
	}

	public void setPosition(int x,int y)
	{
		this.x=x;
		this.y=y;
	}

	



	public int getX()
	{
		return this.x;
	}

	public int getY()
	{
		return this.y;
	}
```


Ich benutze sie so:


```
Kugel k;


	public void paint(Graphics g)
	{
		k.anzeigen(g);
	}

	public void setPosition(int x,int y,Kugel k)
	{
		k.setPosition(x,y);
		repaint();
	}

	public void plusX(Kugel k)
	{
		k.setPosition(k.getX()+1,k.getY());

	}

	public void neueKugelStarten()
	{
		k=new Kugel(100,100);

		new Thread() { 
			@Override public void run() {
				while(true)
				{
					try
					{

						Thread.sleep(1);

					}
					catch(Exception e)
					{

					}
					plusX(k);
					repaint();
					

				}
			}
		}.start();
	}
```


Jetzt kann ich die Kugel fliegen lassen.

Mein Problem:
Wenn ich öfter die Methode neueKugelStarten() aufrufe, dann spielt das ganze verückt(Kugel wird immer schneller).
Was muss ich tun, dass ich mehrere Kugeln habe, die alle gleich schnell fliegen?


----------



## Marco13 (26. Apr 2008)

Jedes mal, wenn die Methode aufgerufen wird, wird eine neue Kugel erstellt, und ein neuer Thread, der "DIE" Kugel bewegt. "DIE" Kugel ist aber immer DIE, die in 'k' liegt. Beim zweiten Aufruf wird also die "alte" Kugel weggeworfen, und beide Threads kümmern sich nurnoch um die neue, die dann in k liegt. Es ist schwierig zu sagen, was die beste Abhilfe dafür ist, wenn man nicht weiß, was dabei am Ende rauskommen soll. Die direkteste Lösung wäre, die Kugeln lokal (in der Methode wo der Thread erstellt wird) als "final Kugel k" zu erstellen, und die Kugeln zusätzlich in eine Liste legen

```
class Bla
{
    //Kugel k; // WEG

    private List<Kugel> kugeln = new ArrayList<Kugel>(); 

    public void neueKugelStarten()
    {
        final Kugel k=new Kugel(100,100);
        kugeln.add(k);

        ... // rest wie vorher
```

Überall da, wo etwas bisher mit "k" gemacht wurde, macht man das dann halt mit allen Kugeln aus der Liste, oder mit einer angegebenen 

```
void malen()
{
    for (Kugel k : kugeln)
    {
          k.malen();
    }
}

void machWasMit(int kugelIndex)
{
    kugeln.get(kugelIndex).machWas();
}
....
```


----------



## Guest (28. Apr 2008)

Ok danke, habe jetzt ein weiteres Problem.

Ich bekomme immer, wenn eine Kugel das Spielfeld verlässt
eine

```
java.util.ConcurrentModificationException
```

So sieht mein Thread aus:



```
new Thread() { 
			@Override public void run() {
				while(true)
				{
					try
					{

						Thread.sleep(1);

					}
					catch(Exception e)
					{

					}

					for (Kugel k : kugeln)
					{
						plusX(k);
					} 


					for (Kugel k : kugeln)
					{

						if(k.getX()>800)//Kugel verlässt Spielfeld
						{
							kugeln.remove(k);//hier tritt der Fehler auf
						}
					}

					repaint();


				}
			}
		}.start();
```


----------



## Marco13 (28. Apr 2008)

Das Entfernen muss man so machen, dass sichergestellt ist, dass nicht gerade ein anderer Thread durch die Kugel-Liste läuft. Schau mal bei Collections.synchronizedList. Wenn es nur den einen Thread zum Kugeln-Bewegen gibt, kann man auch die Kugeln, die entfernt werden müssen, in eine eigene Liste legen, und die dann am Ende alle auf einmal entfernen.


----------

