` DBC Challenge - matrix - LBFN
` arrow keys to move up/ down/ left/ right
` Return key to move faster
` 'F' key to fire - let go and press again to fire again - previous shot will be deleted
` Avoid the enemies' shots and don't let them run into you.
` 'Q' key to quit.
randomize timer()
sync on : sync rate 60
backdrop on : hide mouse
autocam off : fog off
draw to front
set camera range 1.0,5000.0
dim PhotonStat(1) : dim target(3) : dim score(1) : dim EShot(1)
dim Enemy(80,12) : dim PartDirection(51) : dim lives(1)
texture = 1 : stars = 10 : FireBall = 11
score = 0 : lives(1) = 4 : NextZMovePoint# = 13824.0 : EShotStat = 0
ExplodeEnemy = 0 : PhotonStat(1) = 0 : PartMoveCtr = 0
MakeImages(texture,stars,FireBall)
gosub MakeStuff
SetupMatrix(texture)
MakeEnemies()
FirePhotonDelay# = timer() + 50.0
FireEShotDelay# = timer() + 500.0
ms = (screen width()/2) : mt = (screen height()/2)
position camera rnd(450) + 1150.0,rnd(180) + 30.0,0.0
 
do
   x#=camera position x() : y#=camera position y() : z#=camera position z()
  ` position stars object
  position object 12,x#,y#,z#+1500.0
  ` slowly rotate stars
  if timer()>ObjZTimer#
    zrotate object 12,ObjZ#
    ObjZ# = wrapvalue(ObjZ# + .03)
    ObjZTimer# = timer() + 10.0
  endif
  up = upkey() : down = downkey() : left = leftkey() : right = rightkey()
  if (up + down + left + right) <= 2
    if left = 1 and right = 0 and x#>1150.0 then x# = x# - 2.5
    if right = 1 and left = 0 and x#<1700.0 then x# = x#  +2.5
    if up = 1 and down = 0 and y# < 230.0 then y# = y# + 2.5
    if down = 1 and up = 0 and y# > 10.0 then y# = y# - 2.5
    position camera x#, y#, camera position z()
  endif
  move camera 2 : if returnkey()=1 then move camera 4
  if EShotStat = 0 and timer() > FireEShotDelay# then gosub FireEMissle
  if EShotStat = 1 then gosub MoveEMissile
  text 10,30,"FPS: "+str$(screen fps())
`  text 10,50,"z#="+str$(camera position z())
  if keystate(16) = 1 then exit : ` 'Q' key to quit
  if keystate(33) = 1 and timer() > FirePhotonDelay# then FirePhotons() : ` 33 = 'F' key to fire
  if PhotonStat(1) > 0 then MovePhotons()
  MoveEnemies()
  text 10,10,"lives: "+str$(lives(1))
  center text ms,10,"Score: "+str$(score(1))
  gosub CheckCollision
  if ExplodeEnemy = 1 then gosub BlowThemUp
  if lives(1) <= 0 then exit
  sync
  if z# > NextZMovePoint# then position camera camera position x(),camera position y(),0.0
loop
` game is over
EndTimer# = timer() + 2500.0
repeat
 x#=camera position x() : y#=camera position y() : z#=camera position z()
  ` position stars object
  position object 12,x#,y#,z#+1500.0
` slowly rotate stars
  if timer()>ObjZTimer#
    zrotate object 12,ObjZ#
    ObjZ# = wrapvalue(ObjZ# + .03)
    ObjZTimer# = timer() + 10.0
  endif
  ink rgb(128,255,0),0
  set text size 36
  center text ms,mt-50,"Game Over"
  ink rgb(255,255,255),0
  set text size 16
  center text ms,(mt*2)-50,"Thanks for playing!          LBFN"
  sync
until timer() > Endtimer#
end
 
` #####################################    Procedures    #######################################
 
