Circle1 (blue) is moving and its X and Y bounds are the screen (meaning it bounces off the walls).

Circle2 (black) is stationary. Circle1(blue) is supposed to bounce off of Circle2 without intersecting, regardless of the collision point. As you can see on the image below, the blue circle bounces off properly only at the blue arrow spots, otherwise(red arrows), blue ball goes INSIDE the black circle, gets stuck in there for a second and then gets out.

I have no idea why this is happening. Please take a look at my code and help me out. Thanks.

public void handle(ActionEvent t) {
                if (counter++ % 5 == 0) {
                    // Moves the ball depending on the values of X and Y
                    circle.setLayoutX(circle.getLayoutX() + X); //velocity
                    circle.setLayoutY(circle.getLayoutY() + Y); //velocity

// Bounce off the walls (working perfectly)
                    final Bounds bounds = canvas.getBoundsInLocal();
                    boolean leftWall = circle.getLayoutX() <= (bounds.getMinX() + circle.getRadius());
                    boolean topWall = circle.getLayoutY() <= (bounds.getMinY() + circle.getRadius());
                    boolean rightWall = circle.getLayoutX() >= (bounds.getMaxX() - circle.getRadius());
                    boolean bottomWall = circle.getLayoutY() >= (bounds.getMaxY() - circle.getRadius());


//Collision between circle1 and circle2 (stationary black circle.                                
                    double dx = circle.getLayoutX() - circle2.getLayoutX();
                    double dy = circle.getLayoutY() - circle2.getLayoutY();
                    double radii = circle.getRadius() + circle2.getRadius();

                    if ( (dx * dx) + (dy * dy) <= radii * radii) {
                        X = X * -1; //X gets inverted to change direction


 //The code below is working perfectly.
                    // If the bottom or top wall has been touched, the ball reverses direction.
                    if (bottomWall || topWall) {

                        Y = Y * -1;
                        //circle.setLayoutY(circle.getLayoutY() - 50); - Wasn't working. Had to create X and Y to fix the problem.

                    // If the left or right wall has been touched, the ball reverses direction.
                    if (leftWall || rightWall) {
                        X = X * -1;



P.S. Apologies for the amazing paint skills :D

  • \$\begingroup\$ It seems you only invert the X velocity? X = X * -1; \$\endgroup\$
    – ThorinII
    Nov 20, 2013 at 0:38
  • \$\begingroup\$ Yes. if I also invert Y, the ball simply goes backwards, then upwards to the same spot and gets stuck in that small range forever. I tried only reversing Y, and not X, but that didn't help solve the problem. \$\endgroup\$
    – Gregg1989
    Nov 20, 2013 at 0:39
  • \$\begingroup\$ You need to calculate a collision normal, and reflect the velocity across that normal. \$\endgroup\$
    – ThorinII
    Nov 20, 2013 at 0:41
  • \$\begingroup\$ I'm sorry, I'm not well-aware of that. Can you please provide a quick code example of how I can do that? \$\endgroup\$
    – Gregg1989
    Nov 20, 2013 at 0:44
  • \$\begingroup\$ surface normal is normalize(cirlce1.center-circle2.center) reflection is 2*dot(surfNormal, velocity)*surfNormal-velocity in vector math (see the formula for specular reflection) \$\endgroup\$ Nov 20, 2013 at 10:16

1 Answer 1


See this tutorial on circle-circle collisions: http://gamedev.tutsplus.com/tutorials/implementation/when-worlds-collide-simulating-circle-circle-collisions/

You seem to have most of the code implemented - go down to Step 4 (I think that's it anyway). It shows you how to calculate the new velocities.

You might have to change how you calculate your updates, as you have to update circle and circle2's velocities at the same time (I'm not sure how that works for you).

Note, I could post some of the equations here, but 1. it'd be just a copy-paste (not sure about plagiarism), and 2. they are quite long.

  • \$\begingroup\$ I appreciate it nevertheless! Would have +1'd if I had the reputation :) \$\endgroup\$
    – Gregg1989
    Nov 20, 2013 at 0:54
  • \$\begingroup\$ np :-). If this works for you, you can accept it. \$\endgroup\$
    – ThorinII
    Nov 20, 2013 at 1:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .