Hello Members,

I have three balls(all JPanels) bouncing in a JFrame. Following are the files:

BouncingBalls.java:

import javax.swing.*;   
import java.awt.*;   
    
class BouncingBalls extends JFrame   
{   
  
  public BouncingBalls()
  {
      
      setResizable(false);   
      setSize(400,400);   
    
      Ball ball1 = new Ball();   
      Ball ball2 = new Ball();   
      Ball ball3 = new Ball();   
      
      ball1.add(ball2);  
      ball2.add(ball3);
      getContentPane().add(ball1);   
      setVisible(true);   
      Thread x = new Thread(ball1);
      Thread y = new Thread(ball2);
      Thread z = new Thread(ball3);
    
      x.start();
      y.start();
      z.start();
    }
  public static void main(String[] args)   
  {   
     new BouncingBalls();   
     
  }   
}

Ball.java:

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


class Ball extends JPanel implements Runnable   
{   
   private boolean xUp, yUp, bouncing;
   private int x, y, xDx, yDy;
   private final int MAX_X = 400, MAX_Y = 400;
  
  public Ball()   
  { 
     xUp = false;
     yUp = false;
     xDx = 1;
     yDy = 1;
     bouncing = true;


    setOpaque(false);   
    setPreferredSize(new Dimension( MAX_X, MAX_Y));   
  }   
  public void run()   
  {   
   while ( true ) {

         try {
            Thread.sleep( 20 );
         }

         catch ( InterruptedException exception ) {
            System.err.println( exception.toString() );
         }


         if ( xUp == true )
            x += xDx;
         else
            x -= xDx;


         if ( yUp == true )
            y += yDy;
         else
            y -= yDy;

         if ( y <= 0 ) {
            yUp = true;
            yDy = ( int ) ( Math.random() * 5 + 2 );
         }

         else if ( y >= MAX_Y - 30 ) {
            yDy = ( int ) ( Math.random() * 5 + 2 );
            yUp = false;
         }

         if ( x <= 0 ) {
            xUp = true;
            xDx = ( int ) ( Math.random() * 5 + 2 );
         }

         else if ( x >= MAX_X - 30 ) {
            xUp = false;
            xDx = ( int ) ( Math.random() * 5 + 2 );
         }

         repaint();

      }

   }

  
  public void paintComponent(Graphics g)   
  {   
   
    super.paintComponent(g);   
     if ( bouncing ) {
         g.setColor( Color.blue );
         g.fillOval( x, y, 30, 30 );
      }
 
  }   
}

My question:

How do I write a collission check between the three balls given the structure of the above two files? Specifically, in which of the above two files would the function be implemented and what would it's inputs and output be and where would the function be called?

I would be grateful for any input.

Thank you!!
sciprog1

sciprog1:

If a ball is a thread, you should implement the collision detection inside the Ball class, but you need to pass the boundary from Bouncing Ball display to it as well. Currently, it is done inside Ball class too, but the boundary is off (MAX_X and MAX_Y). The size of display panel may not be the same as the real boundary size.

Edited 6 Years Ago by Taywin: n/a

Hello Taywin,

Thanks for the reply!

If we take the case of three balls bouncing, where and how would I check for collission in the Ball class since it is a generic implementation of one ball?
Say that all three threads have started. After this point, they are all calling the run function. What I am unclear is how would I check for collission in this scenario?

If you could write a few function headers/prototypes(I can handle the inside implementation) in my code for handling collission detection, that would be very helpful.

Thank you!!
sciprog1

OK, this is a different story. You need to have shared variables for each ball location in your BouncingBall class. Those variables can be read by any Ball class, but only its own variable location is written. This means, you need to take the x, y variables of the ball out and make them shared variables. Because of doing so, you would be able to initiate starting location of all balls at different location. You may keep the xDx, yDy, xUp, and yUp in the Ball class. An easier way to make it as shared variable is to bring the Ball class inside and becomes the BouncingBall's subclass. Just don't forget to synchronized the shared variables whenever you read/write them.

Also, you need to pull out the part where the ball detect the boundary collision and make it a private method. Then implement another method that read the location x,y of other balls (read all shared variables which are not the Ball itself), so you would have 2 different methods to deal with both collision. You may need an identifier for your Ball thread (ID) in order to identify which shared variables are owned by the Ball.

public void run() {   
    while ( true ) {
      try {
        Thread.sleep( 20 );
      }
      catch ( InterruptedException exception ) {
        System.err.println( exception.toString() );
      }

      // check for ball collision first, then check for boundary collision
      // these methods may have changed the value of your
      // xDx, yDy, xUp, and yUp
      if ( xUp == true )
        x += xDx;
      else
        x -= xDx;
      if ( yUp == true )
        y += yDy;
      else
        y -= yDy;

      // the below code portion is the boundary collision detection
      // take them out to another method for computation
      if ( y <= 0 ) {
        yUp = true;
        yDy = ( int ) ( Math.random() * 5 + 2 );
      }
      else if ( y >= MAX_Y - 30 ) {
        yDy = ( int ) ( Math.random() * 5 + 2 );
        yUp = false;
      }
      if ( x <= 0 ) {
        xUp = true;
        xDx = ( int ) ( Math.random() * 5 + 2 );
      }
      else if ( x >= MAX_X - 30 ) {
        xUp = false;
        xDx = ( int ) ( Math.random() * 5 + 2 );
      }

      // render the new location
      repaint();
    }
  }

Hello Taywin,

Thanks for the detailed reply!! That helped a lot.

Regards,
sciprog1

This article has been dead for over six months. Start a new discussion instead.