Bouncing ball with collision detection in Java

This program shows the same ball simulation with collision detection using “Rectangle” class of java.
Eg:-It works like this,
“r1.intersects(Rectangle r2)” method checks whether the r1 touches the r2.I have made special conditions for ball deflection based on the side it collides.

Class 1:Base Frame with some UI components

package ball_bounds;
import javax.swing.*;

import ball_bounds.canvas.ball;
import java.awt.*;
import java.awt.event.*;
public class base_frame extends JFrame implements ActionListener
{

	canvas draw_panel;
	JButton b_changebg,b_add,b_remove;
	JPanel ui_panel;
	base_frame()
	{
		super("Ball Bounds");

		//our UI panel which contains gui comps
		ui_panel=new JPanel();
		b_changebg=new JButton("Change Background");
		b_add=new JButton("Add");
		b_remove=new JButton("Remove");

		//add listeners
		b_changebg.addActionListener(this);
		b_add.addActionListener(this);
		b_remove.addActionListener(this);

		setLayout(new FlowLayout());
		draw_panel=new canvas();

		//adding to UI panel
		ui_panel.add(b_changebg);
		ui_panel.add(b_add);
		ui_panel.add(b_remove);

		//adding to our JFrame
		add(draw_panel);
		add(ui_panel);

		setSize(540,470);
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	public static void main(String[] args)
	{
		new base_frame();
	}
	public void actionPerformed(ActionEvent ae)
	{
		if(ae.getSource()==b_changebg)
		{
				draw_panel.changeBGcolor();
		}
		else
		if(ae.getSource()==b_add)
		{
			//adds a ball of size 20;
			draw_panel.addBall(20);
			System.out.println("Added a ball");
		}
		else
		if(ae.getSource()==b_remove)
		{
				draw_panel.removeBall();
				System.out.println("Removed a ball");
		}
	}
}

Class 2:Our Drawing canvas

package ball_bounds;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class canvas extends JComponent implements KeyListener,MouseMotionListener
{
	//display details
	private final int width=512;
	private final int height=384;
	boolean bg_change=false;
	int color=254,incr=1;

	//a  ball array
	ArrayList ballarray;

	//my custom box
	My_box b1;

	canvas()
	{
		ballarray=new ArrayList(1);
		b1=new My_box(0,0,120,20);

		addKeyListener(this);
		addMouseMotionListener(this);

		setPreferredSize(new Dimension(width,height));
		setFocusable(true);
	}

	//change to background color dynamically(default:white)
	public void changeBGcolor()
	{
		if(bg_change)
		{
			bg_change=false;
		}
		else
		{
			bg_change=true;
		}
	}

	//add a new ball by passing a "ball" class instance
	public void addBall(int size)
	{
		//added to the arraylist
		ballarray.add(new ball(size));
	}

	public void removeBall()
	{
		if(!ballarray.isEmpty())
		{
			ballarray.remove(ballarray.size()-1);
		}
	}
	public int getBallCount()
	{
			return ballarray.size();
	}
	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);

		//fill rect
		if(bg_change)
		{
			color=color-incr;

			 if(color<1)                         
                        {
                                    incr=-1;                         
                        }             
                         if(color>250)
			{
				incr=1;
			}
			g.setColor(new Color(color,color,color));
		}
		else
		{
			color=254;
			g.setColor(Color.WHITE);
		}
		g.fillRect(0,0,getWidth(),getHeight());

		//my box
		g.setColor(Color.BLACK);
		b1.drawBox(g);

