Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Code Snippets / Ball collision

Author
Message
trager
21
Years of Service
User Offline
Joined: 5th Feb 2003
Location: United Kingdom
Posted: 6th Feb 2003 15:44
I've noticed quite a few people asking for help with ball collision testing for golf games so I've dug up some old code of mine.

Basically it detects a ball colliding with a wall regardless of the speed of the ball; even if the ball is travelling at 100 pixels a frame it will still hit the wall.

I have a real issue with DB functions they never seem to produce quite the right results so if you think you can simplify this to DB feel free.

sync rate 40
sync on
autocam off
screenwidth = 320
halfwidth = screenwidth/2
screenheight = 220
halfheight = screenheight/2
maxspeed = 8



numballs=1

dim ball#(numballs,5)
x=0
y=1
xv=2
yv=3
mass=4
radius=5

randomize timer()
for lp = 0 to numballs
ball#(lp,x) = rnd(screenwidth)-halfwidth
ball#(lp,y) = rnd(screenheight)-halfheight
ball#(lp,xv) = 18
ball#(lp,yv) = rnd(maxspeed)

ball#(lp,radius) = 8
make object sphere lp+1, ball#(lp,radius)
color object lp+1, rgb(rnd(255),rnd(255),rnd(255))

next lp

width = 1
height = 3
dim wall#(1,4)
wall#(1,x) = 0
wall#(1,y) = 0
wall#(1,width) = 1
wall#(1,height) = 125
make object plain 100, wall#(1,width), wall#(1,height)

move camera -200

zrotate object 100,35
half_length# = wall#(1,height)/2

wall_start_x# = wall#(1,x) * cos(35) - (wall#(1,y)+half_length#) * sin(35)
wall_start_y# = wall#(1,x) * sin(35) + (wall#(1,y)+half_length#) * cos(35)
wall_end_x# = wall#(1,x) * cos(35) - (wall#(1,y)-half_length#) * sin(35)
wall_end_y# = wall#(1,x) * sin(35) + (wall#(1,y)-half_length#) * cos(35)



do

for lp=0 to numballs
ball#(lp,x) = ball#(lp,x) + ball#(lp,xv)
ball#(lp,y) = ball#(lp,y) + ball#(lp,yv)

if ball#(lp,x) >= halfwidth then ball#(lp,xv) = 0-ball#(lp,xv): ball#(lp,x) = halfwidth
if ball#(lp,x) = halfheight then ball#(lp,yv) = 0-ball#(lp,yv): ball#(lp,y) = halfheight
if ball#(lp,y) =0 and s# =0 and t#
trager
21
Years of Service
User Offline
Joined: 5th Feb 2003
Location: United Kingdom
Posted: 6th Feb 2003 15:45
What the...?
I think I'll try that again

trager
21
Years of Service
User Offline
Joined: 5th Feb 2003
Location: United Kingdom
Posted: 6th Feb 2003 15:46
sync rate 40
sync on
autocam off
screenwidth = 320
halfwidth = screenwidth/2
screenheight = 220
halfheight = screenheight/2
maxspeed = 8



numballs=1

dim ball#(numballs,5)
x=0
y=1
xv=2
yv=3
mass=4
radius=5

randomize timer()
for lp = 0 to numballs
ball#(lp,x) = rnd(screenwidth)-halfwidth
ball#(lp,y) = rnd(screenheight)-halfheight
ball#(lp,xv) = 18
ball#(lp,yv) = rnd(maxspeed)

ball#(lp,radius) = 8
make object sphere lp+1, ball#(lp,radius)
color object lp+1, rgb(rnd(255),rnd(255),rnd(255))

next lp

width = 1
height = 3
dim wall#(1,4)
wall#(1,x) = 0
wall#(1,y) = 0
wall#(1,width) = 1
wall#(1,height) = 125
make object plain 100, wall#(1,width), wall#(1,height)

move camera -200

zrotate object 100,35
half_length# = wall#(1,height)/2