MakeStuff:
` make object for stars and planets
make object plain 12,3000,3000
texture object 12,stars
ObjZ# = 1.0
ObjZTimer# = timer()+100.0
` make player's shots
make object box 24,2,1,8
scale object 24,100.0,100.0,300.0
texture object 24,FireBall
hide object 24
make object box 36,2,1,8
scale object 36,100.0,100.0,300.0
texture object 36,FireBall
hide object 36
` make enemy shot
make object cylinder 6,4
scale object 6,100.0,100.0,600.0
xrotate object 6,90.0
fix object pivot 6
texture object 6,12
hide object 6
` make object for collision purposes
make object sphere 100,25 : hide object 100
` make particles for exploding enemies
for part = 800 to 850
  make object plain part,3.0,3.0
  hide object part
next part
return
 
 
MoveEMissile:
move object 6,8
` check collision with player
x90# = object position x(6)
y90# = object position y(6)
z90# = object position z(6)
camx# = camera position x()
camy# = camera position y()
camz# = camera position z()
if abs(x90# - camx#) < 25.0 and abs(y90# - camy#) < 25.0 and abs(z90# - camz#) < 25.0
  ` got the player!
 ` text 100,100,"Player died!!":sync : wait key
  hide object 6
  FadeToBlack()
  set gamma 255,255,255
  EShotStat = 0
  lives(1) = lives(1) - 1
  FireEShotDelay# = timer() + 2000.0
  hide object 24 : hide object 36 :  PhotonStat(1) = 0
endif
` check to see if it went past the player
if object position z(6) < camera position z() and EShotStat > 0
 hide object 6
  EShotStat = 0
endif
return
 
 
FireEMissle:
` find a host enemy
for baddy = 1 to 40
  if enemy(baddy,3) = 1 and object in screen(baddy +499) = 1 and EShotStat = 0 and object position z(baddy + 499) > (camera position z() + 150.0)
    ` okay, we found our host
    ` set initial coordinates
    position object 6,object position x(baddy + 499), object position y(baddy + 499), object position z(baddy + 499)
    point object 6,camera position x(), camera position y(), camera position z() + 149.0
    EShotStat = 1 : ` enable movement and collision checking of the enemies' missile
    show object 6
`    text 100,100,"Missile away!":sync :wait 500
  endif
next baddy
return
 
 
BlowThemUp:
inc PartMoveCtr,1
if PartMoveCtr > 40
  PartMoveCtr = 0 : ExplodeEnemy = 0
endif
for part = 800 to 850
  if ExplodeEnemy > 0
    move object part,6
  else
    hide object part
  endif
next part
return
 
 
CheckCollision:
x100# = object position x(100)
y100# = object position y(100)
z100# = object position z(100)
for baddy = 1 to 40
  if enemy(baddy,3) = 1
    xb# = object position x(baddy + 499)
    yb# = object position y(baddy + 499)
    zb# = object position z(baddy + 499)
`    dist1# = Sqrt(((xb# - x100#)^2) + ((yb# + y100#)^2) + ((zb# - z100#)^2))
    if abs(zb# - z100#) < 25.0 and abs(xb# - x100#) < 25.0 and abs(yb# - y100#) < 25.0
      ` got 'em!!
      ` explode enemy
      select enemy(baddy,11)
        case 1
          ` grey
          r = 128 : g = 128 : b = 128
        endcase
        case 2
          ` red
          r = 164 : g = 36 : b = 36
        endcase
        case 3
          ` yellow
          r = 164 : g = 164 : b = 36
        endcase
        case 4
          ` blue
          r = 36 : g = 36 : b = 164
        endcase
      endselect
      for part = 800 to 850
        color object part,rgb(r,g,b)
        position object part, xb#,yb#,zb#
        rotate object part,rnd(359), rnd(359),rnd(359)
        show object part
      next part
      ExplodeEnemy = 1 : PartMoveCtr = 0
      ` place enemy elsewhere above the matrix, but not where the player can see it
      enemy(baddy,1) = rnd(450) + 1150.0 : `x coord
      enemy(baddy,2) = rnd(180)+30  : ` y coord
      okay = 0
      camz# = camera position z()
      repeat
        enemy(baddy,4) = rnd(7400)+2550 : ` z coord
        if enemy(baddy,4)<camz# or (enemy(baddy,4)-camz#)>1600.0 then okay = 1
      until okay = 1
      position object baddy + 499, enemy(baddy,1), enemy(baddy,2), enemy(baddy,4)
      score(1) = score(1) + 1000
      hide object 24 : hide object 36
      PhotonStat(1) = 0
      FirePhotonDelay# = timer() + 50.0
    endif
  endif
next baddy
return
 
`####################################    Functions    #########################################
 
 
function MoveEnemies()
for baddy = 1 to 40
  if enemy(baddy,3) = 1
    x# = object position x(baddy + 499)
    y# = object position y(baddy + 499)
    z# = object position z(baddy + 499)
    ChangePattern = 0
    select enemy(baddy,6) : ` get the direction of the enemy
      case 1
        ` up
         y# = y# + 1.0
         if y# > enemy(baddy,9) then ChangePattern =1
      endcase
      case 2
        ` down
        y# = y# - 1.0
        if y# < enemy(baddy,10) then ChangePattern =2
      endcase
      case 4
        ` right
        x# = x# + 1.0
        if x# > enemy(baddy,8) then ChangePattern =4
      endcase
      case 5
        ` up and right
        y# = y# + 1.0 : x# = x# + 1.0
        if y# > enemy(baddy,9) or x# > enemy(baddy,8) then ChangePattern = 5
      endcase
      case 6
        `  down and right
        y# = y# - 1.0 : x# = x# + 1.0
        if y# < enemy(baddy,10) or x# > enemy(baddy,8) then ChangePattern = 6
      endcase
      case 8
        `  left
        x# = x# - 1.0
        if x# < enemy(baddy,7) then ChangePattern = 8
      endcase
      case 9
        ` up and left
        y# = y# + 1.0 : x# = x# - 1.0
        if y# > enemy(baddy,9) or x# < enemy(baddy,7) then ChangePattern = 9
      endcase
      case 10
        ` down and left
         y# = y# - 1.0 : x# = x# - 1.0
         if y# < enemy(baddy,10) or x# < enemy(baddy,7) then ChangePattern = 10
      endcase
      position object baddy + 499, x#, y#, z#
    endselect
    ` change the direction of the enemy
    if ChangePattern > 0
      okay = 0
      repeat
        np = rnd(9) + 1
        if np <> 3 and np <> 7 and np <> ChangePattern then okay = 1
      until okay = 1
      enemy(baddy,6) = np
    endif
  endif
  ` see if it collides with the player
  xb# = object position x(baddy + 499) : yb# = object position y(baddy + 499) : zb# = object position z(baddy + 499)
  camx# = camera position x() : camy# = camera position y() : camz# = camera position z()
  if abs(xb# - camx#) < 25.0 and abs(yb# - camy#) < 25.0 and abs(zb# - camz#) < 25.0 and enemy(baddy,3) = 1
    ` enemy has coliided with the player
    hide object 6
    FadeToBlack()
    set gamma 255,255,255
    EShotStat = 0
    lives(1) = lives(1) - 1
    FireEShotDelay# = timer() + 2000.0
    hide object 24 : hide object 36 :  PhotonStat(1) = 0
    exitfunction
  endif
next baddy
endfunction
 
function MovePhotons()
  move object 24,8
  move object 36,8
  move object 100,8
  if abs(object position z(24)-target(3))<20.0
    hide object 24
    hide object 36
    PhotonStat(1) = 0
    FirePhotonDelay# = timer() + 50.0
  endif
endfunction
 
 
function FirePhotons()
  x# = camera position x()
  y# = camera position y()
  z# = camera position z()
  position object 24,x#-20.0,y#,z#
  point object 24,x#,y#-40.0,z#+900.0
  position object 36,x#+20.0,y#,z#
  point object 36,x#,y#-40.0,z#+900.0
  target(1) = x#
  target(2) = y# - 40.0
  target(3) = z# + 900.0
  show object 24
  show object 36
  position object 100,x#, y#, z#
  point object 100,x#,y#-40.0,z#+900.0
  PhotonStat(1) = 1 : ` photons are active
endfunction
 
 
function MakeImages(texture,stars,FireBall)
create bitmap 2,768,768
`Grey  - image 1
cls 0
ink rgb(192,192,192),0
box 0,0,255,255
` Medium Green - image 2
ink rgb(0,144,0),0
box 256,0,511,255
` browns for landscape - image 3
ink rgb(148,78,0),0
box 512+0,0,512+51,255
ink rgb(128,64,0),0
box 512+52,0,512+102,255
ink rgb(100,60,0),0
box 512+103,0,512+153,255
ink rgb(84,54,0),0
box 512+154,0,512+205,255
ink rgb(64,46,0),0
box 512+206,0,767,255
` forest green for platform  - image 4
ink rgb(0,144,64),0
box 0,256,255,511
` make green shades for tiles below
ink rgb(0,128,64),0
box 256,256,511,511 : ` image 5
ink rgb(0,112,64),0
box 512,256,767,511 : ` image 6
ink rgb(0,96,60),0
box 0,512,255,767 : ` image 7
ink rgb(0,84,50),0
box 256,512,511,767 : ` image 8
get image texture,0,0,768,768
delete bitmap 2
sw = screen width() : sh = screen height()
create bitmap 2,3000,3000
`Stars
for star = 1 to 412
  x = rnd(2500) + 10
  y = rnd(2500) + 10
  r = rnd(100) + 100 : g = rnd(100) + 100 : b = rnd(100) + 100
  ink rgb(r,g,b),0
  if rnd(1000) < 990
    box x,y,x+2,y+2
  else
    ` make planet
    dec r,70 : dec g,70 : dec b,70
    if r < 100 then r = 100
    if g < 100 then g = 100
    if b < 100 then b = 100
    ink rgb(r,g,b),0
    s = rnd(8)+4 : s = int(s / 2) * 2
    for PlanetSize = s to 1 step-1
      circle x,y,PlanetSize
      inc r,10 : inc g,10 : inc b,10
      ink rgb(r,g,b),0
    next PlanetSize
    dot x,y
  endif
next star
get image stars,0,0,3000,3000
cls 0
` Fire ball
ink rgb(255,128,64),0
box 0,0,sw-1,sh-1
ink rgb(193,63,0),0
for linez = 1 to 100
  sx = rnd(sw-20) : if sx < 0 then sx = 0
  sy = rnd(sh-20) : if sy < 0 then sy = 0
  diffX = sw - sx : diffY = sh - sy
  dx = rnd(diffX) + sx + 1 : dy = rnd(diffY) + sy + 1
  line sx, sy, dx, dy
next linez
get image FireBall,0,0,sw,sh
cls 0
` make image for enemy shots
ink rgb(0,128,255),0 : ` cerulean blue
box 0,0,255,255
get image 12,0,0,256,256
delete bitmap 2
set current bitmap 0
endfunction
 
function SetupMatrix(texture)
MayTricks = 1
make matrix MayTricks,2560,2560*6,40,40
randomize matrix MayTricks,200
prepare matrix texture MayTricks,texture,3,3
for t=0 to 39  : ` x width
  for i=0 to 39 : ` Z depth
    if t>=16 and t<=27
      ` 4, 7, 8, 9, or 10
      if i = 0 or i = 5 or i = 10 or i = 15 or i = 20 or i = 25 or i = 30 or i = 35
        set matrix tile MayTricks,t,i,4 : `dk green
      endif
      if i = 1 or i = 6 or i = 11 or i = 16 or i = 21 or i = 26 or i = 31 or i = 36
        set matrix tile MayTricks,t,i,5 : `green shade
      endif
      if i = 2 or i = 7 or i = 12 or i = 17 or i = 22 or i = 27 or i = 32 or i = 37
        set matrix tile MayTricks,t,i,6 : ` shade of green
      endif
      if i = 3 or i = 8 or i = 13 or i = 18 or i = 23 or i = 28 or i = 33 or i = 38
        set matrix tile MayTricks,t,i,7 : ` shade of green
      endif
      if i = 4 or i = 9 or i = 14 or i = 19 or i = 24 or i = 29 or i = 34 or i = 39
        set matrix tile MayTricks,t,i,8 : ` shade of green
      endif
      set matrix height MayTricks,t,i,-130.0
      set matrix height MayTricks,t,i+1,-130.0
      set matrix height MayTricks,t+1,i,-130.0
      set matrix height MayTricks,t+1,i+1,-130.0
    else
      set matrix tile MayTricks,t,i,3 : ` sands
    endif
    if i<= 3
      ` copy the first ten tiles to the end for smooth scrolling
       y# = get matrix height(MayTricks, t, i)
       set matrix height MayTricks,t,i+36,y#
       y# = get matrix height(MayTricks, t, i+1)
       set matrix height MayTricks,t,i+37,y#
       y# = get matrix height(MayTricks, t+1, i)
       set matrix height MayTricks,t+1,i+36,y#
       y# = get matrix height(MayTricks, t+1, i+1)
       set matrix height MayTricks,t+1,i+37,y#
    endif
  next i
next t
position matrix MayTricks,0.0,0.0,0.0
update matrix MayTricks
endfunction
 
function MakeEnemies()
for baddy = 1 to 40
  enemy(baddy,1) = rnd(450) + 1150.0 : `x coord
  enemy(baddy,2) = rnd(180)+30  : ` y coord
  enemy(baddy,3) = 1 : ` status   0=inactive 1=active 2=exploding  3=destroyed
  enemy(baddy,4) = rnd(7400)+2550 : ` z coord
  enemy(baddy,5) = rnd(2) + 1 : ` move pattern 1=up/down   2=left/right  3 = top/ left to bot/right
                                 ` 4 = top/right to bot/left
  ` get initial enemy direction
  okay = 0
  repeat
    np = rnd(9) + 1
    if np <> 3 and np <> 7 then okay = 1
  until okay = 1
  enemy(baddy,6) = np : ` direction
  enemy(baddy,7) = 1150.0 : `enemy(baddy,1) : ` min x coord
  enemy(baddy,8) = 1700.0 : `enemy(baddy,1) :   `max x coord
  enemy(baddy,9) = 230 : ` upper Y coord max
  enemy(baddy,10) = 10 : ` lower Y coord max
  make object sphere baddy + 499,10
  ` choose from four main colors for the enemies   grey, red, yellow or blue
  enemy(baddy,11) = rnd(3)+1
  select enemy(baddy,11)
    case 1
      ` grey
      r = 128 : g = 128 : b = 128
    endcase
    case 2
      ` red
      r = 164 : g = 36 : b = 36
    endcase
    case 3
      ` yellow
      r = 164 : g = 164 : b = 36
    endcase
    case 4
      ` blue
      r = 36 : g = 36 : b = 164
    endcase
  endselect
  color object baddy + 499,rgb(r + 14,g +14,b + 14)
  position object baddy + 499,enemy(baddy,1),enemy(baddy,2),enemy(baddy,4)
  make object box 599+baddy,6,2,4
  make mesh from object 199+baddy,599+baddy
  sizeX# = object size x(599 + baddy) + 1.5
  delete object 599+baddy
  add limb baddy + 499, 1, 199 + baddy
  offset limb baddy + 499, 1 , 0.0-sizeX#,0.0,0.0
  color limb baddy + 499, 1,rgb(r, g, b)
  add limb baddy + 499, 2, 199 + baddy
  offset limb baddy + 499, 2, object size x(baddy + 499)-2.5,0.0,0.0
  color limb baddy + 499, 2, rgb(r, g, b)
  make object box 599 + baddy,2,15,8
  make mesh from object 200 + baddy,599 + baddy
  sizeX2# = sizeX# + object size x(599 + baddy) + 2.0
  delete object 599 + baddy
  add limb baddy + 499, 3, 200 + baddy
  offset limb baddy + 499, 3 , 0.0 - sizeX2#,0.0,0.0
  color limb baddy + 499, 3,rgb(r - 36,g - 36,b - 36)
  add limb baddy + 499, 4, 200 + baddy
  offset limb baddy +499, 4,object size x(baddy + 499)+sizeX#-6.0,0.0,0.0
  color limb baddy + 499, 4, rgb(r - 36,g - 36,b - 36)
next baddy
endfunction
 
function FadeToBlack()
if object exist(200) = 1 then delete object 200
make object sphere 200,20
color object 200,rgb(255,128,64) : ` orange
ghost object on 200
position object 200,camera position x(),camera position y(),camera position z()+50.0
for blowup = 120 to 2000 step 50
  scale object 200,blowup, blowup, blowup
  sync
next blowup
delete object 200
for lambda = 150 to 0 step-2
  set gamma lambda, lambda, lambda
  sync
next lambda
cls 0
position camera camera position x(),camera position y(),0.0
sync
endfunction