Quote:Original post by Moof
Quote:Original post by shotgunnutter
In your situation, I would approximate each sprite using circles. This could be manually done, or done algorithmically and then stored on file. Each sprite has a list of circles, each with a vector from the center of the sprite and a diameter.
This would work well for most of my sprites, however I have a lot that are rectangular and do not rotate and so I am using bounding boxes for those. Calculating the collision between bounding boxes and bounding circles becomes a little tricky.
I don't think detecting collisions between bounding boxes and circles has to be much trickier than checking collisions between two circles. For a method that isn't perfectly accurate you could inflate the size of the box by the radius of the circle and then check if the x,y of the circle is contained in the inflated box. This will be accurate for the walls, but the corners will return false positives. However, if that test returns a hit you could do a more precise collision detection by testing a wide version of the box, a tall version of the box, and then testing the corners of the box. The code below should explain the algorithm better than I can with words.
Sorry if the syntax is off, I have been using quite a few languages lately I tend to confuse syntax sometimes. It should be close to c++ syntax.
bool ballRectHitTest(Rect rect, Circle ball){ //Assuming you have a rect class with a pixel hittest method //and a circle class with a pixel hittest method both with a signature of //Contains(x,y) --> boolean //Step 1: Make sure a collision is possible //This test is accurate for everything except the corners if (new Rect(rect.x - ball.radius, rect.y - ball.radius, rect.w + ball.radius, rect.h + ball.radius).Contains(ball.x, ball.y) ){ //Test the tall rectangle for a hit and return true on success Rect rect1 = new Rect(rect.x, rect.y - ball.radius, rect.w, rect.h + ball.radius); if rect1.Contains(ball.x, ball.y) { return true; } //Test the wide rectangle for a hit and return true on success Rect rect2 = new Rect(rect.x - ball.radius, rect.y, rect.w + ball.radius, rect.h); if rect2.Contains(ball.x,ball.y) {return true; } //Now test each of the four corners for a hit Circle circ1 = new Circle(rect.x, rect.y, ball.radius) if circ1.Contains(ball.x, ball.y) {return true;} Circle circ2 = new Circle(rect.x+rect.w, rect.y, ball.radius) if circ2.Contains(ball.x, ball.y) {return true;} Circle circ3 = new Circle(rect.x, rect.y+rect.h, ball.radius) if circ3.Contains(ball.x, ball.y) {return true;} Circle circ4 = new Circle(rect.x+rect.w, rect.y+rect.h, ball.radius) if circ4.Contains(ball.x, ball.y) {return true;} } //If the function runs to the end there was no collision return false;}
I personally like the idea of using hit shapes rather than pixel level hit testing.