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.
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);
}