Post by Tom Not logged in on Jul 13, 2004 20:24:35 GMT -5
Try this!
const ballWallBounce# = .8
const ballPinBounce# = .4
const ballBallBounce# = .7
const friction# = 0.1
const debug = false
const ballRadius# = 7
struc SBall
dim pos#(1)
dim vel#(1)
dim radius#
dim active
dim moving
endstruc
struc SWall
dim pos#(1)
dim pin
dim T#(1)
dim N#(1)
dim l#
endstruc
WallData:
data -70, 200
data -85, 215
data -100, 215
data -115, 200
data -115, 185
data -100, 170
data -100, 30
data -110, 20
data -120, 20
data -130, 10
data -130, -10
data -120, -20
data -110, -20
data -100, -30
data -100, -170
data -115, -185
data -115, -200
data -100, -215
data -85, -215
data -70, -200
data 70, -200
data 85, -215
data 100, -215
data 115, -200
data 115, -185
data 100, -170
data 100, -30
data 110, -20
data 120, -20
data 130, -10
data 130, 10
data 120, 20
data 110, 20
data 100, 30
data 100, 170
data 115, 185
data 115, 200
data 100, 215
data 85, 215
data 70, 200
data 0, 0
const maxBalls = 16
dim maxWalls
dim SBall balls(maxBalls - 1), SBall& ball, SBall& ball2, SBall pin
dim x#, y#, i, j, x, y
dim timeFrame#
dim pos#(1), vel#(1), radius#, a#, b#, c#, sqrtTerm#
dim time#, t1#, t2#, colTime#, colType
dim SBall &colBall, SBall &colBall2, SWall &colWall
dim num#, denom#, N#(1), l#
dim moving
read x#, y#
while x# <> 0 or y# <> 0
maxWalls = maxWalls + 1
read x#, y#
wend
reset WallData
dim SWall walls(maxWalls - 1), SWall& wall, SWall& wall2
for i = 0 to maxWalls - 1
&wall = &walls(i)
read wall.pos#(0), wall.pos#(1)
next
for i = 0 to maxWalls - 1
&wall = &walls(i)
&wall2 = &walls((i+1)%maxWalls)
wall.T# = wall2.pos# - wall.pos#
wall.l# = Length (wall.T#)
wall.T# = wall.T# / wall.l#
wall.N# = vec2 (-wall.T#(1), wall.T#(0))
next
for i = 0 to maxWalls - 1
&wall = &walls(i)
&wall2 = &walls((i-1)%maxWalls)
wall.pin = wall.T# * wall2.N# < 0
next
glMatrixMode (GL_PROJECTION)
glLoadIdentity ()
glOrtho (-400, 400, 300, -300, 0, 1)
glMatrixMode (GL_MODELVIEW)
TextMode (TEXT_OVERLAID)
goto Start
DrawScreen:
glClear (GL_DEPTH_BUFFER_BIT or GL_COLOR_BUFFER_BIT)
glLoadIdentity ()
glBegin (GL_LINE_LOOP)
for i = 0 to maxWalls - 1
glVertex2fv (walls (i).pos#)
next
glEnd ()
for i = 0 to maxBalls - 1
&ball = &balls(i)
if ball.active then
gosub DrawBall
endif
next
return
DrawBall:
glPushMatrix ()
glTranslatef (ball.pos#(0), ball.pos#(1), 0)
glScalef (ball.radius#, ball.radius#, ball.radius#)
glBegin (GL_LINE_LOOP)
for j = 0 to 35
glVertex2f (sind (j * 10), cosd (j * 10))
next
glEnd ()
glPopMatrix ()
return
UpdateGame:
const NO_COLLISION = 0
const WALL_COLLISION = 1
const PIN_COLLISION = 2
const BALL_COLLISION = 3
timeFrame# = 1
while timeFrame# > 0
colTime# = timeFrame#
colType = NO_COLLISION
for i = 0 to maxBalls - 1
&ball = &balls (i)
if ball.active and ball.moving then
for j = 0 to maxWalls - 1
&wall = &walls (j)
denom# = -ball.vel# * wall.N#
if denom# > 0 then
num# = (ball.pos# - wall.pos#) * wall.N#
if num# > 0 and num# < ball.radius# then
num# = 0
else
num# = num# - ball.radius#
endif
if num# >= 0 and num# < denom# * colTime# then
time# = num# / denom#
pos# = ball.pos# + ball.vel# * time#
x# = (pos# - wall.pos#) * wall.T#
if x# >= 0 and x# <= wall.l# then
colTime# = time#
colType = WALL_COLLISION
&colBall = &ball
&colWall = &wall
endif
endif
endif
next
endif
next
for i = 0 to maxBalls - 1
&ball = &balls (i)
if ball.active and ball.moving then
for j = 0 to maxWalls - 1
&wall = &walls (j)
if wall.pin then
pin.pos# = wall.pos#
&ball2 = &pin
gosub BallToBallCollision
if time# < colTime# then
colTime# = time#
colType = PIN_COLLISION
&colBall = &ball
&colWall = &wall
endif
endif
next
endif
next
for i = 0 to maxBalls - 2
&ball = &balls (i)
if ball.active then
for j = i + 1 to maxBalls - 1
&ball2 = &balls (j)
if ball2.active and (ball.moving or ball2.moving) then
gosub BallToBallCollision
if time# < colTime# then
colTime# = time#
colType = BALL_COLLISION
&colBall = &ball
&colBall2 = &ball2
endif
endif
next
endif
next
for i = 0 to maxBalls - 1
&ball = &balls (i)
if ball.active and ball.moving then
ball.pos# = ball.pos# + ball.vel# * colTime#
endif
next
timeFrame# = timeFrame# - colTime#
if colType = WALL_COLLISION then
colBall.vel# = colBall.vel# - (1 + ballWallBounce#) * (colBall.vel# * colWall.N#) * colWall.N#
endif
if colType = PIN_COLLISION then
N# = Normalize (colBall.pos# - colWall.pos#)
colBall.vel# = colBall.vel# - (1 + ballPinBounce#) * (colBall.vel# * N#) * N#
endif
if colType = BALL_COLLISION then
N# = Normalize (colBall.pos# - colBall2.pos#)
l# = (colBall.vel# - colBall2.vel#) * N# * (1 + ballBallBounce#)
N# = N# * l# / 2
colBall.vel# = colBall.vel# - N#
colBall2.vel# = colBall2.vel# + N#
colBall.moving = true
colBall2.moving = true
endif
wend
moving = false
for i = 0 to maxBalls - 1
&ball = &balls (i)
if ball.active and ball.moving then
l# = Length (ball.vel#)
if l# <= friction# then
ball.vel# = vec2 (0, 0)
ball.moving = false
else
ball.vel# = ball.vel# * (l# - friction#) / l#
moving = true
endif
endif
next
return
BallToBallCollision:
time# = colTime#
pos# = ball.pos# - ball2.pos#
vel# = ball.vel# - ball2.vel#
if pos# * vel# < 0 then
radius# = ball.radius# + ball2.radius#
a# = vel# * vel#
b# = pos# * vel# * 2
c# = pos# * pos# - radius# * radius#
sqrtTerm# = b# * b# - 4 * a# * c#
if sqrtTerm# >= 0 then
sqrtTerm# = sqrt (sqrtTerm#)
t1# = (-b# - sqrtTerm#) / (2 * a#)
t2# = (-b# + sqrtTerm#) / (2 * a#)
if t2# >= 0 then
if t1# < 0 then
time# = 0
else
time# = t1#
endif
endif
endif
endif
return
Start:
const rackY# = 70
const DY# = 150
const spacing# = .15
i = 1
for y = 1 to 4
y# = -rackY# - y * ballRadius# * (sqrt(3) + spacing#)
x# = -(y - 1) * (ballRadius# + spacing#)
for x = 1 to y
&ball = &balls(i)
ball.pos# = vec2 (x#, y#)
ball.radius# = ballRadius#
ball.active = true
x# = x# + (ballRadius# + spacing#) * 2
i = i + 1
next
next
&ball = &balls (0)
ball.radius# = ballRadius#
ball.pos# = vec2 (0, DY#)
ball.vel# = vec2 ((rnd () % 2000 - 1000) / 100.0, (rnd () % 2000 - 1000) / 100.0 - 25)
ball.active = true
ball.moving = true
moving = true
gosub DrawScreen
SwapBuffers ()
Sleep (2000)
while moving
while SyncTimer (50)
gosub UpdateGame
wend
gosub DrawScreen
SwapBuffers ()
wend
Sleep (2000)
run