Search code examples
javaprocessingcollision-detectioncollision

How to make the ball roll smoothly off the corner?


In this program, the rectangle should block the ball when the mouse is on the opposite side. When the ball and the mouse are on adjacent sides, the ball should roll off the corner. The problem is that this doesn't happens, the ball is stucked on the corner. Here is the complete program:

PVector p = new PVector(100, 100); //position
PVector v = new PVector(0, 0); // velocity

void setup()
{
  size(600, 600);
  frameRate(120);
}

void draw()
{
  background(0);
  rect(250, 250, 200, 100);
  ellipse(p.x, p.y, 20, 20);
  v.setMag(2.5);
  p.add(v);

  if (p.x + 10 >= 250 && p.x - 10 <= 450 && p.y + 10 >= 250 && p.y - 10 <= 350) // ball is inside box
  {
    if (p.y  <= 250 || p.y  >= 350) // ball came from above 
    {
      v.y = -v.y;
    } 
    if (p.x <= 250 || p.x >= 450) // ball came from sides
    {
      v.x = -v.x;
    }
  } 
  else // move ball
  { 
    PVector dir = new PVector(mouseX, mouseY);
    v = PVector.sub(dir, p);
  }
}

I tried to fix this by checking if a corner has been hit but the ball still gets stuck on the corner.

PVector p = new PVector(100, 100); // Pisition
PVector v = new PVector(0, 0); // Velocity

void setup()
{
  size(600, 600);
  frameRate(120);
}

void draw()
{
  background(0);
  rect(250, 250, 200, 100);
  ellipse(p.x, p.y, 20, 20);
  v.setMag(2.5);
  p.add(v);

  if (dist(p.x, p.y, 250, 250)<10) // corner has been hit
  {
    p = new PVector(239, 239); // move ball away from corner
  } 
  else if (dist(p.x, p.y, 450, 250)<10)
  {
    p = new PVector(461, 239);
  } 
  else if (dist(p.x, p.y, 450, 350)<10)
  {
    p = new PVector(461, 361);
  } 
  else if (dist(p.x, p.y, 250, 350)<10)
  {
    p = new PVector(239, 361);
  } 
  else if (p.x + 10 >= 250 && p.x - 10 <= 450 && p.y + 10 >= 250 && p.y - 10 <= 350) // ball is inside box
  {
    if (p.y  <= 250 || p.y  >= 350) // ball came from above 
    {
      v.y = -v.y;
    } 
    if (p.x <= 250 || p.x >= 450) // ball came from sides
    {
      v.x = -v.x;
    }
  } 
  else // move ball towards mouse
  { 
    PVector dir = new PVector(mouseX, mouseY);
    v = PVector.sub(dir, p);
  }
}

Is there a way to make the ball roll smoothly off the corner? Any help is appreciated. Thanks.


Solution

  • I've modified your sketch in order to solve your problem. The trick is to add a little gap at each corner such that the ball can cross the right angle.

    PVector p = new PVector(100, 100); //Position
    PVector v = new PVector(0, 0);     //Velocity
    PVector dir;                       //Direction
    int sizeX = 600, sizeY = 600;      //Window size
    int rectX = 250, rectY = 250;      //Rectangle position
    int rectW = 200, rectH = 100;      //Rectangle size
    int ballR = 10;                    //Ball radius
    int gap = 2;                       //Corner gap
    
    void setup(){
      size(sizeX, sizeY);
      frameRate(120);
    }
    
    void draw(){
      background(0);
      rect(rectX, rectY, rectW, rectH);
      dir = new PVector(mouseX, mouseY);
      v = PVector.sub(dir, p);
      if((v.x>0 && p.x+ballR > rectX         && p.x+ballR < rectX + rectW &&
                   p.y+ballR > rectY + gap   && p.y-ballR < rectY + rectH - gap)
       ||(v.x<0 && p.x-ballR < rectX + rectW && p.x-ballR > rectX &&
                   p.y+ballR > rectY + gap   && p.y-ballR < rectY + rectH - gap)){
          v.x = -v.x;
      } 
      if((v.y>0 && p.y+ballR > rectY         && p.y+ballR < rectY + rectH && 
                   p.x+ballR > rectX + gap   && p.x-ballR < rectX + rectW - gap)
       ||(v.y<0 && p.y-ballR < rectY + rectH && p.y-ballR > rectY &&
                   p.x+ballR > rectX + gap   && p.x-ballR < rectX + rectW - gap)){
          v.y = -v.y;
      }
      v.setMag(2.5);
      p.add(v);
      ellipse(p.x, p.y, 2*ballR, 2*ballR);
    }