ImageRectOverlap type function
BlitzMax Forums/BlitzMax Programming/ImageRectOverlap type function
| ||
Hi I'm looking for a function in Bmax similar to B+'s ImageRectOverlap function, which tests for collision between a rectangle and an image, which igonores transparent image pixels. Does Bmax offer a function like this, and if not could someone please give an example of the code, please? Thanks |
| ||
Wouldn't that be similar to a boundingbox-check? Here, that should work: Function RectsOverlap:Byte(iParX1:Int, iParY1:Int, iParW1:Int, iParH1:Int, iParX2:Int, iParY2:Int, iParW2:Int, iParH2:Int) If iParX1 > (iParX2 + iParW2) Or (iParX1 + iParW1) < iParX2 Then Return False If iParY1 > (iParY2 + iParH2) Or (iParY1 + iParH1) < iParY2 Then Return False Return True End Function |
| ||
Here's an ImageRectCollide function tooFunction ImageRectCollide%(image:TImage, ix%, iy%, iframe%, rx%, ry%, rwidth%, rheight%) If iframe < 0 Then Return ResetCollisions CollideImage image, ix, iy, iframe, 0, 1 If CollideRect(rx, ry, rwidth, rheight, 1, 0) Then Return True Else Return False End Function |
| ||
Hmm, I was just using the RectsOverlap function above and found that it claims rects overlap when they are merely adjacent. For example a 10x10 rect is sitting next to another one. The first one is at 0,0 and the second one is at 10,0. So the test goes: Is 0 > (10+10)? No so it does the next test ... Is (0+10) < 10? No so it it checks the Y coords. If I reduce the width that I pass in by 1 it's fine. It can be be fixed by changing all the comparisons to >= and <=. However, I also changed the function to take floats, but that didn't seem to work as well when I passed in floating coords, hmm. So beware... |
| ||
This is the function I use in my sprite system. It will handle rotated and animated images. You'll have to make a few changes to it to make it work with images though, because you'll need to tell it the rotation and scale of both the image and rect, as well as the frame the image is displaying. This won't interefere with any other collision code you might have because it uses the same temporary collision layer users are not intended to access which the other collision functions use. Method OverlapsRect%(RectX#, RectY#, RectWidth#, RectHeight#, RectRotation#=0) Local Result% ' Clear collision layer 32. ' Using layer 32 because it is a scratch layer used by some internal functions and will probably not be used by the user. ResetCollisions COLLISION_LAYER_32 ' Place sprite in collision layer 32. SetRotation Rotation#(True) SetScale ScaleX#(True), ScaleY#(True) CollideImage _Image, X#(True), Y#(True), Frame#(True), 0, COLLISION_LAYER_32 ' Set Result to true if rect is colliding with the image we just placed in collision layer 32. ' (Rect is not written to collision layer.) SetRotation RectRotation# SetScale 1,1 If CollideRect(RectX#, RectY#, RectWidth#, RectHeight#, COLLISION_LAYER_32, 0) <> Null Result = True Return Result End Method The Rotation() ScaleX() Frame() etc functions are getting the sprite's parameters, so those are what you need to pass to the function for the image. |
| ||
Interesting but overkill for what I needed which was to compare some coords without using the collision layer (no rotated/scaled images for the case I was checking). Did you see what I mean about the other method above being duff? It's not the only example there are loads on the forum, all the same! I'm wondering if they all came from the same corrupt source or if I'm being dumb here and missing something. |
| ||
I wasn't tryong to help YOU Grey, this is supermeekat's thread. :-) |
| ||
yeah but it's *5* months old, I was just resurrecting it due to the code posted being bugged ;-p |
| ||
Ah. Very tricky there. You got me! |