Posted: 3rd Dec 2002 8:07
A small function to calculate a relection angle when bouncing off a circle. This is OK for 2D use, perhaps for sprites.

+ Code Snippet
function RoundReflect(ContactAng#,EntryAng#)
  rem --- ContactAng# = angle of contact on edge of circled area
  rem --- EntryAng# = angle of entry of object hitting circled area

  ta# = ContactAng# - 90.0
  ang# = wrapvalue(ta# + (ta#-EntryAng#))
endfunction ang#



...and a demo.


+ Code Snippet
#CONSTANT MAXBALLS  10
#CONSTANT LR   100
#CONSTANT SR   20

sync on : sync rate 60
randomize timer()

for s = 1 to MAXBALLS
  ink rgb(rnd(200)+55,rnd(200)+55,rnd(200)+55),0
  CircleFill(SR,SR,SR,SR)
  get image s,0,0,SR*2,SR*2
  sprite s,rnd(50)+50,rnd(50)+50,s
  set sprite s,0,1
  offset sprite s,SR,SR
  Rotate sprite s,rnd(359)
next s

ink rgb(255,0,0),0

repeat
  cls
  CircleFill(320,240,LR,LR)

  for s = 1 to MAXBALLS

    move sprite s,5

    rem --- keep sprites on screen
    sx = sprite x(s) : sy = sprite y(s)
    if (sx > 639) or (sx  479) or (sy  639 then dec sx, 639
      if sx  479 then dec sy, 479
      if sy = 0.0 then inc ang#,90.0 else inc ang#,270.0
  endif
endfunction ang#

function RoundReflect(ContactAng#,EntryAng#)
  rem --- ContactAng# = angle of contact on edge of circled area
  rem --- EntryAng# = angle of entry of object hitting circled area

  ta# = ContactAng# - 90.0
  ang# = wrapvalue(ta# + (ta#-EntryAng#))
endfunction ang#



During the demo you may see a ball sticking to the edge of the circle for a second, that's not the fault of the RoundReflect() function. It's the fault of the overlap of the ball and the red circle. I just wanted to do enough to demonstrate the function.

Posted: 3rd Dec 2002 8:09
Bloody forum! hehe

It did'nt copy my demo properly, lets try again.


#CONSTANT MAXBALLS 10
#CONSTANT LR 100
#CONSTANT SR 20

sync on : sync rate 60
randomize timer()

for s = 1 to MAXBALLS
ink rgb(rnd(200)+55,rnd(200)+55,rnd(200)+55),0
CircleFill(SR,SR,SR,SR)
get image s,0,0,SR*2,SR*2
sprite s,rnd(50)+50,rnd(50)+50,s
set sprite s,0,1
offset sprite s,SR,SR
Rotate sprite s,rnd(359)
next s

ink rgb(255,0,0),0

repeat
cls
CircleFill(320,240,LR,LR)

for s = 1 to MAXBALLS

move sprite s,5

rem --- keep sprites on screen
sx = sprite x(s) : sy = sprite y(s)
if (sx > 639) or (sx < 0) or (sy > 479) or (sy < 0)
if sx > 639 then dec sx, 639
if sx < 0 then inc sx, 639
if sy > 479 then dec sy, 479
if sy < 0 then inc sy, 479
sprite s,sx,sy,sprite image(s)
endif

rem --- are we close enough to ricochet of the red circle?
d# = Dist2D(320,240,sx,sy) - SR - LR

rem --- if we are then bounce off
if d# <= 0.0
contact# = GetAngle(320,240,sx,sy)
ref# = RoundReflect(contact#,sprite angle(s))
rotate sprite s, ref#
endif

next s

sync
until spacekey()

end


function CircleFill(xcenter,ycenter,xradius,yradius)
rem --- find vertical ratio to help draw ellipses
xr# = xradius : yr# = yradius
vr# = yr# / xr#

r2 = xradius * xradius
for x = 1 to xradius
y = sqrt(r2 - (x*x)) * vr#
box xcenter - x, ycenter - y, xcenter + x, ycenter + y
next x
endfunction

function Dist2D(x1,y1,x2,y2)
xd = x1 - x2
yd = y1 - y2
dist = sqrt((xd*xd)+(yd*yd))
endfunction dist


function GetAngle(cx#,cy#,x#,y#)
a# = (y# - cy#)
b# = (x# - cx#)

if b# = 0.0
if a# <= 0.0 then ang# = 0.0 else ang# = 180.0
else
ang# = atan(a#/b#)
if b# >= 0.0 then inc ang#,90.0 else inc ang#,270.0
endif
endfunction ang#

function RoundReflect(ContactAng#,EntryAng#)
rem --- ContactAng# = angle of contact on edge of circled area
rem --- EntryAng# = angle of entry of object hitting circled area

ta# = ContactAng# - 90.0
ang# = wrapvalue(ta# + (ta#-EntryAng#))
endfunction ang#
Posted: 30th Dec 2002 23:31
hmmm.......would it be possible to use this code for a pool game for example?
Posted: 31st Dec 2002 1:23
I did'nt think I'd see this post ever again

I originaly created this function for an Asteriods clone I was working on, were I would have shots bouncing off tougher asteriods and enemy ship shields (development currently on hold), but you can use this for any game that needs it.

Remember though, Don't let your balls overlap, It's very painful