wall_start_x# = wall#(1,x) * cos(35) - (wall#(1,y)+half_length#) * sin(35)
wall_start_y# = wall#(1,x) * sin(35) + (wall#(1,y)+half_length#) * cos(35)
wall_end_x# = wall#(1,x) * cos(35) - (wall#(1,y)-half_length#) * sin(35)
wall_end_y# = wall#(1,x) * sin(35) + (wall#(1,y)-half_length#) * cos(35)



do

for lp=0 to numballs
ball#(lp,x) = ball#(lp,x) + ball#(lp,xv)
ball#(lp,y) = ball#(lp,y) + ball#(lp,yv)

if ball#(lp,x) >= halfwidth then ball#(lp,xv) = 0-ball#(lp,xv): ball#(lp,x) = halfwidth
if ball#(lp,x) <= 0-halfwidth then ball#(lp,xv) = 0-ball#(lp,xv): ball#(lp,x) = 0-halfwidth
if ball#(lp,y) >= halfheight then ball#(lp,yv) = 0-ball#(lp,yv): ball#(lp,y) = halfheight
if ball#(lp,y) <= 0-halfheight then ball#(lp,yv) = 0-ball#(lp,yv): ball#(lp,y) = 0-halfheight
gosub plain_collision
next lp
for lp= 0 to numballs

position object lp+1, ball#(lp,x), ball#(lp,y), 0
next lp

sync
loop
end


plain_collision:
box# = ball#(lp,x) - ball#(lp,xv)
boy# = ball#(lp,y) - ball#(lp,yv)

ptx# = wall_start_x#
pty# = wall_start_y#

sox# = ball#(lp,x)-box#
soy# = ball#(lp,y)-boy#
if (sox#=0 and soy#=0) then return

length# = sqrt(sox#*sox#+soy#*soy#)
soox# = sox#
sooy# = soy#
rem collision test point from the centre of the ball to the leading edge of the ball
sox# = (ball#(lp,x) + 5 *(sox#/length#)) - box#
soy# = (ball#(lp,y) + 5 *(soy#/length#)) - boy#

stx# = wall_end_x#-ptx#
sty# = wall_end_y#-pty#
s# = ((0-soy#) * (box#-ptx#) + sox#*(boy#-pty#)) / ((0-stx#)*soy# + sox#*sty#)
t# = (stx# * (boy#-pty#) - sty# * (box#-ptx#)) / ((0-stx#)*soy# + sox#*sty#)

if s# >=0 and s# <=1
if t#>=0 and t#<=1

rem calculate the return
rem get perpendicular

ball#(lp,x) = box# + t# * soox#
ball#(lp,y) = boy# + t# * sooy#


nPx# = 0-sty#
nPy# = stx#

rem normalise Perpendicular
nPx# = nPx#/wall#(1,height)
nPy# = nPy#/wall#(1,height)

rem get N of ball
Nx# = 0-(ball#(lp,xv)*nPx# + ball#(lp,yv)*nPy#)*nPx#
Ny# = 0-(ball#(lp,xv)*nPx# + ball#(lp,yv)*nPy#)*nPy#

rem compute ball velocities
ball#(lp,xv)= 2*Nx#+ball#(lp,xv)
ball#(lp,yv)= 2*Ny#+ball#(lp,yv)

endif
endif
return

Noob
21
Years of Service
User Offline
Joined: 5th Feb 2003
Location: United Kingdom
Posted: 8th Feb 2003 15:57
Cheers mate this looks well useful for my golf game, will check it out when get 2 my other comp as this one does not have DB on it.

trager
21
Years of Service
User Offline
Joined: 5th Feb 2003
Location: United Kingdom
Posted: 8th Feb 2003 19:17
np I hope you find it helpfull

I am considering making a few changes to the code making it detect collision on shallow trajectories more acuratley (sooner).

I'll post it once Im finished.

Login to post a reply

Server time is: 2024-04-25 09:13:38
Your offset time is: 2024-04-25 09:13:38