I need input on a possible bug in v3.5.0 - TerryRitchie - 01-20-2023
I have a tutorial user that has reported my pixel perfect collision routines are not working in v3.5.0 but work fine in v3.4.1 but I can't replicate this.
The code below I've tested in the following and it works fine:
- Windows 7 SP2 and QB64PE v3.4.1 and v3.5.0
- The latest version of Linux Mint and QB64PE v3.5.0
For those of you with different versions of Windows, Linux, and MacOS would you kindly run the code below and let me know what you find out? The ZIP file attached contains the code and the two image files needed to run it.
Code: (Select All) '** Pixel Perfect Collision Demo #5
Type TypeSPRITE ' sprite definition
image As Long ' sprite image
mask As Long ' sprite mask image
x1 As Integer ' upper left X
y1 As Integer ' upper left Y
x2 As Integer ' lower right X
y2 As Integer ' lower right Y
End Type
Type TypePOINT
x As Integer
y As Integer
End Type
Dim RedOval As TypeSPRITE ' red oval images
Dim GreenOval As TypeSPRITE ' green oval images
Dim Intersect As TypePOINT
RedOval.image = _LoadImage("redoval.png", 32) ' load red oval image image
GreenOval.image = _LoadImage("greenoval.png", 32) ' load green oval image
MakeMask RedOval ' create mask for red oval image
MakeMask GreenOval ' create mask for green oval image
Screen _NewImage(640, 480, 32) ' enter graphics screen
_MouseHide ' hide the mouse pointer
GreenOval.x1 = 294 ' green oval upper left X
GreenOval.y1 = 165 ' green oval upper left Y
Do ' begin main program loop
_Limit 30 ' 30 frames per second
Cls ' clear screen
While _MouseInput: Wend ' get latest mouse information
_PutImage (GreenOval.x1, GreenOval.y1), GreenOval.image ' display green oval
_PutImage (RedOval.x1, RedOval.y1), RedOval.image ' display red oval
RedOval.x1 = _MouseX ' record mouse X location
RedOval.y1 = _MouseY ' record mouse Y location
If PixelCollide(GreenOval, RedOval, Intersect) Then ' pixel collision?
Locate 2, 36 ' yes, position text cursor
Print "COLLISION!" ' report collision happening
Circle (Intersect.x, Intersect.y), 4, _RGB32(255, 255, 0)
Paint (Intersect.x, Intersect.y), _RGB32(255, 255, 0), _RGB32(255, 255, 0)
End If
_Display ' update screen with changes
Loop Until _KeyDown(27) ' leave when ESC key pressed
System ' return to operating system
'------------------------------------------------------------------------------------------------------------
Sub MakeMask (Obj As TypeSPRITE)
'--------------------------------------------------------------------------------------------------------
'- Creates a negative mask of image for pixel collision detection. -
'- -
'- Obj - object containing an image and mask image holder -
'-------------------------------------------------------------------
Dim x%, y% ' image column and row counters
Dim cc~& ' clear transparent color
Dim Osource& ' original source image
Dim Odest& ' original destination image
Obj.mask = _NewImage(_Width(Obj.image), _Height(Obj.image), 32) ' create mask image
Osource& = _Source ' save source image
Odest& = _Dest ' save destination image
_Source Obj.image ' make object image the source
_Dest Obj.mask ' make object mask image the destination
cc~& = _RGB32(255, 0, 255) ' set the color to be used as transparent
For y% = 0 To _Height(Obj.image) - 1 ' cycle through image rows
For x% = 0 To _Width(Obj.image) - 1 ' cycle through image columns
If Point(x%, y%) = cc~& Then ' is image pixel the transparent color?
PSet (x%, y%), _RGB32(0, 0, 0, 255) ' yes, set corresponding mask image to solid black
Else ' no, pixel is part of actual image
PSet (x%, y%), cc~& ' set corresponding mask image to transparent color
End If
Next x%
Next y%
_Dest Odest& ' restore original destination image
_Source Osource& ' restore original source image
_SetAlpha 0, cc~&, Obj.image ' set image transparent color
_SetAlpha 0, cc~&, Obj.mask ' set mask transparent color
End Sub
'------------------------------------------------------------------------------------------------------------
Function PixelCollide (Obj1 As TypeSPRITE, Obj2 As TypeSPRITE, Intersect As TypePOINT)
'--------------------------------------------------------------------------------------------------------
'- Checks for pixel perfect collision between two rectangular areas. -
'- Returns -1 if in collision -
'- Returns 0 if no collision -
'- -
'- obj1 - rectangle 1 coordinates -
'- obj2 - rectangle 2 coordinates -
'---------------------------------------------------------------------
Dim x1%, y1% ' upper left x,y coordinate of rectangular collision area
Dim x2%, y2% ' lower right x,y coordinate of rectangular collision area
Dim Test& ' overlap image to test for collision
Dim Hit% ' -1 (TRUE) if a collision occurs, 0 (FALSE) otherwise
Dim Osource& ' original source image handle
Dim p~& ' pixel color being tested in overlap image
Obj1.x2 = Obj1.x1 + _Width(Obj1.image) - 1 ' calculate lower right x,y coordinates
Obj1.y2 = Obj1.y1 + _Height(Obj1.image) - 1 ' of both objects
Obj2.x2 = Obj2.x1 + _Width(Obj2.image) - 1
Obj2.y2 = Obj2.y1 + _Height(Obj2.image) - 1
Hit% = 0 ' assume no collision
'** perform rectangular collision check
If Obj1.x2 >= Obj2.x1 Then ' rect 1 lower right X >= rect 2 upper left X ?
If Obj1.x1 <= Obj2.x2 Then ' rect 1 upper left X <= rect 2 lower right X ?
If Obj1.y2 >= Obj2.y1 Then ' rect 1 lower right Y >= rect 2 upper left Y ?
If Obj1.y1 <= Obj2.y2 Then ' rect 1 upper left Y <= rect 2 lower right Y ?
'** rectangular collision detected, perform pixel perfect collision check
If Obj2.x1 <= Obj1.x1 Then x1% = Obj1.x1 Else x1% = Obj2.x1 ' calculate overlapping
If Obj2.y1 <= Obj1.y1 Then y1% = Obj1.y1 Else y1% = Obj2.y1 ' square coordinates
If Obj2.x2 <= Obj1.x2 Then x2% = Obj2.x2 Else x2% = Obj1.x2
If Obj2.y2 <= Obj1.y2 Then y2% = Obj2.y2 Else y2% = Obj1.y2
Test& = _NewImage(x2% - x1% + 1, y2% - y1% + 1, 32) ' make overlap image
_PutImage (-(x1% - Obj1.x1), -(y1% - Obj1.y1)), Obj1.image, Test& ' place image 1
_PutImage (-(x1% - Obj2.x1), -(y1% - Obj2.y1)), Obj2.mask, Test& ' place image mask 2
'** enable the line below to see a visual represenation of mask on image
'_PUTIMAGE (x1%, y1%), Test&
x2% = x1%
y2% = y1%
y1% = 0 ' reset row counter
Osource& = _Source ' record current source image
_Source Test& ' make test image the source
Do ' begin row (y) loop
x1% = 0 ' reset column counter
Do ' begin column (x) loop
p~& = Point(x1%, y1%) ' get color at current coordinate
'** if color from object 1 then a collision has occurred
If p~& <> _RGB32(0, 0, 0, 255) And p~& <> _RGB32(0, 0, 0, 0) Then
Hit% = -1
Intersect.x = x1% + x2% ' return collision coordinates
Intersect.y = y1% + y2%
End If
x1% = x1% + 1 ' increment to next column
Loop Until x1% = _Width(Test&) Or Hit% ' leave when column checked or collision
y1% = y1% + 1 ' increment to next row
Loop Until y1% = _Height(Test&) Or Hit% ' leave when all rows checked or collision
_Source Osource& ' restore original destination
_FreeImage Test& ' test image no longer needed (free RAM)
End If
End If
End If
End If
PixelCollide = Hit% ' return result of collision check
End Function
RE: I need input on a possible bug in v3.5.0 - Jack - 01-20-2023
TerryRitchie, tested ok in Ubuntu 22.04.1 x64
tested with the official 3.5.0 release and with QB64pe latest Git repo
RE: I need input on a possible bug in v3.5.0 - bplus - 01-20-2023
Tested in 3.4.1 then downloaded fresh 3.5 and tested again on my Windows 10 -64 laptop.
Looks good on 3.5 as well!
PS I'd be more impressed with Collision code if demo used a sort of Christmas Star shape that had ins and outs around the out-line of the shape. But knowing you, Terry it will work anyway OTOH this sort of collision test using POINT depends upon 2 different color objects.
RE: I need input on a possible bug in v3.5.0 - SMcNeill - 01-20-2023
(01-20-2023, 07:52 PM)bplus Wrote: TOTOH this sort of collision test using POINT depends upon 2 different color objects.
Wouldn't triangle collision be the way to test for stars colliding?
And this runs fine for me in 3.5 and 3.4.1 both, on a Windows 11, 64-bit machine.
RE: I need input on a possible bug in v3.5.0 - bplus - 01-20-2023
I just tried 2 Xmas Stars with Terry's code, looks like a complicated thing using a mask and requiring image object to fit exactly inside image width and height... I don't know. It didn't allow a simple substitution of images of 2 other objects. Damn might have to read the directions, all is lost ;-))
If Terry wants to try here are 2 images to check with collision code colors are red 255, blue 255 and clear or black background.
RE: I need input on a possible bug in v3.5.0 - TerryRitchie - 01-21-2023
Thanks for checking on this guys. False alarm.
After working with the tutorial user it was discovered that he didn't put the image files in the same folder. Evidently the image files were in his 3.4.1 folder but not his 3.5.0 folder.
Also, yeah, my pixel collision routine is quite clunky at best. Is there a better way to do pixel perfect detection? I would really welcome a more elegant solution if someone has one.
RE: I need input on a possible bug in v3.5.0 - bplus - 01-21-2023
nevermind... sorry
RE: I need input on a possible bug in v3.5.0 - TerryRitchie - 01-21-2023
(01-21-2023, 01:15 AM)bplus Wrote: Am I remembering @CodeGuy had some collision code for polynomials?
https://qb64forum.alephc.xyz/index.php?topic=2667.msg118777#msg118777
Wrong kind of collision, CodeGuy was always sorting things out.
I remember the Nspace stuff that he and I believe Darthwho were working on years ago and I did play with it. If I remember correctly is was painfully slow when images starting getting larger. Thank for the link though, I'll have another look at it.
(01-21-2023, 01:15 AM)bplus Wrote: nevermind... sorry
LOL, ok.
RE: I need input on a possible bug in v3.5.0 - bplus - 01-21-2023
I said never mind because I found another link and learned it was for regular polygons, heck I have that (I think quite recent).
I remember Petr took a shot at it, slow but for irregular shapes what can you expect. Your code (Terry's) is nice fast-wise.
It is nice challenge I set up a folder and started thinking about it.
RE: I need input on a possible bug in v3.5.0 - TempodiBasic - 01-21-2023
@TerryRithie
too late,
LOL, Your code work well on Windows 11 64 bit and QB64 2.0.2 and QB64PE 3.4.1
@Bplus
I have saved your stars and used in the collision demo...
I find an issue: the width and the height of the image is taken from the whole sprite and not for the dimensions of the star!
(all that black area is used like piece of image and not as transparent color! In other words the background of an image covers the other image when they overlaps.)
So I have thought that we must set black color (the background color of these images) as transparent before to make the Mask using TerryRitchie tool.
adding these two lines of code before calling MakeMask subroutine, we got it!
Code: (Select All) _SetAlpha 0, _RGB32(0), RedOval.image
_SetAlpha 0, _RGB32(0), GreenOval.image
but when we run the code we get another issue about the collisions: the function returns a collision also if there no is.
The result is the same also if we set to transparency the background color taken directly from the loaded images
as for example this code does
Code: (Select All) _Source RedOval.image
_SetAlpha 0, Point(10, 10), RedOval.image
_Source GreenOval.image
_SetAlpha 0, Point(10, 10), GreenOval.image
_Source 0
MakeMask RedOval ' create mask for red oval image
MakeMask GreenOval ' create mask for green oval image
so it needs further investigations about what happens with masks.
|