set display mode 1024,768,32
sync on
sync rate 0
sync
randomize timer()
backdrop on
color backdrop 0
set image colorkey 0,0,0
autocam off
PERFORM CHECKLIST FOR FONTS
SET TEXT FONT "arial"
EMPTY CHECKLIST
set text size 50
set text to bold
hide mouse
 
global spd#
global spdinc#
global maxspd#
global numbox
 
brand_new_game:
 
 ` some setup functions
make_images()
makeexplosionboxes()
ink rgb(100,0,255),0
 
 ` you
make object box 1,13,13,13
 ` the dummy object you point at
make object box 2,0,0,0
hide object 2
 ` the sphere that represents the thing that you don't want the ball to hit
make object sphere 3,32
position object 3,0,0,0
 ` the ball
make object sphere 4,9
 ` texture the player's objects black&white
for t=1 to 4
 texture object t,11
next t
 
score=0
level=1
 
beginanewlevelhere:
 
 ` out with the old before in with the new:
delobs()
 
if level>11 then end_of_game(score)
 
` get the data for the level.
  ` the "restore" and "for/next t loop" are unnecessary, but DO allow you to hard-code
   ` a different starting level.
  restore
 for t=1 to level
read spd#,spdinc#,maxspd#
read numbox,boxsize,boxdist
read boxmove#,oscilate
 next t
 
  ` set up some starting values for the level.
if numbox<1 then numbox=20
offset#=0.0
ballheld=1
boxleft=numbox
degree#=0.0
f#=0.1
 
 ` make the target boxes for the level.
x=0
y=(360/numbox)
for t=101 to 100+numbox
 make object box t,boxsize,boxsize,boxsize
 texture object t,level
 d=boxdist
 position object t,sin(x)*d,cos(x)*d,0
 x=x+y
next t
 
 ` make the skybox for the level.
make object cube 100,1000
set object light 100,0
set object cull 100,0
texture object 100,level
set object collision off 100
position object 100,0,0,-250
 
 ` show the approach to the new level.
approach(level)
position camera 0,0,-250
 
` this should be set right before the loop, to ensure accuracy the timer-based movement.
T1#=TIMER()
 
do
 
 ` this makes it so that in level 11, the boxes go both directions
if level=11
 if abs(boxmove#)>0.9 then f#=-f# : boxmove#=boxmove#+f#*gs#
 boxmove#=boxmove#+f#*gs#
   ` this gives you all the textures of the boxes so far, to contrast with the
    ` now black-and-white environment.
  for t=1 to 4
   texture object t,rnd(9)+1
  next t
endif
 
 ` timer-based movement:
GS#=(TIMER()-T1#)*0.010
T1#=TIMER()
 
 ` this moves and positions and points the player
offset#=offset#+(rightkey()-leftkey())*(29+level)*gs#
position object 1,sin(offset#)*20,cos(offset#)*20,0
position object 2,sin(offset#)*230,cos(offset#)*230,0
point object 1,object position x(2),object position y(2),object position z(2)
 
 ` degree# is a counter used to measure in/out oscillation.
degree#=degree#+gs#*4
if degree#>360.0 then degree#=degree#-360.0
 
 ` this positions the boxes according to the variables of the level...
  ` their speed, distance, oscillation (in/out)
x=0
y=(360/numbox)
d=(boxdist+(sin(degree#)*oscilate))
if d<50 then d=50
if d>150 then d=150
for t=101 to 100+numbox
 boxpos#=boxpos#+(boxmove#*gs#)
 if boxpos#>360.0 then boxpos#=boxpos#-360.0
 position object t,sin(boxpos#+x)*d,cos(boxpos#+x)*d,0
 x=x+y
next t
 
 ` if you are holding the ball, it is positioned on your paddle.
  ` this is the only place that we check the spacekey() to launch it.
if ballheld=1
 position object 4,object position x(1),object position y(1),object position z(1)
 point object 4,object position x(2),object position y(2),object position z(2)
 move object 4,11
  if spacekey() then  ballheld=0
endif
 
 
 ` these are things that happen when you are NOT holding the ball
   ` it is moved, and we check for collisions with boxes and your inner sphere.
if ballheld=0
 move object 4,spd#*gs#
 
  ` this checks collision with boxes, sets up new explosions, and bounces the ball
 x=object collision(4,0)
 if x>100 and x<200
  explode(x,level)
  hide object x
  set object collision off x
  redirball()
  dec boxleft
  score=score+10*level
 endif  : ` hit a box object
 
 ` if the ball hits your paddle/shield/cube, send it out in the same direction.
if x=1
 rotate object 4,object angle x(1),object angle y(1),object angle z(1)
endif : ` hit your paddle
 
 ` this detects collision on your inner sphere, deducts your score, and makes you explode.
  ` it also sets the 'ballheld' flag, and takes some speed off the ball.
if x=3
 if level>1
  score=score-level*50
  if score<0 then score=0
 endif
 ballheld=1
 explode(3,11)
 spd#=spd#-3.0
 if spd#<15.0 then spd#=15.0
endif
 
 endif : ` if ball is NOT HELD
 
 
  ` this keeps the ball within a circular arena (even though the screen is square)
if sqdisob(1,4)>23000
 redirball()
endif
 
 ` this checks to send you to the next level. it allows you to witness the end of the explosion
if boxleft<1
 inc level
for x=1 to 30
 for t=201 to 220
  move object t,15*gs#
 next t
 sync
next x
 goto beginanewlevelhere
endif
 
` this keeps the background moving
rotate object 100,object angle x(100)+gs#,object angle y(100)+gs#,object angle z(100)+gs#
 
 ` this keeps your inner sphere moving
rotate object 3,rnd(360),rnd(360),rnd(360)
 
` this moves the explosion bits. it is always on. they go till you can't see them anymore.
for t=201 to 220
 move object t,15*gs#
next t
 
 ` print score to screen:
text 20,20,str$(score)
 
sync : loop
 
function sqdisob(a,b)
 dist=(object position x(a)-object position x(b))^2+(object position y(a)-object position y(b))^2
` this provides distance checking only on the x&y axes (that's all we use here),
 ` and it reports the squared distance value, to avoid using the SQRT() command, because
  ` that's a slow command. you must then check this against the distance you want, but squared.
endfunction dist
 
function delobs()
 ` deletes objects to begin a new level
for t=100 to 199
 if object exist(t) then delete object t
next t
for t=201 to 220
 position object t,0,0,-300
 point object t,0,0,-400
next t
endfunction
 
function makeexplosionboxes()
 ` only called once. makes 20 boxes for explosions.
for t=201 to 220
 make object box t,5,5,5
 position object t,0,0,-300
 point object t,0,0,-400
 ghost object on t
 set object collision off t
next t
endfunction
 
function make_images()
  ` images 1-11 are made random for each game.
 for z=1 to 10
create bitmap 1,32,32
 ink rgb(rnd(150+50),rnd(150+50),rnd(150+50)),0
 box 0,0,31,31
for t=1 to 15
 ink rgb(rnd(150+50),rnd(150+50),rnd(150+50)),0
 x=rnd(29-t)
 y=rnd(29-t)
 box x,y,x+2+t,y+2+t
next t
get image z,0,0,31,31
delete bitmap 1
 next z
 
create bitmap 1,32,32
ink rgb(255,255,255),0
 for t=1 to 300
  dot rnd(31),rnd(31)
 next t
get image 11,0,0,31,31
delete bitmap 1
 
endfunction
 
function explode(a,b)
 ` this positions a new explosion at object position(a), and textures it as 'B'.
x=object position x(a)
y=object position y(a)
for t=201 to 220
 position object t,x,y,0
 rotate object t,rnd(360),rnd(360),rnd(360)
 texture object t,b
next t
endfunction
 
function redirball()
` this covers what happens when to ball hits a box or the outer bounds.
 ` it is redirected and sped up.
 
  ` this z-flag system checks to see whether the ball is heading IN or OUT at the moment.
   ` it it's heading IN and hits something, then it's bounced back OUT (z=1)
z=0
a=sqdisob(1,4)
move object 4,5
b=sqdisob(1,4)
move object 4,-5
if b<a then z=1
 ` if the ball is already near the outer bounds, it just comes back in.
if a>22000 or b>22000 then z=0
 
` this imparts a random factor to the ball as it comes back IN.
point object 4,rnd(60)-30,rnd(60)-30,0
 
 ` if z flag is 1, then it's rotated to face outwards.
if z=1 then zrotate object 4,object angle z(4)+200-rnd(40)
 
 ` this inc's the ball's speed. a new max speed of 33.3 is in effect.
spd#=spd#+spdinc#/2.0
if spd#>33.3 then spd#=33.3
 
endfunction
 
function approach(l)
  ` this shows the approach to a new level.
 for t=201 to 220
  hide object t
 next t
 for t=1 to 4
  hide object t
 next t
for t=-600 to -250 step 5
position camera 0,0,t
position object 100,0,0,t
center text 512,300,"LEVEL "+STR$(L)
sync
next t
 for t=201 to 220
  show object t
 next t
 for t=1 to 4
  show object t
 next t
endfunction
 
function end_of_game(s)
 
for t=1 to 4
 hide object t
next t
 
for t=201 to 220
 texture object t,rnd(9)+1
 scale object t,300,300,300
 ghost object off t
next t
 
make object cube 100,1000
set object light 100,0
set object cull 100,0
texture object 100,11
set object collision off 100
position object 100,0,0,-250
position camera 0,0,-250
 
do
 
GS#=(TIMER()-T1#)*0.010
T1#=TIMER()
 
 boxpos#=boxpos#+(2.0*gs#)
 if boxpos#>360.0 then boxpos#=boxpos#-360.0
 
 ` make some spinning boxes for the background
x=0
for t=201 to 210
  position object t,sin(boxpos#+x)*75,cos(boxpos#+x)*75,0
 x=x+36
next t
x=0
for t=211 to 220
 position object t,sin(-boxpos#+x)*125,cos(-boxpos#+x)*125,0
 x=x+36
next t
 
center text 512,280,"YOUR SCORE:"
center text 512,320,str$(s)
center text 512,380,"PERFECT SCORE:"
center text 512,420,"29370"
center text 512,640,"press [space] to play again"
center text 512,680,"or [escape] to quit"
 
if spacekey()
` start a new game...delete old objects first
 for t=201 to 220
  delete object t
 next t
  for t=1 to 11
   delete image t
  next t
   for t=1 to 4
    delete object t
   next t
    goto brand_new_game
endif
 
if escapekey() then end
 
sync
loop
 
endfunction
 
LEVEL_ONE_DATA:
`spd#,spdinc#,maxspd#
data 10.0,0.250,20.0
`numbox,boxsize,boxdist
data 10,50,100
`boxmove#,oscilate
data 0.035,0
` points available on this level: 100
 
LEVEL_Two_DATA:
`spd#,spdinc#,maxspd#
data 11.0,0.250,30.0
`numbox,boxsize,boxdist
data 40,15,100
`boxmove#,oscilate
data -0.05,10
` 800
 
LEVEL_Three_DATA:
`spd#,spdinc#,maxspd#
data 12.0,0.250,40.0
`numbox,boxsize,boxdist
data 20,30,100
`boxmove#,oscilate
data 0.10,25
 ` 20*30=600
 
LEVEL_four_DATA:
`spd#,spdinc#,maxspd#
data 13.0,0.350,40.0
`numbox,boxsize,boxdist
data 30,20,100
`boxmove#,oscilate
data -0.15,250
 ` 30*40=1200
 
LEVEL_five_DATA:
`spd#,spdinc#,maxspd#
data 14.0,0.350,20.0
`numbox,boxsize,boxdist
data 60,40,135
`boxmove#,oscilate
data 0.25,0
 ` 60*50=3000
 
LEVEL_six_DATA:
`spd#,spdinc#,maxspd#
data 15.0,0.250,30.0
`numbox,boxsize,boxdist
data 16,15,125
`boxmove#,oscilate
data -1.00,25
 ` 16*60=960
 
LEVEL_seven_DATA:
`spd#,spdinc#,maxspd#
data 16.0,0.250,40.0
`numbox,boxsize,boxdist
data 45,10,150
`boxmove#,oscilate
data 0.25,75
 ` 45*70=3150
 
LEVEL_eight_DATA:
`spd#,spdinc#,maxspd#
data 17.0,0.250,40.0
`numbox,boxsize,boxdist
data 30,20,75
`boxmove#,oscilate
data -0.15,0
  ` 30*80=2400
 
LEVEL_nine_DATA:
`spd#,spdinc#,maxspd#
data 18.0,0.250,30.0
`numbox,boxsize,boxdist
data 36,15,125
`boxmove#,oscilate
data 0.10,50
 ` 36*90=3240
 
LEVEL_ten_DATA:
`spd#,spdinc#,maxspd#
data 19.0,0.250,40.0
`numbox,boxsize,boxdist
data 60,10,150
`boxmove#,oscilate
data -0.25,75
 ` 60*100=6000
 
LEVEL_eleven_DATA:
`spd#,spdinc#,maxspd#
data 20.0,0.250,40.0
`numbox,boxsize,boxdist
data 72,12,100
`boxmove#,oscilate
data 0.15,50
 ` 72*110=7920
 
` my high score: 18,020
` perfect score: 29,370