		try{
			Thread.sleep(5);
			for(ball temp_ball:ballarray)
			{
				//drawing the ball using "drawBall(Graphics g,boolean)".
				//boolean is for displaying ball's bounding rectangle which deals with collision
				temp_ball.drawBall(g,false);

				//checking for collision with our movable pad
				temp_ball.collision(b1);
			}
			repaint();//calls the paint method

		}catch(Exception e)
		{
			System.out.println(e);
		}
	}

	//keyboard call-back methods
	public void keyPressed(KeyEvent ke)
	{
		if(ke.getKeyCode()==KeyEvent.VK_RIGHT)//increase x
		{

			b1.translate(10,0);
		}
		else
		if(ke.getKeyCode()==KeyEvent.VK_LEFT)
		{
			b1.translate(-10,0);
		}
       	}
	public void keyReleased(KeyEvent ke)
	{
	}
	public void keyTyped(KeyEvent ke)
	{

	}

	//mouse call-back methods

	public void mouseMoved(MouseEvent me)
	{
		//move the rectangle box too
		b1.setLocation(me.getX(),me.getY());
	}
	public void mouseDragged(MouseEvent me)
	{

	}

	//Ball inner-class
	class ball
	{
		private int x_pos=0;
		private int y_pos=0;
		private int dir_x=1;
		private int dir_y=1;
		private int size=0;

		ball(int size)
		{
			this.size=size;
		}

		private void calculate_direction()
		{
			//move the ball
			x_pos=x_pos-dir_x;
			y_pos=y_pos-dir_y;

			//for X-direction
			if(x_pos<0)
                        { 		       
                            x_pos=0; 	
          		    dir_x=-1;//incr   
                        }
                        else   
                       if(x_pos+size>getWidth())
			{
				 dir_x=1;//decr
			}

			//for Y-direction
			if(y_pos<0)  
                        {  
                                 y_pos=0;     
                             dir_y=-1;//incr                         

                        }                         
                         else                                            
                         if(y_pos+size>getHeight())
			{
				dir_y=1;//decr
			}
		}

		public void changeDirection_Y()
		{
             		if(dir_y==-1)
			{
				dir_y=1;
			}
			else
			{
				dir_y=-1;
			}
		}

		public void changeDirection_X()
		{
			if(dir_x==-1)
			{
				dir_x=1;
			}
			else
			{
				dir_x=-1;
			}
		}

		public void drawBall(Graphics g,boolean bound)
		{
			calculate_direction();
			g.setColor(Color.BLUE);
			g.fillOval(x_pos,y_pos,size,size);

			if(bound)
			{
				g.drawRect(x_pos,y_pos,size,size);
			}
		}

		public Rectangle getRectBounds()
		{
			return new Rectangle(x_pos,y_pos,size,size);
		}

                //this method is called for all balls and checked whether it touches the rect.if so,the ball's direction gets changed accordingly.
		public void collision(My_box rect)
		{
                           //if ball collides with top/bottom part of the rect
			if(this.getRectBounds().intersectsLine(rect.x,rect.y,rect.x+rect.width,rect.y) ||
                           this.getRectBounds().intersectsLine(rect.x,rect.y+rect.height, rect.x+rect.width,rect.y+rect.height))
			{

				changeDirection_Y();//reverses the direction along Y

			}

			  //if ball collides with left/right part of the rect
			if(this.getRectBounds().intersectsLine(rect.x,rect.y    ,    rect.x,rect.y+rect.height) ||
                           this.getRectBounds().intersectsLine(rect.x+rect.width,rect.y  ,   rect.x+rect.width,rect.y+rect.height))
			{
				changeDirection_X();//reverses the direction along X

			}

		}
	}
}

Class 3:Our “My_box ” class.
This class extends Rectangle class.It is written in separate class just for future scalability.nothing specific

package ball_bounds;
import java.awt.*;
import java.awt.event.*;
class My_box extends Rectangle
{
	//default vars
	/*
	 * x,y,width,height
	 */
	My_box(int x1,int y,int width,int height)
	{
		super(x1,y,width,height);
	}

	public void drawBox(Graphics g)
	{
		g.setColor(Color.BLACK);
		g.fillRect(x,y,width,height);
	}
}

This is the Screenshot

Screenshot:

About PraveenMax
My Interests: ------------------ Programming , Drawing & Music

2 Responses to Bouncing ball with collision detection in Java

  1. Wiksiloh says:

    Cool… I also wrote a program like this

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: