i was test collision between ball and box. i have a ball and long rect(platform) on screen. the collision part works fine. but i want to test where the ball is touch the platform. so if ball touch the ball from left or right or top or bottom. but when i run this. but it is not seem to be going in any of the inner if statments.

x = ball x
y = ball y
radius = ball width and height
rx = rect x
ry = rect y
rheight = rect height
rwidth = rect width


main game loop:

x += dx;   //keep the ball moving so i can test the collision
y += dy;

 //collsion between ball and box
 if(x+radius > rx && x < rx+rwidth)
 {
    if(y+radius > ry && y < ry+rheight)
    {
      if(y+radius == ry) 
        {  
        System.out.println("top");
        }
       else  if(y == ry+rheight) 
        {
         System.out.println("bottom");
        }
       else if(x+radius == rx)
            {
        System.out.println("left");
            }
         else if(x == rx+rwidth)
        {
         System.out.println("right");
        }
   }
}

With all those == tests you are testing for exactly just touching, but depending on dx, dy, and the whole history of the movement an exact touch may be unlikely. (If any of the variables is floating pint an == is even more unlikely.) You coud try using >= or <= instead of == so you test for touching-or-overlapping.

Edited 3 Years Ago by JamesCherrill

i change the code and now it now its only goes to if statment collision left or right. but never in top or bottom.

any idea how can i change this so it will tell me where the ball vaoolision is.

ry,rx,rwidth,rheight = rect postion etc

if (y+height > ry && y < ry+rheight)  //left and right
            {
                if(x+width > rx && x < rx+rwidth) //top and bottom
                {
                    if(x+width <= rx+rwidth/2)
                    {
                        System.out.println("collision left");
                    }
                    else if(x >= rx+(width/2))        
                    {
                        System.out.println("collision right");
                    }
                    else if(y+height <= y+height/2)
                    {
                        System.out.println("collision top");
                    }
                    else if(y >= y+height/2)
                    {
                        System.out.println("collision bottom");
                    }

                }
            }

yeah.... that isnt working. so i want to try some thing else.

1st check for collision

if(this.getBounds_ball().intersects(this.getBounds_rect()))  

now in side that if statment i can get the over laping x and y. so i know where did the ball collision

xOverlap = getBounds_ball().getX() - getBounds_rect().getX();  
yOverlap = getBounds_ball().getY() - getBounds_rect().getY();  

You can't check for a ball touching something just with its bounding Rectangle - that includes the corners that are not part of the circle, so you will get false positives. Thta's even more important for collisions between two balls, or more complex-shaped objects.
A good compromise between speed and correctness is to maintain a bounding Rectangle and a Shape for each object. You can do a very fast check on the bounds first, then if that looks like a collision you can get the intersection of the two Shapes to see if they really touched (eg: get the Shape's Path2Ds, translate to the correct positions, get the corresponding Areas, intersect them - very accurate but relatively expensive). You can then use that intersection Area to see which side (or corner - see below) of your box it contains. You'll find the methods you need in Shape, Line2D, Path2D and Area.
ps: When a ball collides with box it may hit a corner, not a side. In fact, as the ball gets bigger relative to the box the more likely it is that it will hit a corner not a side.
pps: You can use the ball's velocity (dx, dy) to quickly eliminate at least two sides - eg if the ball is moving downwards (dy>0) it can't collide with the bottom of the box!

p...ps Is this an "official" project that you will submit for marking, or is this just something you are doing for fun and your own skill development?

Edited 3 Years Ago by JamesCherrill

this is a project for fun and this is my first time learning about collision.

its ok if it doesnt includes the corners of circles. bc this is my 1st time i want to keep it simple. later i can go back and focus on correctness.

i am srry, if i sould like iam saying same thing again but iam having really really really difficult time learning about this by myself.

i know how to test for collision between ball and rect. this works fine for now.

if(this.getBounds_ball().intersects(this.getBounds_rect()))  

the problem is that: this if statment doesnt tell you where the ball is touching from. it only tell you when ball is touching the rect.

i want:
if ball intersects rect from top than i want ball to go up.
if ball intersect rect from bottom than i want ball to go down.
if ball intersect rect from left than i want ball to go left.
if ball intersect rect from right than i want ball to go right.

so this will tell me if its touching:
if(this.getBounds_ball().intersects(this.getBounds_rect()))

but this doesnt tell where the ball is touching the rect from. so i cant really move the ball bc i dont know if i want to move the ball up,down,right,or left.

is there some function i can use inside intersect() if statment. that will return or tell me where the ball is touching from.

or if there is way?

Here's a way to do it that will be right quite a ot of the time...

Get the Line2D that goes from the center of the ball to the center of the rect.
The Rect has 4 Line2Ds that form its top, botton. left side, right side.
There's a method in Line2D to tell if two Line2Ds intersect.
If the first line intersects the top line of the rect then the ball is probably touching the top
If the first line intersects the left line of the rect then the ball is probably touching the left side
etc
Not perfect - but probably good enough for now

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