I'm horrible explaining anything with words so I'll just do it with codes. So far, this is what I know about collisions.
remstart
Ashingda - This Example shows:
* Box collision fencing outward
* Box collision fencing inward
* Radius collision fencing outward
- Radius fencing inward is not shown but can easily be done
by switching a few operaters (-,+)
None of this requires sprites, point(), 3d Statements, or memblocks.
-Others
Pixel collision is the same as Box collision. You set a Box collision
with the same dimension as your Image as they are both squared it's
not hard to do. Once the pointer is within the collision area, you
switch to a memblock and check the designated pixel.
remend
set display mode 640,480,16
create bitmap 1,640,480
sync on
sync rate 0
dim FpsTimer(0)
BallX# = 200
BallY# = 200
MoveBallX# = 1
MoveBallY# = 1
BallR = 5
PaddleX# = 321
PaddleY# = 360
PaddleR = 40
do
gosub Example
ink rgb(255,255,255),0
text 200,0,str$(mousex())+","+str$(mousey())
copy bitmap 1,0
SyncTimer(60)
cls
loop
Example:
for FrameSkip = 0 to 1
gosub BrickHandle
gosub BorderHandle
gosub RoundPaddle
gosub BallHandle
next FrameSkip
gosub Display
return
BrickHandle:
BrickX = 320
BrickY = 240
x1 = BrickX-(25+BallR)
y1 = BrickY-(8+BallR)
x2 = BrickX+(32+BallR)
y2 = BrickY+(8+BallR)
`Boxed collision fencing outward
if CheckArea(BallX#+MoveBallX#,BallY#+MoveBallY#,x1,y1,x2,y2) = 1
`While checking outward it's best to only check 1 or the other
if BallY#-BallR < y1 or BallY#+BallR > y2
MoveBallY# = MoveBallY# * -1
BallY# = BallY# + MoveBallY#
`If you dont increase BallY# here it'll cause bugs and
`the same for others.
else
if BallX#-BallR < x1 or BallX#+BallR > x2
MoveBallX# = MoveBallX# * -1
BallX# = BallX# + MoveBallX#
endif
endif
endif
return
BorderHandle:
BorderX = 321
BorderY = 240
x1 = BorderX-(200-BallR)
y1 = BorderY-(120-BallR)
x2 = BorderX+(200-BallR)
y2 = BorderY+(120-BallR)
`Boxed collision fencing inward
if CheckArea(BallX#+MoveBallX#,BallY#+MoveBallY#,x1,y1,x2,y2) = 0
`While checking inward it's best to have both checks
if BallY#-BallR < y1 or BallY#+BallR > y2
MoveBallY# = MoveBallY# * -1
BallY# = BallY# + MoveBallY#
endif
if BallX#-BallR < x1 or BallX#+BallR > x2
MoveBallX# = MoveBallX# * -1
BallX# = BallX# + MoveBallX#
endif
endif
return
RoundPaddle:
`Moving the RoundedPaddled around
inc PaddleX#, rightkey() - leftkey()
inc PaddleY#, downkey() - upkey()
if PaddleX#<80 then PaddleX#=80
if PaddleX#>560 then PaddleX#=560
if PaddleY#<80 then PaddleY# = 80
if PaddleY#>400 then PaddleY# = 400
`Radius collision fencing outward
if CheckDist(BallX#,BallY#,PaddleX#,PaddleY#,BallR+PaddleR)
r = atanfull(PaddleX#-BallX#,PaddleY#-BallY#)
MoveBallX# = sin(r)*-1
MoveBallY# = cos(r)*-1
endif
return
BallHandle:
BallX# = BallX# + MoveBallX#
BallY# = BallY# + MoveBallY#
return
Display:
`Draw the Brick for Example
ink rgb(0,255,255),0
dot BrickX, BrickY
LineBox(BrickX-32,BrickY-8,BrickX+32,BrickY+8)
`Draw the border for Example
ink rgb(255,0,0),0
dot BorderX,BorderY
LineBox(BorderX-200,BorderY-120,BorderX+200,BorderY+120)
ink rgb(155,155,155),0
FillCircle(PaddleX#,PaddleY#,PaddleR)
ink rgb(255,255,255),0
FillCircle(BallX#,BallY#,BallR)
return
`Ashingda - Check to see if (px,py) is inside [x1,y2,x2,y2]
Function CheckArea(BallX#,BallY#,x1,y1,x2,y2)
if BallX#>x1 and BallX#<x2 and BallY#>y1 and BallY#<y2 then EndFunction 1
EndFunction 0
`Ashingda - Check to see if BallX,BallY are with the Paddle's radius
Function CheckDist(BallX#,BallY#,PaddleX#,PaddleY#,r)
diffX = (BallX#-PaddleX#)
diffY = (BallY#-PaddleY#)
dist = sqrt(diffX*diffX + diffY*diffY)
if dist < r then EndFunction 1
EndFunction 0
Function FillCircle(x#,y#,r)
sr = r*r
for i = 1 to r
h = sqrt( sr - i*i )
box x# - i, y# - h, x# + i, y# + h
next i
EndFunction
Function LineBox(x1,y1,x2,y2)
box x1,y1,x2,y1
box x1,y1,x1,y2
box x2,y1,x2,y2
box x1,y2,x2,y2
EndFunction
Function Fps()
ink rgb(255,255,255),0
text 0,0,"FPS: "+str$(screen fps())
EndFunction
Function SyncTimer(FpsRate)
FpsRate = (1000/FpsRate)+FpsTimer(0)
repeat
until timer() > FpsRate
FpsTimer(0) = timer()
sync
EndFunction