Im am workin on typin it but its takin awhile its over 200 lines but its just really what you already have but with collisions (balls and pockets are the same but one scores the other bounces) and thats about it. Alright heres how spin works
1) topspin - add cos(topspin_angle) to foward momentum if this value is negative its called backspin
topspin will make a ball travel foward faster or slower but will have the opposite effect when the ball collides
with something backspin slow before collision fast after topspin fast before slow after
2) sidespin does this for sideways momentum and will make the ball travel along a curve to the left or right but it is
different when the ball collides with something it changes the angle of the bounce effect slightly
whilst traveling between collisions -
dirx = cos(ball_ang)*foward_momentum + cos(ball_ang+pi/2)*side_momentum
diry = sin(ball_ang)*foward_momentum + sin(ball_ang+pi/2)*side_momentum
new_posx = posx + dirx
new_posy = posy + diry
this should help you with the collisions with other balls and walls -
open window 640,512
window origin "cc"
degree = pi/180
doubpi = pi*2
halfpi = pi/2
kg = 1
m = 30
secs = 30
mins = 60*secs
mps = m/secs
rpm = doubpi/mins
rem initialise balls -
balls = 4
radius = 30
dim posx(balls), posy(balls), posz(balls)
dim dirx(balls), diry(balls), dirz(balls)
dim rotx(balls), roty(balls), rotz(balls)
dim r(balls), g(balls), b(balls)
for b = 0 to balls
repeat
rem randomise ball location -
posx(b) = ran(200) - ran(200)
posy(b) = ran(200) - ran(200)
posz(b) = ran(200) - ran(200)
rem ensure initial positions are clear of other balls -
h = radius*3
for a = 0 to balls
if (a <> b) then
rem check if location is already occupied -
adj = posx(b) - posx(a)
opp = posy(b) - posy(a)
hyp = sqrt(adj*adj + opp*opp)
if (hyp < h) h = hyp
fi
next
until (h>radius*2)
rem initialise other properties -
dirx(b) = ran(mps)*5 : rem only positive values are allowed
diry(b) = ran(mps)*5 : rem only positive values are allowed
dirz(b) = ran(mps)*5 : rem only positive values are allowed
rotx(b) = ran(doubpi)
roty(b) = ran(doubpi)
rotz(b) = ran(doubpi)
r(b) = ran(100)+ran(100)+ran(55) : rem balanced random colours
g(b) = ran(100)+ran(100)+ran(55) : rem balanced random colours
b(b) = ran(100)+ran(100)+ran(55) : rem balanced random colours
next
diry(0) = diry(0)*3
rem draw fake phong shaded balls -
sub pcircle(a,b,c) x = a+c/3 : y = b+c/3 : f = pi/8
for e = 0 to doubpi step f
gtriangle x,y to a+cos(e)*c,b+sin(e)*c to a+cos(e+f)*c,b+sin(e+f)*c
next
end sub
repeat
setdispbuf draw
draw = 1 - draw
setdrawbuf draw
clear window
rem draw balls
for b = 0 to balls
red = r(b)
grn = g(b)
blu = b(b)
setrgb 1, red, grn, blu
setrgb 2, red/10, grn/10, blu/10
setrgb 3, red/10, grn/10, blu/10
pcircle(posx(b),posy(b),radius)
setrgb 1, red*2, grn*2, blu*2
fill circle posx(b)+radius/3,posy(b)+radius/3,3
next
rem collision detection
for b = 0 to balls
rem update current ball position -
posx(b) = posx(b) + cos(rotz(b))*diry(b)
posy(b) = posy(b) + sin(rotz(b))*diry(b)
rem check new position against other balls
for a = 0 to balls
if (a <> b) then
rem calculate the distance between both balls
adj = posx(b) - posx(a)
opp = posy(b) - posy(a)
hyp = sqrt(adj*adj + opp*opp)
rem check if both balls overlap -
if (hyp < radius*2) then
rem find out how much they are overlapping by -
penetration = (radius*2) - hyp
rem rewind the current ball to the point of collision -
posx(b) = posx(b) - cos(rotz(b))*penetration
posy(b) = posy(b) - sin(rotz(b))*penetration
rem calculate new trajectories for the both balls -
rotz(b) = atan(-adj, opp) + halfpi
rotz(a) = atan(-adj, opp) - halfpi
rem energy is transferred between both balls and
rem each ball will lose energy as a result -
dx = dirx(b)/4 + dirx(a)/4 : rem relative velocity x
dy = diry(b)/4 + diry(a)/4 : rem relative velocity y
dx = dx*0.8 : rem coefficient of restitution
dy = dy*0.8 : rem coefficient of restitution
dirx(a) = dirx(a)/2 + dx
diry(a) = diry(a)/2 + dy
dirx(b) = dirx(b)/2 + dx
diry(b) = diry(b)/2 + dy
else
dirx(b) = dirx(b)*0.9999 : rem coefficient of friction
diry(b) = diry(b)*0.9999 : rem coefficient of friction
fi
fi
next
rem ensure that current ball doesn't leave the screen -
if (posx(b) < -320+radius) then
rotz(b) = pi - rotz(b)
posx(b) = -320 + radius
elsif (posx(b) > 320-radius) then
rotz(b) = pi - rotz(b)
posx(b) = 320 - radius
fi
if (posy(b) < -256+radius) then
rotz(b) = -rotz(b)
posy(b) = -256 + radius
elsif (posy(b) > 256-radius) then
rotz(b) = -rotz(b)
posy(b) = 256 - radius
fi
next
until (1 = 0)