user2919717 user2919717 - 16 days ago 12
Java Question

Simple bouncing ball program in Java

I am trying to code a simple bouncing ball program. It has a rectangle and two balls in it. The balls have to bounce off the walls of the rectangle (I have coded that succesfull) and they also have to bounce off of each other. This is where I need your help. When I give the balls the same speed, they bounce fine and the program works, but I have to give the balls random speeds. When I do this the balls won't bounce anymore and just move through each other.

import java.applet.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

public class BallApplet2 extends Applet implements Runnable
{
// Begin variabelen
int x_pos1 = 150;
int y_pos1 = 200;
int radius1 = 20;

int x_pos2 = 250;
int y_pos2 = 200;
int radius2 = 20;

private float ballspeedx1 = -3;
private float ballspeedy1 = 0;

private float ballspeedx2 = 3;
private float ballspeedy2 = 0;


public void init() {}

public void start() {
Thread th = new Thread (this);
th.start (); }
public void stop() {}
public void destroy() {}
public void run () {
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
while (true)
{
x_pos1 += ballspeedx1;
y_pos1 += ballspeedy1;
x_pos2 += ballspeedx2;
y_pos2 += ballspeedy2;


repaint();
// als x_pos < 100 is draait de richting van de bal om
if (x_pos1 < 100) {
ballspeedx1 = -ballspeedx1;
x_pos1 = 100;
}
if (x_pos2 < 100) {
ballspeedx2 = -ballspeedx2;
x_pos2 = 100;
}
// als x_pos > 300 is draait de richting van de bal om
if (x_pos1 > 300) {
ballspeedx1 = -ballspeedx1;
x_pos1 = 300;
}
if (x_pos2 > 300) {
ballspeedx2 = -ballspeedx2;
x_pos2 = 300;
}
// als de x van de rode bal gelijk is aan de x en twee keer de straal van de blauwe bal, draaien beide ballen om.
if (x_pos1 == x_pos2 + 40) {
ballspeedx1 = -ballspeedx1;
ballspeedx2 = -ballspeedx2;
}
// als de x van de blauwe bal gelijk is aan de x van de rode bal, draaien beide ballen om.
if (x_pos2 == x_pos1 ) {
ballspeedx1 = -ballspeedx1;
ballspeedx2 = -ballspeedx2;
}
// als de x en twee keer de straal van de rode bal gelijk is aan de x van de blauwe bal, draaien beide ballen om.
if (x_pos1 + 40 == x_pos2) {
ballspeedx1 = -ballspeedx1;
ballspeedx2 = -ballspeedx2;
}
// als de x en twee keer de straal
if (x_pos2 + 40 == x_pos1) {
ballspeedx1 = -ballspeedx1;
ballspeedx2 = -ballspeedx2;
}

try { Thread.sleep (20); }



catch (InterruptedException ex) {}

Thread.currentThread().setPriority(Thread.MAX_PRIORITY); }}

public void paint (Graphics g) {

g.setColor (Color.red);
g.fillOval (x_pos1 - radius1, y_pos1 - radius1, 2 * radius1, 2 * radius1);

g.setColor (Color.blue);
g.fillOval (x_pos2 - radius2, y_pos2 - radius2, 2 * radius2, 2 * radius2);


g.setColor(Color.black);
g.drawLine(80,80,80,320); // lijn links
g.drawLine(320,80,320,320); // lijn rechts
g.drawLine(80,80,320,80); // lijn boven
g.drawLine(80,320,320,320); // lijn onder
}




// Einde eventmethoden


}


Does anyone have a solution? If so try to keep it as simple as possible please :)

Answer

These 4 conditions appear to concern themselves with detecting a collision

  if (x_pos1 == x_pos2 + 40) {
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;
  }
  if (x_pos2 == x_pos1 ) {
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;
  }
  if (x_pos1 + 40 == x_pos2) {
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;  
  }  
  if (x_pos2 + 40 == x_pos1) {
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;  
  }

But they all ask if objects are at exact positions relative to other objects rather than within a range. Remember because this sort of program runs in time jumps an object may be partially within annother when the collision occurs, Changing all 4 of these conditions to just this one condition solves the problem

  if (Math.abs(x_pos2-x_pos1)<radius1+radius2){
    ballspeedx1 = -ballspeedx1;
    ballspeedx2 = -ballspeedx2;
  }

This rather than asking if the balls at specific distances from each other asks if then are overlapping at all, which provides a much safer test.

Obviously you know that these simple reverse velocity collisions are not physically correct, but an additional thing to watch out for is if a collision occurs in an overlap and (for whatever reason) the two objects aren't brought out of collision in the next time step, then annother collision occures, once this happens the two balls seem to "stick together". This can be resolved by physically moving the objects out of collision, then applying the velocity changes. This problem happens a lot with non elastic collisions but can also occure when multiple bodies collide at the same time.

Comments