2D Collision checking in applet?

  • (2 Pages)
  • +
  • 1
  • 2

15 Replies - 6220 Views - Last Post: 10 February 2011 - 11:34 PM Rate Topic: -----

#1 fig79   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 75
  • Joined: 25-February 09

2D Collision checking in applet?

Posted 01 February 2011 - 02:41 AM

How to checking for collision between 2D objects in applet?
This is my code.
import java.awt.*;
import java.util.*;
import java.applet.*;

public class Main extends Applet implements Runnable
{
	Thread th;

	//double buffering
	private Image dbImage;
	private Graphics dbg;

	//Reference
	private Ball redBall;
	private Ball blueBall;

	public void init()
	{
		setBackground(Color.black);
		redBall = new Ball(45, 20, 10, 1, 1, Color.red); 
		blueBall = new Ball(390, 345, 10, -1, -1, Color.blue);
	}

	public void start()
	{
		th = new Thread (this);
		th.start ();
	}

	public void stop()
	{
		th.stop();
	}

	public void destroy()
	{
		th.stop();
	}

	public void run()
	{
		Thread.currentThread().setPriority(Thread.MIN_PRIORITY);		
		while(true)
		{
		   redBall.moveBall();
		   blueBall.moveBall();
			
		   repaint();

		   try
		   {
		      Thread.sleep (15);
		   }
		   catch (InterruptedException ex)
		   {
		       
		   }
		   Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
		}
	}

	public void paint(Graphics g)
	{
	   redBall.drawBall(g);
	   blueBall.drawBall(g);
	}


	public void update(Graphics g)
	{
		if (dbImage == null)
		{
			dbImage = createImage (this.getSize().width, this.getSize().height);
			dbg = dbImage.getGraphics ();
		}
		dbg.setColor (getBackground ());
		dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);

		dbg.setColor (getForeground());
		paint (dbg);

		g.drawImage (dbImage, 0, 0, this);
	}
}



import java.awt.*;
import java.applet.*;

public class Ball
{
	private int xpos;
	private int ypos;
	private int radius;
	private int vx; //vector x
	private int vy; //vector y
	Color color;
	
	public Ball(int x, int y, int r, int vx, int vy, Color color)
	{
		xpos = x;
		ypos = y;
		radius = r;
		this.vx = vx;
		this.vy = vy;
		this.color = color;
	}

	public void drawBall(Graphics g)
	{
		g.setColor (color);
		g.fillOval (xpos - radius, ypos - radius, 2 * radius, 2 * radius);
	}

	public void moveBall()
	{
		xpos += vx;
		ypos += vy;
	}
}



Is This A Good Question/Topic? 0
  • +

Replies To: 2D Collision checking in applet?

#2 japanir   User is offline

  • jaVanir
  • member icon

Reputation: 1014
  • View blog
  • Posts: 3,025
  • Joined: 20-August 09

Re: 2D Collision checking in applet?

Posted 01 February 2011 - 02:54 AM

