ID:161286
May 25 2008, 8:00 am
|
|
I need the algorithm for pixel box collisions(For sizes over and under 32x32). So i've gotten that you need the exact location of the atom(x/y*32+pixel_x/y) the Width and Length, and I just now need the algorithm to see if it hits the obj.
|
In response to Jtgibson
|
|
var/X Thats what I came up with, PixX means exact x location in pixels they are on the map, PixY means just the exact y location, Length and Width are how big the rectangle is, and MovementX/Y is how big the movement is towards that direction. It only will bump around the icons head though :/ ... |
In response to Bakasensei
|
|
This is what I used in a recent platformer demo I was working on. Credit for the arctan2() proc goes to Lummox.
PixelStep |
In response to Xooxer
|
|
Hmm, you didn't show the movement in there, but I could probably wing it xD
|
In response to Bakasensei
|
|
In response to Xooxer
|
|
Ick. I question the wisdom of returning the pixel-to-pixel direction on collision unless you really always need it. It's nastily expensive to calculate.
(Also, using x**2 (etc.) instead of x*x is bad bad bad.) Edit: Also, your get_pix_dir() routine returns false if delta-x or delta-y is 0, and your get_collision() routine returns that value to indicate a collision. Thus you won't be able to collide in the cardinal directions. This is probably not what you intend. |
In response to Hobnob
|
|
Hobnob wrote:
Ick. I question the wisdom of returning the pixel-to-pixel direction on collision unless you really always need it. It's nastily expensive to calculate. I always need it, so. Yeah. Always. [edit] To elaborate... Well, the object needs to know how to react to what it just bumped into, which depends mainly on the direction. I'd have to request the direction somehow else anyways, so I thought I might as well have it built right into the pixel bump system. If you can think of something superior, please do share. [/edit] (Also, using x**2 (etc.) instead of x*x is bad bad bad.) Like I said, I didn't write the arctan2() proc. I'm just abusing it for my own fiendish desires. Edit: Also, your get_pix_dir() routine returns false if delta-x or delta-y is 0, and your get_collision() routine returns that value to indicate a collision. Thus you won't be able to collide in the cardinal directions. This is probably not what you intend. I see. That might explain some of the bugs I was having. Thanks for the info. |
The algorithm is quite simple: for each corner of the smaller box, check to see if it is inside the bounds of the larger box. If both boxes are equal in size, you can choose whichever box you like.
This is, at its heart, solving a system of inequalities. The difference, of course, is that the computer solves the problem for you by determining whether all of the equations are satisfied with the given "x,y" values plugged in. In this case, you need to find the equations. For boxes that never rotate, this is extremely easy, since the equations are just constant values that you check against. For boxes that can rotate, you have to find the lines that intersect the corners -- the lines that make up the sides of the larger box -- which is much more math intensive.
Basically, the easy version (non-rotating boxes) works like this:
Determine the closest corner of the smaller box
Find the "bounds" of the larger box
If corner's x is greater than/equal to larger box's min x (x >= equation of left side)
And if corner's x is less than/equal to larger box's max x (x <= equation of right side)
And if corner's y is greater than/equal to larger box's min y (y >= equation of bottom side)
And if corner's y is less than/equal to larger box's max y (y <= equation of top side)
Collision has occurred
Else no collision
Usually you would then adjust the position of the smaller box so it was no longer penetrating the larger box. This is more difficult because it depends on which side of the larger box is closer to the offending corner -- compare the absolute value of corner x - large_min_x and corner x - large_max_x to know whether it's the left side or right side, and similarly for corner y and min/max y to determine whether it's the bottom or top. Once you know that, it's a matter of bumping the smaller box by the distance from that side.
The same applies for rotating boxes, but you have to bump perpendicularly to the equation for the side, which is of course very math intensive and takes a lot of working out on paper in order to solve for the general case.