I'm making an Android game and I'm having some problems with bitmap collision detection. The problem is that one of the bitmaps is a triangle and the second one is a rectangle. I don't know how to detect collision between them because now I use this code:
if(policeY<((canvas.getHeight()/20)+eye.getHeight()) && (policeY+police.getHeight())>(canvas.getHeight()/20)){
if((policeX+police.getWidth())>triangleLeft && policeX<(triangleLeft+eye.getWidth())){
//collision
play = false;
}else if((policeX+police.getWidth())<triangleLeft && policeX>(triangleLeft+eye.getWidth())){
//collision
play = false;
}
}
However, this code handles both of them as rectangles and this causes collision even when triangle isn't even touching rectangle.
Like in this picture the circled area is considered as a collision
I'd set up the problem as an intersection problem. Define the edges of the triangles as lines then use the line-line intersection formula with the edges of the rectangle. Then check whether this point is on the edge of the rectangle or if it is outside the rectangle.
Related
I want to collide a rectangle with a semi-circle that comes rotating. A rectangular hitbox for the semi-circle, of course, is not appropriate as the side of the rectangular hitbox on the round side of the semi-circle will touch other targets before the semi-circle touches the targets. I am not inclined to use pixel collision detection as the two images are large.
I am thinking of using stripes of narrow hitbox rectangles of varying heights that approximately cover the contours of the semi-circle. How well would this work?
Not sure how you are doing collision detection, so I will just assume parametric equations and you can easily test for collisions between basic shapes.
If you think of a semi-circle as a circle missing a triangular element, then this is easy.
if (collide(rect, circle) && !collide(rect, triangle)) {
// then collision semi-circle
}
Use an isosceles triangle. The tip of the triangle is the center of the circle. The height of the triangle is the radius of the circle. The angle is based on what is missing from the circle.
I am writing a program that allows a user to left-click the panel and add a bouncing ball, and right-click to remove a ball. The balls bounce off of all walls with a constant velocity. I have all of this finished. The last part that I cannot figure out is handling the collisions with other bouncing balls. The same results as bouncing off of the walls should occur. Any help will be greatly appreciated. Here is the code for the movement of the ball so far...
#SuppressWarnings("AccessingNonPublicFieldOfAnotherObject")
private void processMovement(long interval)
{
/* Compute the distance moved in the interval. Decompose the distance
moved into x and y components, and determine the next position of the Ball
by those amounts. */
float x = position.x + velocity.getDistanceX(interval);
float y = position.y + velocity.getDistanceY(interval);
position.setLocation(x, y);
/* Collisions with the walls. If so, adjust the speed and direction for
the next period. */
/* Collision with the east or west (vertical) wall. */
float wall;
if( x <= (wall = 0.0F) ||
x >= (wall = model.getDimension().width - SIZE) )
{
x = wall;
velocity.reverseX();
}
/* Collision with the north or south (horizontal) wall. */
if( y <= (wall = 0.0F) ||
y >= (wall = model.getDimension().height - SIZE) )
{
y = wall;
velocity.reverseY();
}
position.setLocation(x, y);
}
When I wrote a program like this, I ended up creating a wall object, which had a start x/y and an end x/y. Geometry was needed in order to determine the correct ricochet/bounce angle since walls could be at any orientation. Essentially the direction of the ball changes by two times the difference in orientation between the wall and the ball's direction. For example, if the ball is moving at 45* above the X-axis, and the wall is oriented at 90* above the X-axis (i.e. it's straight up and down), then the ball's new heading is its original heading plus two times the difference between its heading and the wall's direction, or in other words 45* + 2*(90*-45*), or in other words, 135*. The problem is that it doesn't work if you consider the wall's orientation to be -90* (i.e. 90* below the X-axis, which is still straight up and down). In that case you'd calculate the ball's new heading as -45* which is wrong. It also matters if you hit the wall from the left or from the right. Fun, right? Lots of things to think about.
Balls collide when their centers are within (R1 + R2) distance of each other, where R1 is the radius of the first ball, and R2 is the radius of the second ball.
Essentially, what I did was I created a temporary (invisible) wall that was perpendicular with the vector from the center of one ball to the center of the other, and then I ordered the two balls to bounce off of this wall. This gave the correct ricochet behavior.
I know you probably don't care about my "wall collision" stuff, but I think what I have described could give you something of an idea of the kind of geometry you're going to need to perform in order to solve this problem.
In short, bouncing balls off of each other correctly is difficult. Consider removing/abandoning this functionality if it's not required and/or you're not willing to spend the effort.
You could also put together something less correct, but easier. You could simply have balls move away from each other when they collide, but then you'd get "unnatural" looking ricochets.
I know it certainly doesn't solve your problem, but hopefully this helps.
In Java (at least when using Bluej as the environment), the top left corner pixel is (0,0) and bottom left is (600,600)(depending on window size). Your logic is unfamiliar to me, but assuming your math is correct to have the balls reverse direction when hitting a wall you should have 4 if statements per ball. I know there are ways of getting away with 1 or 2 and my way is ugly and not very effecient, but a least it will isolate if the problem is your math of logic.
if (X<=0 || X>=600)
{
velocity.reverseX();
}
if (Y<=0 || Y>=600)
{
velocity.reverseY();
}
I hope this helps :)
I am currently working on a simple space game for android. My collision detection will be done using rectangular and circular bounding boxes. These bounding boxes need to be able to rotate, so my question is: what is the best to detect a collision between a rotated rectangle and a circle? Thanks for your help :)
Ok, I have solved my own problem! There are only two cases when a circle intersects a rectangle:
1. The center of the circle is inside the rectangle
2. The circle is intersecting one of the sides of the rectangle
So to check for the collision, I first check if the center of the circle is inside the rectangle, after rotating the center of the circle according to the rotation of the rectangle, to simplify my calculations. If the center of the circle is inside the rectangle, I know there is an intersection, and return true.
If the first check returns false, then I check for intersections between each side of the rectangle, and the circle. If there is an intersection I return true. Feel free to comment if anyone wants the code, thanks for the help guys! :)
Generally, bounding boxes just define the bounds of an object, (a shape generated by the vertices of an object's max & min's X & Y) - this makes it much simpler to calculate, bounding boxes do not need to rotate as their purpose is met simply as I have explained. If you want to use them for collision detection simply check if the center of the circle plus its radius intersects the rectangle in both axis such as:
public boolean boxintersectscircle(BoundingBox box, BoundingCircle circle) {
if (box.x > circle.centerx+circle.radius) return false;
if (box.y > circle.centery+circle.radius) return false;
if (box.x+box.width < circle.centerx-circle.radius) return false;
if (box.y+box.height < circle.centery-circle.radius) return false;
return true;
}
However bounding boxes aren't accurate - they can leave a lot of unoccupied space so if that's a worry for your game (player frustration), Personally I would implement the separating axis theorem or line/circle detection.
I'm creating a 2d game. There are a lot of objects(oval, triangle etc) created by Bitmap. I'm going to detect collisions. Now I can do it only with rectange like this:
int x, y;
...
if(x>=bmp.getX() && x<=bmp.getX()+bmp.getWidth()
&& y>=bmp.getY() && y<=bmp.getY()+bmp.getHeight()) {
//Collision.
}
But there is one problem: I don't know how to do it with another figure (oval, triangle, etc). Any ideas will be appreciated. Thank you.
A simple solution is to use sub rectangles to calculate collisions. The sub rectangles wont be able to cover the entire object but they can cover most of it.
This image should illustrate what I mean, it uses several rectangles for collision detection of a aeroplane
Another option (though NOT recommended) is to use per pixel color collision, if a colored pixel in the triangle intercepts a colored of an oval then there is a collision. Be warned this is computationally expensive.
1) for most figures try formula for intersection of edges
to find more try ie: How do you detect where two line segments intersect?
2) for intersection of circle and not circle, try distance from centre of circle to edgeHow to tell if a line segment intersects with a circle?
3) intersection of two circles is easiest, just check is distance between both centres are lower than sum of their radius
I faced the same problem as you, however with irregular Shapes. How I fixes the problem:
Create a Shape class that contains a list of Rectangles.
When first creating your game object, you should add Rectangles to the list so that a Shape is formed.
Now for collision detection; instead of just checking the one rect, iterate over all the rects in the list.
I hope this helps.
For oval you can use: -
if((Math.pow(x, 2) / Math.pow(a, 2)) + (Math.pow(y, 2) / Math.pow(b, 2)) < 1) {
/** Point (x, y) is inside Oval **/
}
For Triangle, it is a little trivial task: -
Visit this link
This is about animation in JAVA. I had success when using same dimension on all picture. But if i keep all picture dimension on same size(width and height) i get some bug which when player punch. Before player's hand touch enemy body, enemy died
But others with my case where idle, run, and punch has an different
dimension. Punching animation facing to the left became very strange.
Should his hand hit to the left but his body shifts to the right. This
is because I draw on the x & y are the same.
How can I fix it? Need instructions :D
I use png coz support transparent
I think this can fix with 2 option
1. Fix my collision detection
2. Fix of drawing position my image when some condition occur
Trying to picture your problem, hope this helps.
I am typeing directly from my head, so there are might errors in code
fixing coalision decection
i would try this
Image fist
Image enemy
//in paint
g2D.drawImage(fist,x,y,this);
g2D.drawImage(enemy,x1,y1,this);
Rectangle2D myFist = new Rectangle2D.Double(x,y,fist.getWidth(this),fist.getHeight(this));
Rectangle2D myEnemy = new Rectangle2D.Double(x1,y1,enemy.getWidth(this),enemy.getHeight(this));
if (myEnemy.contains(myFist){
//action u want to happend
}
I think something like this should fix coalision problems
I am seeing this as mario a game on sega
Fix of drawing position
//arm image can be the same image if u want
Image leftArm;
Image rightArm;
image headLegsAndTorsoLeft;
image headLegsAndTorsoRight;
//where am i looking in game if true i look to the leftside of user thats playing
boolean turnedLeft
//in paint
if(turnedLeft){
//this lets it look like he is turned to the left with his right arm in the visible behind his left.
//draw right arm
g2D.drawImage(rightArm,x,y,this);
//draw body moved a bit in x coor
g2D.drawImage(headLegsAndTorsoLeft,x-3,y,this);
// draw left arm a bit more in x coor
g2D.drawImage(leftArm,x-6,y,this);
}else{
//this lets it look like he is turned to the right with his left arm in the visible behind his right.
// draw left arm
g2D.drawImage(leftArm,x,y,this);
//draw body moved a bit in x coor
g2D.drawImage(headLegsAndTorsoRight,x-3,y,this);
//draw right arm a bit more in x coor
g2D.drawImage(rightArm,x-6,y,this);
}
same order for animation of arms, ultimatly i would use different methods animations for torso, leftarm, rightarm
something like keypressed leftarrow torso does walking animation left, hit left arm key moves left arm,hit right arm key moves right arm,thats 3 for lets say left arm, now u need another 3 for when ur char is moved to the right.
Thats how i would try to do things.