rem variables
global time as integer
global stars as integer
global gamelevel as integer : gamelevel=1
global numberofstars as integer : numberofstars=200
global maximumobjects as integer : maximumobjects=1000
global xmid : xmid=int(1024/2)
global ymid : ymid=int(768/2)
global shiprotatespeed as float : shiprotatespeed=0.4
global shipbulletlife as integer : shipbulletlife=1500
global shipsleft as integer : shipsleft=2
global shipfirerate as integer
global shipacceleration as float
global shipmaximumspeed as float
global shipfiretime as integer
global shipscore as integer : shipscore=0
 
 
 
rem setup
sync on
sync rate 50
set display mode 1024,768,32
hide mouse
set text font "microsoft sans serif"
null=make vector2(1)
null=make vector2(2)
sync
 
 
 
rem make the stars
ink rgb(255,255,200),rgb(0,0,0)
for x=1 to numberofstars
   dot rnd(1024),rnd(768)
next x
stars=1 : get image stars,0,0,1024,768
ink rgb(255,255,255),rgb(0,0,0)
 
 
 
rem types and arrays
type pointtype
   x as float
   y as float
   tx as float
   ty as float
endtype
type objecttype
   points as integer
   size as float
   xpos as float
   ypos as float
   rotation as float
   xvel as float
   yvel as float
   spin as float
endtype
type bullettype
   id as integer
   time as integer
endtype
type asteroidtype
   id as integer
   size as integer
endtype
global dim object(maximumobjects) as objecttype
global dim objectpoint(maximumobjects,20) as pointtype
global dim asteroid() as asteroidtype
global dim bullet() as bullettype
 
 
 
rem make the ship
array insert at bottom object(0)
object(0).points=5
object(0).size=10
object(0).xpos=xmid
object(0).ypos=ymid
object(0).rotation=0
object(0).xvel=0
object(0).yvel=0
object(0).spin=0
objectpoint(0,0).x=0
objectpoint(0,0).y=-10
objectpoint(0,1).x=-6
objectpoint(0,1).y=6
objectpoint(0,2).x=0
objectpoint(0,2).y=3
objectpoint(0,3).x=6
objectpoint(0,3).y=6
objectpoint(0,4).x=0
objectpoint(0,4).y=-10
 
 
 
`===========================================================================================
 
 
 
rem load the first level and start the loop
_load_level()
do
   rem get time and paste stars
   time=timer()
   paste image stars,0,0
 
   rem main routines
   _control_ship()
   _check_bullets()
   _update_objects()
 
   rem print stats and sync
   set cursor 0,5
   text 10,10,"Level_"+str$(gamelevel)
   text 10,30,"Ships left: "+str$(shipsleft)
   text 10,50,"Score: "+str$(shipscore)
   sync
loop
 
 
 
`==========================================================================================
 
 
 
rem sets up a level
function _load_level()
   object(0).xpos=xmid
   object(0).ypos=ymid
   object(0).rotation=0
   object(0).spin=0
   object(0).xvel=0
   object(0).yvel=0
   inc shipsleft
   shipfirerate=1000-shipscore*4
   shipmaximumspeed=1.5+shipscore*0.005
   shipacceleration=0.1+shipscore*0.0009
   for x=1 to 5
      xpos=rnd(1024) : ypos=rnd(768)
      if xpos>400 and xpos<600 then xpos=600
      if ypos>300 and ypos<500 then ypos=300
      makeasteroid(3,xpos,ypos)
   next x
   paste image stars,0,0
   set text size 40
   center text xmid,ymid-50,"Level_"+str$(gamelevel) : sync
   set text size 20
   wait 3000
endfunction
 
 
 
