Post by bplus on Feb 17, 2024 19:25:54 GMT
Collision detection is crucial to games and other graphics drawing.
There are 2 simple ones:
1. Using Point to detect colors at (x, y) ie ptColr~& = Point(x, y) ' load the color at x,y into ptColr~&
I would call this method the crudest and requires all objects to be certain colors. You kinda just feel around for colors and if clear or if an open space color you can move into or over that pixel. it only lets you know that that one point is safe or not. Fine for beginners because easy to understand.
2. Collision of 2 circle objects, this is about the nicest easiest method specially if the 2 objects of concern are round or nearly so. A square is sorta round so this method might be passable for two square objects or a square and a circle of near equal size, ehh. Best for 2 circles, for sure, because they don't have to be of equal size!
Let xc1, yc1 be the center of object 1 and let xc2, yc2 be the center of object 2 and r1 = radius of object 1 and r2 radius of object2
Function CircleCollision%(xc1, cyc1, r1, xc2, yc2, r2)
3. Is more advanced, collision between two rectagular objects, but is really handy to have in your Toolbox because all tiles, sprites and allot of graphics objects are rectangular.
Here is a demo for a good Collision detection of two rectangles:
There are 2 simple ones:
1. Using Point to detect colors at (x, y) ie ptColr~& = Point(x, y) ' load the color at x,y into ptColr~&
I would call this method the crudest and requires all objects to be certain colors. You kinda just feel around for colors and if clear or if an open space color you can move into or over that pixel. it only lets you know that that one point is safe or not. Fine for beginners because easy to understand.
2. Collision of 2 circle objects, this is about the nicest easiest method specially if the 2 objects of concern are round or nearly so. A square is sorta round so this method might be passable for two square objects or a square and a circle of near equal size, ehh. Best for 2 circles, for sure, because they don't have to be of equal size!
Let xc1, yc1 be the center of object 1 and let xc2, yc2 be the center of object 2 and r1 = radius of object 1 and r2 radius of object2
Function CircleCollision%(xc1, cyc1, r1, xc2, yc2, r2)
_Title "CircleCollision%() detection function" 'b+ 2024-02-17
Screen _NewImage(800, 600, 32)
_ScreenMove 200, 60
' circle 1 at center screen, radius 80
xc1 = 400: yc1 = 300: r1 = 80
' circle 2 xc2 = mx, yc2 = my, r2 = 30
r2 = 30
While _KeyDown(27) = 0 ' while no escape keypress
Cls
Circle (xc1, yc1), r1
'poll mouse
While _MouseInput: Wend
mx = _MouseX: my = _MouseY
Circle (mx, my), r2, &HFFFFFF00
If CircleCollision%(xc1, yc1, r1, mx, my, r2) Then _PrintString (400 - 36, 300 - 8), "Collision"
_Display
_Limit 60
Wend
Function CircleCollision% (xc1, yc1, r1, xc2, yc2, r2)
'xc1, yc1 center of circle 1 with radius r1
'xc2, yc2 center of circle 2 with radius r2
If _Hypot(xc1 - xc2, yc1 - yc2) <= Sqr((r1 + r2) * (r1 + r2)) Then CircleCollision% = -1
End Function
3. Is more advanced, collision between two rectagular objects, but is really handy to have in your Toolbox because all tiles, sprites and allot of graphics objects are rectangular.
Here is a demo for a good Collision detection of two rectangles:
Option _Explicit
_Title "Box1 Box2 Collision Detection Demo of a very Handy Sub!"
' Collision - Test orig by johnno called Bounding Box
'
' 2018-06-10 mod by B+ change for x, y, w, h of images
' by readjusting all the variables and setup for using in a very handy copy/paste SUB.
' So can reuse IN ANY APP using sprites / tiles / images
' 2019-08-30 rewrite this fordemo so mouse box never gets inside the central box
' 2020-03-03 update for my Toolbox
' 2024-02-17 review and update this for a box1 box2 collision demo
Const box1Width = 400 ' setup a White Central Box that will remain sationary
Const box1Height = 100
Const box1LeftX = 400 - box1Width / 2 ' put box smack in middle of screen 400 - half box width
Const box1TopY = 300 - box1Height / 2 ' center box on Y axis, 300 middle - half box height
Const mboxWidth = 50, mboxHeight = 40 ' mouse controled box height and width
Screen _NewImage(800, 600, 32) '<<< something more standard center is 400, 300
_ScreenMove 200, 60
Dim hey$(5) ' that center box is going to tell you when the mouse tries to run into it!
hey$(0) = "Hey!"
hey$(1) = "I beg your pardon."
hey$(2) = "Bang!"
hey$(3) = "Yikes!"
hey$(4) = "Ouch!"
hey$(5) = "Watch where you are going."
Dim k$ ' using Inkey$ to detect escape to quit
Dim mx, my ' locate mouse pixels
Dim mBoxX, mBoxY ' current mouse box (x, y)
Dim r$ ' pick a random reply from hey$()
Dim f~&, b~& ' fore and back Color of screen, reverse colors for print inside center box
'set colors using hexidexmal system
f~& = &HFFFFFFFF ' white
b~& = &HFF000000 ' black
Color f~&, b~&
Do
Cls ' clean sweep for next screen update
k$ = InKey$ ' await escape key press to quit
While _MouseInput: Wend ' <<< this polls mouse for status change since last check
mx = _MouseX: my = _MouseY ' save the mouse place (mx, my) currently
' calculate where the left, top corner is of mousebox (x, y) from current mouse location
mBoxX = mx - mboxWidth / 2 ' left x
mBoxY = my - mboxHeight / 2 ' top y
Line (box1LeftX, box1TopY)-Step(box1Width, box1Height), _RGB32(255, 255, 255), BF
Color b~&, f~&
r$ = "Move that mouse!"
_PrintString (box1LeftX + (box1Width - Len(r$) * 8) / 2, 292), r$
Color f~&, b~&
If TwoBoxCollision%(box1LeftX, box1TopY, box1Width, box1Height, mBoxX, mBoxY, mboxWidth, mboxHeight) Then
' draw box inside the center box after clearing text
Line (box1LeftX, box1TopY)-Step(box1Width, box1Height), _RGB32(255, 255, 255), BF
Line (mBoxX, mBoxY)-Step(mboxWidth, mboxHeight), _RGB32(255, 128, 0), BF
Beep ' complain!!!!
Color b~&, f~& ' reverse for inside center box
r$ = hey$(Int(Rnd * 6))
_PrintString (box1LeftX + (box1Width - Len(r$) * 8) / 2, 292), r$
_Display
Color f~&, b~& ' bounce back out
End If
Line (mBoxX, mBoxY)-Step(mboxWidth, mboxHeight), _RGB32(255, 128, 0), BF '<<< use step with width and height
_Display
_Limit 60
Loop Until k$ = Chr$(27)
' Description:
' Check for the collison of 2 rectangles given their top left x, y and width, height.
' Returns true value -1, if they overlap and false 0 if they don't.
Function TwoBoxCollision% (b1x, b1y, b1w, b1h, b2x, b2y, b2w, b2h)
' x, y represent the boxes left most x and top most y
' w, h represent the boxes width and height
' which is the usual way sprites / tiles / images are described
' such that boxbottom = by + bh
' and boxright = bx + bw
If (b1y + b1h < b2y) Or (b1y > b2y + b2h) Or (b1x > b2x + b2w) Or (b1x + b1w < b2x) Then
TwoBoxCollision% = 0 ' no collision = 0 False
Else
TwoBoxCollision% = -1 ' Collsion is true
End If
End Function