# Java Bouncing Balls



## iChaos (13. Apr 2010)

Hi zusammen

Wir haben die Aufgaben erhalten, eine Applikation welche 2 oder mehrere Bälle hat, die sich bewegen und bei einem Zusammenprall abprallen. Jedoch habe ich keinen blassen Schimmer wie ich das mit der Abprallfunktion hinbekommen soll... Wer hat ne Idee?



```
public class MoveBall extends JPanel implements Runnable {

	int xRed = 180;//xKoordinate für Rot
	int xBlue = 60;//xKoordinate für Blau
	int xWayRed = 1;//Steuerungsrichtung
	int xWayBlue = 1;
	
	int yWayRed = -1;
	int yWayBlue = -1;
	int yRed = 160;
	int yBlue = 150;
	
	int radius = 50;
	int speedRed = 3;
	int speedBlue = 5;
	
	int xSize = 500;
	int ySize = 550;
	
	public MoveBall(){
		
		this.setBackground(Color.WHITE);
		this.setVisible(true);
		start();
	}

	private void start() {
		Thread move = new Thread(this);
		move.start();		
	}

	public void run() {
		while (true) {
			//Randabprall für Rot
			if (xRed+radius == xSize) {
				xWayRed = -1;
			}
			if (yRed+radius == ySize) {
				yWayRed = -1;
			}
			if (xRed == 0) {
				xWayRed = 1;
			}
			if (yRed == 0) {
				yWayRed = 1;
			}
			//Randabprall für Blau
			if (xBlue+radius == xSize) {
				xWayBlue = -1;
			}
			if (yBlue+radius == ySize) {
				yWayBlue = -1;
			}
			if (yBlue == 0) {
				yWayBlue = 1;
			}
			if (xBlue == 0) {
				xWayBlue = 1;
			}
			//Kollision
			if(xRed == xBlue){
				if(yWayRed ==1){
					yWayRed = -1;
				}
			if(yWayBlue == 1){
				yWayBlue = -1;
			}
	
			}
				if(yRed+(radius) == yBlue+(radius)){
				System.out.println("Getroffen bei Y");
				xWayRed = xWayRed *(-1);
				xWayBlue = xWayBlue *(-1);
			}
					
			repaint();
			xRed += xWayRed;
			yRed += yWayRed;
			
			xBlue += xWayBlue;
			yBlue += yWayBlue;
			try {
				Thread.sleep(6);
			} 
			catch (InterruptedException exc) {
				exc.printStackTrace();
			}
		}
	}

	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.setColor(Color.RED);
		g.fillOval(xRed, yRed, radius, radius);
		g.setColor(Color.BLUE);
		g.fillOval(xRed, yBlue, 10, 10); 
		g.setColor(Color.BLUE);
		g.fillOval(xBlue, yBlue, radius, radius);
	}
}
```


----------



## MiDniGG (13. Apr 2010)

Kommt mir bekannt vor... Aber ich schreibs nochmal... :-D

Schau mal hier. Das sind recht coole Sachen, was der da gemacht hat. 
J2MeForum :: Thema anzeigen - Feuer / Explosion / Partikeleffekte / Skalieren / Physics...
Allerdings ist das für Java ME (Mobile) sollte aber nicht allzu schwer sein das auf SE umzuschreiben.

Gruß MiDniGG


----------



## iChaos (13. Apr 2010)

Danke für die Antwort^^

Jedoch habe ich keine Ahnung von Canvas oder sonst was, mir bringt der Code nicht allzuviel.
Mein Gedankengang sieht eigentlich so aus:

Überprüfen von X und Y Koordinaten der beiden Bälle und wenn sie dicht aufeinander liegen, wird die Richtung umgekehrt.

Jedoch kam ich auf keine richtige Lösung, da sich die Bälle immer übereinander bewegen. 
Wer kann mir helfen?


----------



## Michael... (13. Apr 2010)

Stecke nicht alle "Bälle" in eine Klasse, sondern verwende die Klasse MoveBall um einen Ball zu definieren. Erzeuge in einer Controlerklasse die gewünschte Anzahl von Objekten setze sie auf ein "Spielfeld" oder was auch immer. Im Controler koodinierst Du die Bewegung der Objekte und überprüfst, ob sie aneinander (d(M1,M2)<=2*r) oder an die Spielfeldbegrenzung stossen.
Ich würde zunächst mal mit einem Ball anfangen der sich alleine im Spielfeld bewegt.


----------



## Gast2 (13. Apr 2010)

Es gibt auch schon vorhandene 2D Engine die das für dich machen

Wenn du das nicht willst mache eine Klasse Ball die entweder Shape implementiert oder von eine passende vorhandene Shape die java.awt.geom schon mitbringt. Die haben meistens auch schon Methoden zur überprüfen dabei...


----------



## iChaos (13. Apr 2010)

Michael... hat gesagt.:


> Stecke nicht alle "Bälle" in eine Klasse, sondern verwende die Klasse MoveBall um einen Ball zu definieren. Erzeuge in einer Controlerklasse die gewünschte Anzahl von Objekten setze sie auf ein "Spielfeld" oder was auch immer. Im Controler koodinierst Du die Bewegung der Objekte und überprüfst, ob sie aneinander (d(M1,M2)<=2*r) oder an die Spielfeldbegrenzung stossen.
> Ich würde zunächst mal mit einem Ball anfangen der sich alleine im Spielfeld bewegt.



Mit einem Ball hab ich alles hingekriegt, er prallt auch von den Wänden ab. Das mit der Klassentrennung ist mir bewusst, ist aber auf meine Frage bezogen nicht relevant. 
Kannst du mir die Formel genäuer erklären? Werde da nicht ganz schlau, was genau gemeint ist...
thx

@SirWayne;

Werde ich gleich mal probieren


----------



## Gast2 (13. Apr 2010)

iChaos hat gesagt.:


> Mit einem Ball hab ich alles hingekriegt, er prallt auch von den Wänden ab. Das mit der Klassentrennung ist mir bewusst, ist aber auf meine Frage bezogen nicht relevant.
> Kannst du mir die Formel genäuer erklären? Werde da nicht ganz schlau, was genau gemeint ist...
> thx
> 
> ...



Klassentrennung ist immer relevant...  Du machst eine Klasse Ball (wie gesagt mit einer gescheiten Shape)... Dann musst du in MoveBall nur noch 2 Instanzen erzeugen die in paint mit g2.draw(ball1) g2.draw(ball2) malen und entsprechend deiner Logik x und y neu setzen... die shapes haben dann methoden wie inersection usw. damit findest du raus ob sie sich berühren und dann kannst du entscheiden was zu tun wäre...


----------



## ARadauer (13. Apr 2010)

wenn der Abstand der beiden Mittelpunkte, kleiner als der Radius ist, soll sich die Richtung ändern.

abstand zweier punkte koordinatensystem - Google-Suche


----------



## iChaos (14. Apr 2010)

Update!!!

-Ich kann jetzt mit Hilfe von Arrays und for-Schleife, beliebig viele Bälle erzeugen. Nun meine Frage; Wie vergleiche ich Arrays, bzw deren Koordinaten? Etwa mit equals? Hab atm keinen Plan wie ich vorgehen soll...

Main Klasse, mit Array Ausgabe!


```
public class Main extends JFrame {
	
	static int xGui = 500;
	static int yGui = 600;
	
	public Main() {
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setBackground(Color.GRAY);
		this.setSize(xGui, yGui);
		this.setResizable(false);	
		this.setLocation(50,50);
		
		Ball[] ball ={
				new Ball(xGui, yGui, 150, 150, Color.YELLOW),
				new Ball(xGui, yGui, 300, 300, Color.RED),
//				new Ball(xGui, yGui, 200, 150, Color.BLUE),
//				new Ball(xGui, yGui, 400, 150, Color.GREEN),
//				new Ball(xGui, yGui, 100, 150, Color.PINK),
//				new Ball(xGui, yGui, 90, 150, Color.CYAN),
		};
		for (int i = 0; i < ball.length; i++) {
			this.add(ball[i]);
		}
		 {
			
		}
	}
	public static void main(String[] args){
		Main gui = new Main();
		gui.setVisible(true);
	}
}
```

Thread, wo der Ball definiert wird

```
public class Ball extends JLabel implements Runnable  {
	
	private int x = 200;
	private int y = 200;
	private double speed = 5;
	private int durchmesser = 50;
	private int xDirection = 1;
	private int yDirection = 1;
	private int xGui;
	private int yGui;
	private Color farbe;
	
	public Color getFarbe() {
		return farbe;
	}

	public void setFarbe(Color farbe) {
		this.farbe = farbe;
	}

	public Ball(int xGui,int yGui, int x, int y, Color farbe){
		this.xGui = xGui;
		this.yGui = yGui;
		this.x = x;
		this.y = y;
		this.farbe = farbe;
		this.setSize(xGui, yGui);
		start();
	}

	private void start() {
		Thread thread = new Thread(this);
		thread.start();
	}
	
	public void run() {
		while(true){
			if (x+durchmesser == xGui || x == 0) {
				xDirection *=-1;
			}
			if (y+durchmesser == yGui || y == 0){
				yDirection *=-1;
			}
			
			x += xDirection*speed;
			y += yDirection*speed;
			repaint();
						
			try {
				Thread.sleep(10);
			} 
			catch (InterruptedException exc) {
				exc.printStackTrace();			
			}
			this.setLocation(x, y);
		}
	}

	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.setColor(farbe);
		g.fillOval(0, 0, durchmesser, durchmesser);
		
	}
}
```


----------