rem controls the ship
function _control_ship()
   rem rotate the ship
   object(0).spin=mousemovex()*shiprotatespeed
   if leftkey() or keystate(30) then dec object(0).spin,shiprotatespeed*10
   if rightkey() or keystate(32) then inc object(0).spin,shiprotatespeed*10
   rem move the ship
   if keystate(17) or upkey() or mouseclick()=2 or mouseclick()=3
      inc object(0).xvel,sin(object(0).rotation)*shipacceleration
      inc object(0).yvel,cos(object(0).rotation)*shipacceleration
      set vector2 1,object(0).xvel,object(0).yvel
      if length vector2(1)>shipmaximumspeed
         normalize vector2 1,1
         object(0).xvel=x vector2(1)*shipmaximumspeed
         object(0).yvel=y vector2(1)*shipmaximumspeed
      endif
   endif
   rem fire bullets
   if shipfiretime+shipfirerate<time
      if spacekey() or mouseclick()=1 or mouseclick()=3
         shipfiretime=time
         makebullet(object(0).xpos,object(0).ypos,object(0).rotation)
         dec shipscore
         if shipscore<0 then shipscore=0
      endif
   endif
   rem check for asteroid collision
   for x=0 to array count(asteroid(0))
      set vector2 1,object(0).xpos-object(asteroid(x).id).xpos,object(0).ypos-object(asteroid(x).id).ypos
      if length vector2(1)<object(0).size+object(asteroid(x).id).size
         destroyasteroid(x)
         center text xmid,ymid-80,"You were hit!" : sync
         dec shipsleft
         if shipsleft<0
            set text size 40
            center text xmid,ymid-40,"You Lose!"
            center text xmid,ymid,"Your Score: "+str$(shipscore)
            sync
            wait 5000 : end
         endif
         object(0).xpos=xmid
         object(0).ypos=ymid
         object(0).rotation=0
         object(0).spin=0
         object(0).xvel=0
         object(0).yvel=0
         wait 1500
      endif
   next x
   rem check for next level
   if array count(asteroid(0))=-1
      inc gamelevel
      _load_level()
   endif
endfunction
 
 
 
rem draws and updates all objects
function _update_objects()
   for x=0 to maximumobjects
      rem rotation
      dec object(x).rotation,object(x).spin
      for y=0 to object(x).points-1
         objectpoint(x,y).tx=cos(object(x).rotation)*objectpoint(x,y).x+sin(object(x).rotation)*objectpoint(x,y).y
         objectpoint(x,y).ty=cos(object(x).rotation)*objectpoint(x,y).y-sin(object(x).rotation)*objectpoint(x,y).x
      next y
      rem movement
      dec object(x).xpos,object(x).xvel
      dec object(x).ypos,object(x).yvel
      if object(x).xpos<0 then object(x).xpos=1024
      if object(x).ypos<0 then object(x).ypos=768
      if object(x).xpos>1024 then object(x).xpos=0
      if object(x).ypos>768 then object(x).ypos=0
      rem drawing
      for y=0 to object(x).points-2
         line objectpoint(x,y).tx+object(x).xpos,objectpoint(x,y).ty+object(x).ypos,objectpoint(x,y+1).tx+object(x).xpos,objectpoint(x,y+1).ty+object(x).ypos
      next y
   next x
endfunction
 
 
 
rem expolodes asteroids and gets rid of bullets
function _check_bullets()
   while x<=array count(bullet(0))
      bulletobject=bullet(x).id
      collision=0
      for y=0 to array count(asteroid(0))
         asteroidobject=asteroid(y).id
         set vector2 1,object(asteroidobject).xpos-object(bulletobject).xpos,object(asteroidobject).ypos-object(bulletobject).ypos
         if length vector2(1)<object(asteroidobject).size+object(bulletobject).size
            select asteroid(y).size
               case 3
                  for z=1 to (gamelevel+3)*0.5
                     makeasteroid(2,object(asteroidobject).xpos,object(asteroidobject).ypos)
                  next z
                  inc shipscore,1
               endcase
               case 2
                  for z=1 to (gamelevel+3)*0.5
                     makeasteroid(1,object(asteroidobject).xpos,object(asteroidobject).ypos)
                  next z
                  inc shipscore,2
               endcase
               case 1
                  inc shipscore,3
               endcase
            endselect
            destroyasteroid(y)
            collision=1 : exit
         endif
      next y
      if collision or bullet(x).time+shipbulletlife<time
         destroybullet(x)
      else
         inc x
      endif
   endwhile
endfunction
 
 
 
