I use libGDX library for my game. I user overlap method for detecting collision detection between two rectangles.
...
if (r1.overlaps(r2)) collisionTest();
...
I want to detect touching side on rectangle (top, bottom, left or right):
r1 overlap r2 on the left side
Can anyone give me code for this, but this need to be fast method.
Thanks
You can use the method intersectRectangles provided in the Intersector class to determine if two rectangles are overlapping, and if so, where they overlap. You could use this info to determine if they overlap with the left, right, top, and/or bottom.
Rectangle r1 = /*Initialize*/;
Rectangle r2 = /*Initialize*/;
Rectangle intersection = new Rectangle();
Intersector.intersectRectangles(r1, r2, intersection);
if(intersection.x > r1.x)
//Intersects with right side
if(intersection.y > r1.y)
//Intersects with top side
if(intersection.x + intersection.width < r1.x + r1.width)
//Intersects with left side
if(intersection.y + intersection.height < r1.y + r1.height)
//Intersects with bottom side
Related
I have the following situation, for illustrative purposes split into 2 situations.
The green rectangle in the middle is the rectangle that I am referring to as my base, since it is the rectangle that is constant.
Now I'd like to know if a yellow rectangle is intersecting, is inside or fully encapsulates the green rectangle.
I've seen this post and understand it, but (unless I forget something) it ignores the case of a yellow rectangle being inside the green rectangle. The simplest solution I can think of is to double check the 4 points in either order, but is that the only("best") solution?
Two rectangles A, B have a non-empty intersection iif
A.l < B.r and A.r > B.l and A.t < B.b and A.b > B.t
(left, right, top, bottom coordinates, y downward).
A wholly contains B iif
A.l <= B.l and A.r >= B.r and A.t <= B.t and A.b >= B.b
I have two rectangles. In my code, I can check when a collision occurs with Rect.intersects() method but cannot determine which side it is from. I've tried these below and it works for X-Axis but not for Y-Axis.
if(R1.getTranslateX() + R1.getWidth() < R2.getTranslateX() + (R2.getWidth() / 2) ) {
//Collision from left side
}
if(R1.getTranslateX() > R2.getTranslateX() + (R2.getWidth() / 2) ) {
//Collision from right side
}
if(R1.getTranslateY() + R1.getHeight() < R2.getTranslateY() + (R2.getHeight() / 2)) {
//Collision from top side
}
if(R1.getTranslateY() > R2.getTranslateY() + (R2.getHeight() / 2)) {
//Collision from bottom side
}
The code doesn't get past the X-Axis to check the Y-Axis side... Any ideas?
Left/right and top/bottom are with respect to R1. It is not possible to know for sure in all cases from which direction a collision happened without knowing the directions the objects were moving. The following would be the best way, as I see it, to detect collision direction with the information at hand. Consider the rectangle R1. We will make an estimation on how much colliding rectangles will at most intersect before the collision is detected. We'll call this margin m. Let's detect collisions following this illustration. We see that the smaller the margin, the smaller the areas at the corners are in which we don't know the direction of the collision for sure. The problem with making the margin smaller is that if the rectangles intersect more than the margin allows, we don't detect the direction of the collision at all. See code below.
int m = [an estimate on how much the rectangles will intersect at most]; //margin
//x-direction
if(R1.getTranslateX() + m > R2.getTranslateX() + R2.getWidth()){
//Collision from left side
}else if(R1.getTranslateX() + R1.getWidth() - m < R2.getTranslateX()){
//Collision from right side
}
//y-direction
if(R1.getTranslateY() + m > R2.getTranslateY() + R2.getHeight()){
//Collision from top side
}else if(R1.getTranslateY() + R1.getHeight() - m < R2.getTranslateY()){
//Collision from bottom side
}
I've been stuck on a bug regarding collision in my 2D Mario-like game.
public void collision() {
if (Rect.intersects(Robot.rect2, r)){
robot.setSpeedY(0);
robot.setCenterY(tileY - 32);
robot.setJumped(false);
} else if (Rect.intersects(Robot.rect, r)){
robot.setSpeedY(0);
robot.setCenterY(tileY + 32);
}
updateRect();
if (Rect.intersects(Robot.rect3, r)){
robot.setCenterX(tileX + 32);
robot.setSpeedX(0);
} else if (Rect.intersects(Robot.rect4, r)){
robot.setCenterX(tileX - 32);
robot.setSpeedX(0);
}
}
Collision in my game is checked by comparing rectangles. My robot's rectangles: rect (bottom collision, so rectangle on bottom half of my robot sprite), rect2 (top collision), rect3 (left collision), and rect4 (right collision).
Every tile in my game is bounded by an instanced Rectangle r. When my robot's rectangle and the tile's rectangle intersect, I call collision(), which sets the position of my robots direction.
Here is my problem: If my robot is at a corner, where it is in bottom collision and right collision, and I move to the right, my robot moves INTO the right tile, and that triggers the bottom collision, and screws everything up.
Switching the postiions of the Bottom/Top & Right/Left collision doesn't help since then the same problem occurs, where the robot falls into the ground, triggering the Right/Left collision.
Essentially, I need a way to run all four at the same time.
Thanks
Yku are trying to build it one check at a time. Why not something like
if(!Rect.intersects(robot.rect1) && !Rect.intersects(robot.rect2) && !Rect.intersects(robot.rect3) && !Rect.intersects(robot.rect4)
{
//act normally
} else {
//collieion
}
What youre doing now is checking one side and base your result on that.
yes I also had a trouble with that, what you are missing is to call updateRect(); again after you made the collision detection on the X axis.
And I recommendto check the X axis first.
here is a nice Article about tile based Collision:
http://higherorderfun.com/blog/2012/05/20/the-guide-to-implementing-2d-platformers/
I am trying to make a brickbreaker game and I have run into some issues when it comes to collision detection. If you have ever played brick breaker you know that on the paddle, if the ball is moving to the left and you hit the left side of the top, then it continues moving right. Although, if you hit it on the right side in this case, then the ball changes directions. And also if you hit it on the sides of the paddle, it bounces off on the Y axis. Since I have no idea how to do the top part of the paddle, I can't show you the code because I don't have any :) This is the code that I am using for the sides:
Rectangle rect1 = new Rectangle((int) paddleDir, 570, imsLoader.getImage("paddle1").getWidth(), imsLoader.getImage("paddle1").getHeight());
Rectangle rect2 = new Rectangle((int) ballX, (int) ballY, imsLoader.getImage("ball").getWidth(), imsLoader.getImage("ball").getHeight());
if (rect1.intersects(rect2))
{
if (rect1.x == rect2.getMaxX() || rect1.getMaxX() == rect2.x)
{
ballVX = -ballVX;
clipsLoader.play("pattleHit", false);
}
else
{
ballVY = -ballVY;
ballY += 0.05;
clipsLoader.play("pattleHit", false);
}
}
What happens is that the ball when gets hit on the side, just goes right through the paddle going all over the place and when it reaches the other end either goes up or down!
You have to make the ball bounce, right?
Let's look at an example. Think the top square as the ball (I can't draw that nice). When the ball collides from left, it should move right and if it's from right, then go left.
You can achieve this with a simple thing. Don't change the horizontal velocity but instead reverse the vertical one.
if (ball.getBounds().intersects(paddle.getBounds()))
{
ball.setVy(-ball.getVy());
}
Easy right!
Now let's figure out how to do bounce effect on bricks.
This is a scenario when ball hits the brick. The red area is the intersection. Now notice it carefully.
If the intersection width is greater than the intersection height, the ball has hit in the bottom or vertical sides of the brick.
If the intersection height is greater that the intersection width, then it is a horizontal collision.
So we have to first calculate the intersection rectangle. It's so easy with java.
Rectangle intersection = ball.getBounds().intersection(brick.getBounds());
Now let's implement the bouncing.
if (intersection.width >= intersection.height)
{
ball.setVy(-ball.getVy());
}
if (intersection.height >= intersection.width)
{
ball.setVx(-ball.getVx());
}
That's it and you should have it fully functional.
Im trying to get into some basic JavaFX game development and I'm getting confused with some circle maths.
I have a circle at (x:250, y:250) with a radius of 50.
My objective is to make a smaller circle to be placed on the circumference of the above circle based on the position of the mouse.
Where Im getting confused is with the coordinate space and the Trig behind it all.
My issues come from the fact that the X/Y space on the screen is not centered at 0,0. But the top left of the screen is 0,0 and the bottom right is 500,500.
My calculations are:
var xpos:Number = mouseEvent.getX();
var ypos:Number = mouseEvent.getY();
var center_pos_x:Number = 250;
var center_pos_y:Number = 250;
var length = ypos - center_pos_y;
var height = xpos - center_pos_x;
var angle_deg = Math.toDegrees(Math.atan(height / length));
var angle_rad = Math.toRadians(angle_deg);
var radius = 50;
moving_circ_xpos = (radius * Math.cos(angle_rad)) + center_pos_x;
moving_circ_ypos = (radius * Math.sin(angle_rad)) + center_pos_y;
I made the app print out the angle (angle_deg) that I have calculated when I move the mouse and my output is below:
When the mouse is (in degrees moving anti-clockwise):
directly above the circle and horizontally inline with the center, the angle is -0
to the left and vertically centered, the angle is -90
directly below the circle and horizontally inline with the center, the angle is 0
to the right and vertically centered, the angle is 90
So, what can I do to make it 0, 90, 180, 270??
I know it must be something small, but I just cant think of what it is...
Thanks for any help
(and no, this is not an assignment)
atan(height/length) is not enough to get the angle. You need to compensate for each quadrant, as well as the possibility of "division-by-zero". Most programming language libraries supply a method called atan2 which take two arguments; y and x. This method does this calculation for you.
More information on Wikipedia: atan2
You can get away without calculating the angle. Instead, use the center of your circle (250,250) and the position of the mouse (xpos,ypos) to define a line. The line intersects your circle when its length is equal to the radius of your circle:
// Calculate distance from center to mouse.
xlen = xpos - x_center_pos;
ylen = ypos - y_center_pos;
line_len = sqrt(xlen*xlen + ylen*ylen); // Pythagoras: x^2 + y^2 = distance^2
// Find the intersection with the circle.
moving_circ_xpos = x_center_pos + (xlen * radius / line_len);
moving_circ_ypos = y_center_pos + (ylen * radius / line_len);
Just verify that the mouse isn't at the center of your circle, or the line_len will be zero and the mouse will be sucked into a black hole.
There's a great book called "Graphics Gems" that can help with this kind of problem. It is a cookbook of algorithms and source code (in C I think), and allows you to quickly solve a problem using tested functionality. I would totally recommend getting your hands on it - it saved me big time when I quickly needed to add code to do fairly complex operations with normals to surfaces, and collision detections.