Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
I need input on a possible bug in v3.5.0
#31
While making the changes it dawned on me that a mask image is not needed at all! A simple check for two alpha values of 0 works as well. Use the same red oval and green oval images.

Code: (Select All)
'** Pixel Perfect Collision Demo #5

TYPE TypeSPRITE '             sprite definition
    image AS LONG '           sprite 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,y point definition
    x AS INTEGER '            x coordinate
    y AS INTEGER '            y coordinate
END TYPE

DIM RedOval AS TypeSPRITE '   red oval image
DIM GreenOval AS TypeSPRITE ' green oval image
DIM Intersect AS TypePOINT '  point of collision

RedOval.image = _LOADIMAGE("redoval.png", 32) '                       load red oval image image
GreenOval.image = _LOADIMAGE("greenoval.png", 32) '                   load green oval image

'+---------------------------------------------------------------------------------------------+
'| Set image transparent color. This does not need to be done for PNG files with transparency. |
'+---------------------------------------------------------------------------------------------+

_SETALPHA 0, _RGB32(255, 0, 255), RedOval.image '                     set image transparent color
_SETALPHA 0, _RGB32(255, 0, 255), GreenOval.image '                   set image transparent color
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


'------------------------------------------------------------------------------------------------------------
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 Test1& '   overlap image 1 to test for collision
    DIM Test2& '   overlap image 2 to test for collision
    DIM Hit% '     -1 (TRUE) if a collision occurs, 0 (FALSE) otherwise
    DIM Osource& ' original source image handle
    DIM p1~& '     alpha value of pixel on image 1
    DIM p2~& '     alpha value of pixel on image 2

    Obj1.x2 = Obj1.x1 + _WIDTH(Obj1.image) - 1 '  calculate lower right x,y coordinates of both objects
    Obj1.y2 = Obj1.y1 + _HEIGHT(Obj1.image) - 1
    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 coordinates
                    IF Obj2.y1 <= Obj1.y1 THEN y1% = Obj1.y1 ELSE y1% = Obj2.y1
                    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
                    Test1& = _NEWIMAGE(x2% - x1% + 1, y2% - y1% + 1, 32) '               make overlap image of object 1
                    Test2& = _NEWIMAGE(x2% - x1% + 1, y2% - y1% + 1, 32) '               make overlap image of object 2
                    _PUTIMAGE (-(x1% - Obj1.x1), -(y1% - Obj1.y1)), Obj1.image, Test1& ' place overlap area of object 1
                    _PUTIMAGE (-(x1% - Obj2.x1), -(y1% - Obj2.y1)), Obj2.image, Test2& ' place overlap area of object 2
                    x% = 0 '                                                             reset overlap area coordinate counters
                    y% = 0
                    Osource& = _SOURCE '                                                 remember calling source
                    DO '                                                                 begin pixel collide loop
                        _SOURCE Test1& '                                                 read from image 1
                        p1~& = _ALPHA32(POINT(x%, y%)) '                                 get alpha level of pixel
                        _SOURCE Test2& '                                                 read from image 2
                        p2~& = _ALPHA32(POINT(x%, y%)) '                                 get alpha level of pixel
                        IF (p1~& <> 0) AND (p2~& <> 0) THEN '                            are both pixels transparent?
                            Hit% = -1 '                                                  no, there must be a collision
                            Intersect.x = x1% + x% '                                     return collision coordinates
                            Intersect.y = y1% + y% '
                        END IF
                        x% = x% + 1 '                                                    increment column counter
                        IF x% > _WIDTH(Test1&) - 1 THEN '                                beyond last column?
                            x% = 0 '                                                     yes, reset x
                            y% = y% + 1 '                                                increment row counter
                        END IF
                    LOOP UNTIL y% > _HEIGHT(Test1&) - 1 OR Hit% '                        leave when last row or collision detected
                    _SOURCE Osource& '                                                   restore calling source
                    _FREEIMAGE Test1& '                                                  remove temporary image from RAM
                    _FREEIMAGE Test2&
                END IF
            END IF
        END IF
    END IF
    PixelCollide = Hit% '                                                                return result of collision check

END FUNCTION
Reply


Messages In This Thread
RE: I need input on a possible bug in v3.5.0 - by TerryRitchie - 01-21-2023, 05:40 PM



Users browsing this thread: 18 Guest(s)