`=========================================================================================
 
 
 
rem makes a new asteroid
function makeasteroid(size,x#,y#)
   num=newobject()
   array insert at bottom asteroid(0)
   asteroid(array count(asteroid(0))).id=num
 
   direction#=rnd(359)
   speed#=rnd(9*gamelevel)*0.09+0.09*gamelevel
   if rnd(1)
      spin#=rnd(10*gamelevel)*0.1+0.1*gamelevel
   else
      spin#=-1*rnd(10*gamelevel)*0.1+0.1*gamelevel
   endif
 
   select size
      case 1
         asteroid(array count(asteroid(0))).size=1
         object(num).points=6
         object(num).size=10
         object(num).xpos=x#
         object(num).ypos=y#
         object(num).rotation=0
         object(num).xvel=sin(direction#)*speed#
         object(num).yvel=cos(direction#)*speed#
         object(num).spin=spin#
         objectpoint(num,0).x=0
         objectpoint(num,0).y=-10
         objectpoint(num,1).x=-10+(rnd(6)-3)
         objectpoint(num,1).y=-3+(rnd(6)-3)
         objectpoint(num,2).x=-5+(rnd(6)-3)
         objectpoint(num,2).y=10+(rnd(6)-3)
         objectpoint(num,3).x=5+(rnd(6)-3)
         objectpoint(num,3).y=10+(rnd(6)-3)
         objectpoint(num,4).x=10+(rnd(6)-3)
         objectpoint(num,4).y=-3+(rnd(6)-3)
         objectpoint(num,5).x=0
         objectpoint(num,5).y=-10
      endcase
      case 2
         asteroid(array count(asteroid(0))).size=2
         object(num).points=7
         object(num).size=20
         object(num).xpos=x#
         object(num).ypos=y#
         object(num).rotation=0
         object(num).xvel=sin(direction#)*speed#
         object(num).yvel=cos(direction#)*speed#
         object(num).spin=spin#
         objectpoint(num,0).x=0
         objectpoint(num,0).y=-20
         objectpoint(num,1).x=-20+(rnd(10)-5)
         objectpoint(num,1).y=-10+(rnd(10)-5)
         objectpoint(num,2).x=-20+(rnd(10)-5)
         objectpoint(num,2).y=10+(rnd(10)-5)
         objectpoint(num,3).x=0+(rnd(10)-5)
         objectpoint(num,3).y=20+(rnd(10)-5)
         objectpoint(num,4).x=20+(rnd(10)-5)
         objectpoint(num,4).y=10+(rnd(10)-5)
         objectpoint(num,5).x=20+(rnd(10)-5)
         objectpoint(num,5).y=-10+(rnd(10)-5)
         objectpoint(num,6).x=0
         objectpoint(num,6).y=-20
      endcase
      case 3
         asteroid(array count(asteroid(0))).size=3
         object(num).points=9
         object(num).size=30
         object(num).xpos=x#
         object(num).ypos=y#
         object(num).rotation=0
         object(num).xvel=sin(direction#)*speed#
         object(num).yvel=cos(direction#)*speed#
         object(num).spin=spin#
         objectpoint(num,0).x=0
         objectpoint(num,0).y=-30
         objectpoint(num,1).x=-18+(rnd(12)-6)
         objectpoint(num,1).y=-18+(rnd(12)-6)
         objectpoint(num,2).x=-30+(rnd(12)-6)
         objectpoint(num,2).y=0+(rnd(12)-6)
         objectpoint(num,3).x=-18+(rnd(12)-6)
         objectpoint(num,3).y=18+(rnd(12)-6)
         objectpoint(num,4).x=0+(rnd(12)-6)
         objectpoint(num,4).y=30+(rnd(12)-6)
         objectpoint(num,5).x=18+(rnd(12)-6)
         objectpoint(num,5).y=18+(rnd(12)-6)
         objectpoint(num,6).x=30+(rnd(12)-6)
         objectpoint(num,6).y=0+(rnd(12)-6)
         objectpoint(num,7).x=18+(rnd(12)-6)
         objectpoint(num,7).y=-18+(rnd(12)-6)
         objectpoint(num,8).x=0
         objectpoint(num,8).y=-30
      endcase
   endselect
endfunction
 
 
 
rem gets rid of asteroids
function destroyasteroid(num)
   object(asteroid(num).id).points=0
   array delete element asteroid(0),num
endfunction
 
 
 
rem makes bullets
function makebullet(x#,y#,direction#)
   num=newobject()
   array insert at bottom bullet(0)
   bullet(array count(bullet(0))).id=num
   bullet(array count(bullet(0))).time=time
   object(num).points=5
   object(num).size=2
   object(num).xpos=x#
   object(num).ypos=y#
   object(num).rotation=direction#
   object(num).xvel=sin(direction#)*10.0
   object(num).yvel=cos(direction#)*10.0
   object(num).spin=0
   objectpoint(num,0).x=0
   objectpoint(num,0).y=-2
   objectpoint(num,1).x=-1
   objectpoint(num,1).y=0
   objectpoint(num,2).x=0
   objectpoint(num,2).y=2
   objectpoint(num,3).x=1
   objectpoint(num,3).y=0
   objectpoint(num,4).x=0
   objectpoint(num,4).y=-2
endfunction
 
 
 
rem gets rid of bullets
function destroybullet(num)
   object(bullet(num).id).points=0
   array delete element bullet(0),num
endfunction
 
 
 
rem returns a free object slot
function newobject()
   while object(test).points<>0
      inc test
   endwhile
endfunction test