You can represent each objects with a Rectangle Object (based on the object's x, y, width and height)
and then just use the intersects(Rectangle r) method of Rectangle.
here is the API:
http://download.orac....awt.Rectangle)
Was This Post Helpful? 0
  • +
  • -

#3 Dogstopper   User is offline

  • The Ninjaducky
  • member icon

Reputation: 2975
  • View blog
  • Posts: 11,224
  • Joined: 15-July 08

Re: 2D Collision checking in applet?

Posted 01 February 2011 - 04:14 AM

I have a tutorial on Bounding boxes here:
http://www.dreaminco...bounding-boxes/

It shows rectangular bounding boxes, so if you need something more accurate, like circular, you can use the distance formula to check if the edge of another ball is inside of the other.
Was This Post Helpful? 0
  • +
  • -

#4 fig79   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 75
  • Joined: 25-February 09

Re: 2D Collision checking in applet?

Posted 01 February 2011 - 05:25 AM

View Postjapanir, on 01 February 2011 - 02:54 AM, said:

You can represent each objects with a Rectangle Object (based on the object's x, y, width and height)
and then just use the intersects(Rectangle r) method of Rectangle.
here is the API:
http://download.orac....awt.Rectangle)


I made some change in Ball.class
       private int xpos; --> public int xpos;
       private int xpos; --> public int ypos;



and I added boolean method in Main.class
Rectangle rRed;
Rectangle rBlue;

public boolean collide()
	{
		rRed = new Rectangle(redBall.xpos, redBall.ypos, 10, 10);
		rBlue = new Rectangle(blueBall.xpos, blueBall.ypos, 10, 10);		
                return Red.intersection(rBlue); //incompatible types        
	}



How to make Red.intersection(rBlue) suitable for boolean?
What I have to do?

View PostDogstopper, on 01 February 2011 - 04:14 AM, said:

I have a tutorial on Bounding boxes here:
http://www.dreaminco...bounding-boxes/

It shows rectangular bounding boxes, so if you need something more accurate, like circular, you can use the distance formula to check if the edge of another ball is inside of the other.


Thanks, I will check it.

This post has been edited by fig79: 01 February 2011 - 05:26 AM

Was This Post Helpful? 0
  • +
  • -

#5 japanir   User is offline

  • jaVanir
  • member icon

Reputation: 1014
  • View blog
  • Posts: 3,025
  • Joined: 20-August 09

Re: 2D Collision checking in applet?

Posted 01 February 2011 - 06:35 AM

use intersects(Rectangle r) it is a boolean method:
return rRed.intersects(rBlue);

Was This Post Helpful? 0
  • +
  • -

#6 fig79   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 75
  • Joined: 25-February 09

Re: 2D Collision checking in applet?

Posted 01 February 2011 - 11:42 AM

View Postjapanir, on 01 February 2011 - 06:35 AM, said:

use intersects(Rectangle r) it is a boolean method:
return rRed.intersects(rBlue);

Thanks japanir.
This is my updated sourecode, it's working.
When two objects(red ball & blue ball) collide, they are stop.
-----------------
I have some question:
1. rRed.intersects(rBlue) is equal result with rBlue.intersects(rRed) ?
2. I already tried to add one more ball's object:
whiteBall = new Ball(100, 250, 10, -1, 1, Color.white)
public boolean intersects()
	{
		rRed = new Rectangle(redBall.xpos, redBall.ypos, 15, 15);
		rBlue = new Rectangle(blueBall.xpos, blueBall.ypos, 15, 15);
		rWhite = new Rectangle(whiteBall.xpos, blueBall.ypos, 15, 15);		
		return (rBlue.intersects(rRed) || rBlue.intersects(rWhite) || rRed.intersects(rWhite) );
	}


But it's not working, in some case they stop moving even though there is no collision.
How to solve this problem?

Bellow is my updated sourecode.
It's working for just 2 object.

Main.class
import java.awt.*;
import java.util.*;
import java.applet.*;

public class Main extends Applet implements Runnable
{
	Thread th;
	Rectangle rRed;
	Rectangle rBlue;	

	//double buffering
	private Image dbImage;
	private Graphics dbg;

	//Reference
	private Ball redBall;
	private Ball blueBall;	

	public void init()
	{
		setBackground(Color.black);		
		redBall = new Ball(70, 80, 10, 1, 1, Color.red); 
		blueBall = new Ball(150, 245, 10, 1, -1, Color.blue);		
	}

	public void start()
	{
		th = new Thread (this);
		th.start ();
	}

	public void stop()
	{
		th.stop();
	}

	public void destroy()
	{
		th.stop();
	}

	public boolean intersects()
	{
		rRed = new Rectangle(redBall.xpos, redBall.ypos, 15, 15);
		rBlue = new Rectangle(blueBall.xpos, blueBall.ypos, 15, 15);		
		return rRed.intersects(rBlue);		
	}

	public void run()
	{
		Thread.currentThread().setPriority(Thread.MIN_PRIORITY);		
		while(true)
		{
			if(!intersects())
			{
				redBall.moveBall();
				blueBall.moveBall();						
			}
									
			repaint();

			try
			{
				Thread.sleep (10);
			}
			catch (InterruptedException ex)
			{
				
			}

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

	public void paint(Graphics g)
		{
			redBall.drawBall(g);
			blueBall.drawBall(g);			
		}


	public void update(Graphics g)
	{
		if (dbImage == null)
		{
			dbImage = createImage (this.getSize().width, this.getSize().height);
			dbg = dbImage.getGraphics ();
		}
		dbg.setColor (getBackground ());
		dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);

		dbg.setColor (getForeground());
		paint (dbg);

		g.drawImage (dbImage, 0, 0, this);
	}
}



Ball.class
import java.awt.*;
import java.applet.*;
import java.util.*;

public class Ball
{
	public int xpos;
	public int ypos;
	private int radius;
	public int vx; //vector x
	public int vy; //vector y
	
	//applet size width=400 height=400
        private int rightOut = 390;
	private int leftOut = 10;
	private int upOut= 10;
	private int bottomOut = 390;
	Color color;
	
	//random 
	Random rnd = new Random ();
		
	public Ball(int x, int y, int r, int vx, int vy, Color color)
	{
		xpos = x;
		ypos = y;
		radius = r;
		this.vx = vx;
		this.vy = vy;
		this.color = color;
	}

	public void drawBall(Graphics g)
	{
		g.setColor (color);
		g.fillOval (xpos - radius, ypos - radius, 2 * radius, 2 * radius);
	}
		
	public void moveBall()
	{
		if(xpos < leftOut)
		{
		       //change direction of vector x	
                       vx = rnd.nextInt(2) + 1;		
		}
		else if(xpos > rightOut)
		{
		       //change direction of vector x	
                       vx = -(rnd.nextInt(2) + 1);	
		}		
		else if(ypos > bottomOut)
		{
		       //change direction of vector y	
                       vy = -(rnd.nextInt(2) + 1);		
		}
		else if(ypos < upOut)
		{
		       //change direction of vector y	
                       vy = rnd.nextInt(2) + 1;		
		}		
		
		xpos += vx;
		ypos += vy;		
	}	
}


This post has been edited by fig79: 01 February 2011 - 11:47 AM

Was This Post Helpful? 0
  • +
  • -

#7 japanir   User is offline

  • jaVanir
  • member icon

Reputation: 1014
  • View blog
  • Posts: 3,025
  • Joined: 20-August 09

Re: 2D Collision checking in applet?

Posted 01 February 2011 - 04:45 PM

You can add an intersects(Ball B) method to your Ball class.
Then check for each Ball object if it collides with other ball and act accordingly.
Was This Post Helpful? 0
  • +
  • -

#8 fig79   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 75
  • Joined: 25-February 09

Re: 2D Collision checking in applet?

Posted 04 February 2011 - 05:52 AM

View Postjapanir, on 01 February 2011 - 04:45 PM, said:

You can add an intersects(Ball B) method to your Ball class.
Then check for each Ball object if it collides with other ball and act accordingly.


I have no idea how to do it.
Could you tell me how?
Was This Post Helpful? 0
  • +
  • -

#9 macosxnerd101   User is offline

  • Games, Graphs, and Auctions
  • member icon




Reputation: 12800
  • View blog
  • Posts: 45,992
  • Joined: 27-December 08

Re: 2D Collision checking in applet?

Posted 04 February 2011 - 09:05 AM

Start off the method to accept a Ball parameter.
public boolean intersects(Ball other){}



Now do you understand bounding boxes? What we want to do is compare to see if the param's top-left (x,y) and bottom-right (x,y) coordinates fall within the top-left and bottom-right (x,y) coordinates of this Ball. Think about two squares or rectangles intersecting.
Was This Post Helpful? 0
  • +
  • -

#10 japanir   User is offline

  • jaVanir
  • member icon

Reputation: 1014
  • View blog
  • Posts: 3,025
  • Joined: 20-August 09

Re: 2D Collision checking in applet?

Posted 04 February 2011 - 09:11 AM

Update your ball class:
//this is the same Ball class you created
public class Ball {
   ...
   //add Rectangle object variable:
   private Rectangle rect;
   ...
  
   public Ball(int x, int y, int radius){
      rect = new Rectangle(x, y, radius, radius);
   }

   //just add collision check method:
   public boolean isCollision(Ball b2){
       return (rect.intersects(b2.rect));
   }
}       

In your main class simply check in the loop:
if(redBall.isCollision(blueBall)){
   //handle..
}

This post has been edited by japanir: 04 February 2011 - 09:12 AM

Was This Post Helpful? 0
  • +
  • -

#11 fig79   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 75
  • Joined: 25-February 09

Re: 2D Collision checking in applet?

Posted 04 February 2011 - 11:12 AM

@macosxnerd101
Yes I understood, thank you.

@japanir
I already updated my source according to your explanation.
No more stopping again although there is no collision.
But, the problem now, the balls can not stop although there is collision.
What's wrong with my source. could you tell me please?

//Ball.class
private Rectangle rect;
public Ball(int x, int y, int r, int vx, int vy, Color color)
{
	xpos = x;
	ypos = y;
	radius = r;
	this.vx = vx;
	this.vy = vy;
	this.color = color;
	rect = new Rectangle(x, y, radius, radius);
}

public boolean isCollision(Ball b2)
{
	return (rect.intersects(b2.rect));
}



//Main.class
public void run()
	{
		Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
		
		while(true)
		{
			if((!redBall.isCollision(blueBall)) || (!redBall.isCollision(whiteBall)) ||
				(!blueBall.isCollision(whiteBall)))
			{
				redBall.moveBall();
				blueBall.moveBall();	
				whiteBall.moveBall();			
			}
									
			repaint();

			try
			{
				Thread.sleep (10);
			}
			catch (InterruptedException ex)
			{
				
			}

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

	}


Was This Post Helpful? 0
  • +
  • -

#12 japanir   User is offline

  • jaVanir
  • member icon

Reputation: 1014
  • View blog
  • Posts: 3,025
  • Joined: 20-August 09

Re: 2D Collision checking in applet?

Posted 04 February 2011 - 11:20 AM

If you create more than 2 balls better use a Collection to store them and then iterate that collection to invoke methods.
What initial x,y values does your balls get? if there is a collision at the begining they won't move.
Also, I would suggest a better collision handling.
if there is a collision, the dx\dy of the colliding balls should be changed. to simply stop them, change the collided balls dx and dy to 0.
Was This Post Helpful? 0
  • +
  • -

#13 fig79   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 75
  • Joined: 25-February 09

Re: 2D Collision checking in applet?

Posted 04 February 2011 - 10:49 PM

View Postjapanir, on 04 February 2011 - 11:20 AM, said:

If you create more than 2 balls better use a Collection to store them and then iterate that collection to invoke methods.
What initial x,y values does your balls get? if there is a collision at the begining they won't move.
Also, I would suggest a better collision handling.
if there is a collision, the dx\dy of the colliding balls should be changed. to simply stop them, change the collided balls dx and dy to 0.


rect = new Rectangle(xpos, ypos, radius, radius);



xpos and ypos value are not update.
Both of them still the same value although the ball is moving.
Was This Post Helpful? 0
  • +
  • -

#14 japanir   User is offline

  • jaVanir
  • member icon

Reputation: 1014
  • View blog
  • Posts: 3,025
  • Joined: 20-August 09

Re: 2D Collision checking in applet?

Posted 05 February 2011 - 02:01 PM

You can create the Rectangle Objects when checking for colisions. thus, the x,y values will be the updated values.
public boolean isCollision(Ball B)/>{
  return (this.getRect().intersects(b.getRect());
}

define a getRect() method to return the current Rectengle from the current x,y values.
Was This Post Helpful? 0
  • +
  • -

#15 fig79   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 75
  • Joined: 25-February 09

Re: 2D Collision checking in applet?

Posted 10 February 2011 - 10:53 PM

View Postjapanir, on 05 February 2011 - 02:01 PM, said:

You can create the Rectangle Objects when checking for colisions. thus, the x,y values will be the updated values.
public boolean isCollision(Ball B)/>{
  return (this.getRect().intersects(b.getRect());
}

define a getRect() method to return the current Rectengle from the current x,y values.


In Ball.class
public boolean isCollision(Ball b2)
	{
		rect = new Rectangle(xpos, ypos, 15, 15);
		return (this.getRect().intersects(b2.getRect()));
        }

public int getRect()
	{
		return xpos;
	}



But error :
Ball.java:44: int cannot be dereferenced
		return (this.getRect().intersects(b2.getRect()));
		                      ^


This post has been edited by fig79: 10 February 2011 - 11:13 PM

Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2