! **************************************
! RFO Space Invaders
! May 2012-October 2013
! (C) Antonis (tony_gr)
! this program is free for personal use
! use it at your own risk
! **************************************
Input "Speed (1/2)", xspeed, 1
if xspeed<>1 then xspeed=2
DIM dead[24],col[4],row[5], invader1[24], invader2[24],cas[5]
DIM x[24],y[24]
startSpaceInvaders:
delay=500
level=1
hitted=0
points=0
finishedInv=0
lives=3
DEVICE dev$

GR.OPEN 255,0,0,0,0,1

PAUSE 1000
GR.SET.STROKE 4
GR.TEXT.SIZE 35
GR.SCREEN w,h
sx=w/800
sy=h/1232
GR.SCALE sx,sy
GR.BITMAP.LOAD s0, "spacebg.jpg"
GR.BITMAP.LOAD b0, "spacerover.png"
GR.BITMAP.LOAD c0, "spacerover2.png"
GR.BITMAP.LOAD t1, "castle.png"
GR.BITMAP.LOAD u0, "ufopoints.png"
GR.BITMAP.LOAD l1, "ufo.png"
GR.BITMAP.LOAD b1, "robo1a.png"
GR.BITMAP.LOAD b2, "robo1b.png"
GR.BITMAP.LOAD r1, "robo2a.png"
GR.BITMAP.LOAD r2 ,"robo2b.png"
GR.BITMAP.LOAD r3, "robo3a.png"
GR.BITMAP.LOAD r4, "robo3b.png"
GR.BITMAP.LOAD bom, "bomb.png"
AUDIO.LOAD au1,"appear.mp3" % ufo appearance OK
AUDIO.LOAD au2,"inv.ogg" % invaders movement OK
AUDIO.LOAD au3,"invufo.mp3" % ufo hitted
AUDIO.LOAD au4,"shipdestroyed.mp3" % ship hitted -

SOUNDPOOL.OPEN 4
SOUNDPOOL.LOAD soushot, "bomb.mp3" % ship shot OK
SOUNDPOOL.LOAD soushooted, "invhitted.mp3" % invader killed - remove
SOUNDPOOL.LOAD invshot, "invshot.mp3" % invader shot
GR.BITMAP.DRAW space,s0,0,0

restartSpaceInvaders:
GR.CLS
game=1
if xspeed=2 then delay=450 else delay=500
level=1
hitted=0
points=0
finishedInv=0
lives=3
finished=0
stars=0

NexLevel:
GR.TEXT.ALIGN 1
GR.TEXT.SIZE 33
GR.TEXT.BOLD 1
GR.TEXT.TYPEFACE 3
IF level=1 | level=2 THEN delay=delay-150 ELSE delay=delay-50
FOR i=1 TO 20
 dead[i]=0
NEXT i
hitted=0
FOR i=1 TO 4
 col[i]=0
 row[i]=0
NEXT i
row[5]=0

GR.BITMAP.DRAW space,s0,0,40
GR.COLOR 255,255,0,0,1
gr.text.draw tony,0,1231,"      >> Space Invaders v1.01 for RFO Basic! by Tony <<"
GR.CIRCLE cir,5,5,6
GR.BITMAP.DRAW ship,b0,0,1000 % here
GR.BITMAP.DRAW destr,c0,0,0
GR.BITMAP.DRAW ufo,l1,-60,50
GR.BITMAP.DRAW ufopoints,u0,0,0
GR.COLOR 255,0,255,255,0
GR.HIDE ufopoints
GR.HIDE ufo
GR.HIDE cir
GR.HIDE destr
FOR i=1 TO 4
 GR.BITMAP.DRAW cas[i],t1,50+(i-1)*205,890
NEXT i
j=0
k=1
FOR i=1 TO 20
 dead[i]=0
 j=j+1
 IF j=5 THEN
  j=1
  k=k+1
 ENDIF
 x[i]=50+(j-1)*150
 y[i]=100+(k-1)*100
 IF i<9 THEN
  GR.BITMAP.DRAW invader1[i],b1,x[i],y[i]
  GR.BITMAP.DRAW invader2[i],b2,-100,-100
 ELSEIF i>8 & i<17 THEN
  GR.BITMAP.DRAW invader1[i],r1,x[i],y[i]
  GR.BITMAP.DRAW invader2[i],r2,-100,-100
 ELSE
  GR.BITMAP.DRAW invader1[i],r3,x[i],y[i]
  GR.BITMAP.DRAW invader2[i],r4,-100,-100
 ENDIF
NEXT i
GR.COLOR 255,255,255,0,1
GR.TEXT.DRAW lv,290,30,"Level: 1"
GR.COLOR 255,15,155,255,1
GR.TEXT.DRAW lf,430,30,"Lives: 3"
GR.COLOR 255,255,0,0,1
GR.TEXT.DRAW jo,0,30,"Space Invaders"
GR.COLOR 255,255,0,255,1
GR.TEXT.DRAW point,580,30,"Points: "+REPLACE$(STR$(points),".0","")
GR.BITMAP.DRAW bomb, bom, 25, 970

GR.RENDER

rot=1
c=CLOCK()
cc=c
ccc=c
cl=CLOCK()
clflag=0
xship=0
ybomb=970
maxright=700
spaceleft=50
flag=0
extraspeed=0
ufo_x=-60
ufoflag=0
shotflag=0 %
sclk=CLOCK() %
ufopointsflag=0

AUDIO.STOP
AUDIO.PLAY au2
SOUNDPOOL.PLAY shootedid2, soushot , 0.9, 0.9, 1, 0, 1

! ****************
startLoopInvaders:

IF ufoflag=0 THEN
 AUDIO.ISDONE k
 IF k>0 THEN
  AUDIO.STOP
  AUDIO.PLAY au2
 ENDIF
ENDIF

GOSUB moveShip
GOSUB moveBullet
! GR.RENDER
! check collisions
GOSUB invaders_hitted
IF ufoflag=1 THEN GOSUB ufohit
GOSUB castlehit


! invaders will shoot
! if clock()-sclk>=5000 then
IF shotflag=1 THEN GOTO nnext1

FOR i=20 TO 1 STEP -1
 IF dead[i]=0 THEN
  found=i
  F_N.BREAK
 ENDIF
NEXT i
IF y[i]<=700 THEN
 SOUNDPOOL.PLAY shootedid3, invshot , 0.9, 0.9, 1, 0, 1
 xshot=x[i]+25
 yshot=y[i]+50
 GR.SHOW cir
 GR.MODIFY cir,"x",xshot
 GR.MODIFY cir,"y",yshot
 shotflag=1
ENDIF
! sclk=clock() ? to test

nnext1:

IF shotflag=0 THEN GOTO nnext2

IF yshot<1050 THEN % here
 yshot=yshot+8
 if xspeed=2 then yshot=yshot+2
 GR.MODIFY cir,"y",yshot
ELSE
 GR.HIDE cir
 shotflag=0
ENDIF
GOSUB shiphitted
GOSUB castlehitted

nnext2:

! ufo & sound
IF CLOCK()-cl<10000  THEN GOTO nnext3

IF ufoflag=0 THEN
 GR.SHOW ufo
 AUDIO.STOP
 AUDIO.PLAY au1
ENDIF
ufoflag=1
ufo_x=ufo_x+8
IF xspeed=2 THEN ufo_x=ufo_x+2
GR.MODIFY ufo, "x",ufo_x
AUDIO.ISDONE k
IF k>0 THEN
 AUDIO.STOP
 AUDIO.PLAY au1
ENDIF
IF ufo_x>=800 THEN
 AUDIO.STOP
 ufo_x=-60
 GR.MODIFY ufo, "x",ufo_x
 GR.HIDE ufo
 cl=CLOCK()
 ufoflag=0
ENDIF
nnext3:
GOSUB moveBullet
! move bullet

GOSUB moveShip
GR.RENDER
! move invaders
IF CLOCK()-c<delay THEN GOTO nnext4

IF ufopointsflag=1 & CLOCK()-ufopointsclk>=1000 THEN
 ufopointsclk=CLOCK()
 ufo_x=-60
 GR.MODIFY ufo, "x",ufo_x
 GR.HIDE ufo
 GR.HIDE ufopoints
 GR.HIDE tx
 ufopointsflag=0
ENDIF
c=CLOCK()
rot=!rot
k=0
IF x[4]>=maxright THEN
 FOR j=1 TO 20
  k=k+1
  IF k=5 THEN k=1
  x[j]=spaceleft+(k-1)*150
  y[j]=y[j]+100
  IF y[j]>988 THEN y[j]=985 % -->here
 NEXT j
ELSE
 FOR i=1 TO 20
  x[i]=x[i]+10+extraspeed
 NEXT i
ENDIF

FOR i=1 TO 20
 IF dead[i]<>1
  IF rot=1   THEN
   GR.SHOW invader1[i]
   GR.MODIFY invader1[i],"x",x[i]
   GR.MODIFY invader1[i],"y",y[i]
   GR.HIDE invader2[i]
  ELSE
   GR.SHOW invader2[i]
   GR.MODIFY invader2[i],"x",x[i]
   GR.MODIFY invader2[i],"y",y[i]
   GR.HIDE invader1[i]
  ENDIF
 ENDIF
NEXT i
GOSUB checkdown
nnext4:
GOTO startLoopInvaders

! *******************************
! * SUBROUTINES Space Invaders *
!********************************
moveBullet:
IF ybomb>50 THEN
 if xspeed=2 then ybomb=ybomb-30 else ybomb=ybomb-17
 IF ybomb<=70 THEN
  ! z1=CLOCK()-z  % speed test
  ! PRINT z1
 ENDIF
 GR.MODIFY bomb,"y",ybomb
ELSE
 ! z=CLOCK()
 ybomb=970
 xbomb=xship+2
 GR.MODIFY bomb,"x",xbomb
 GR.MODIFY bomb,"y",ybomb
 SOUNDPOOL.PLAY shootedid2, soushot , 0.9, 0.9, 1, 0, 1
ENDIF
RETURN
moveShip:
! move starship
GR.TOUCH touched,x,y 
IF touched<=0 THEN GOTO nnext0
 IF x>400*sx & xship<750 THEN
  if xspeed=2 then xship=xship+18 else xship=xship+10
  GR.MODIFY ship,"x",xship
 ENDIF
 IF x<400*sx & xship>5 THEN
  if xspeed=2 then xship=xship-18 else xship=xship-10
  GR.MODIFY ship,"x",xship
 ENDIF
nnext0:
RETURN

! collision castle, invaders shot
castlehitted:
FOR i=1 TO 4
 a1=GR_COLLISION(cir,cas[i])
 IF a1=1 THEN
  GR.HIDE cir
  shotflag=0
  GR.RENDER
  F_N.BREAK
 ENDIF
NEXT i
RETURN

! collision invaders shot, ship
shiphitted:
a1=GR_COLLISION(cir,ship)
IF a1=0 THEN GOTO nnext5
IF yshot>=1000 THEN
 AUDIO.STOP
 AUDIO.PLAY au4
 points=points-150
 lives=lives-1
 GR.MODIFY point,"text", "Points: "+REPLACE$(STR$(points),".0","")
 GR.MODIFY lf,"text", "Lives: "+REPLACE$(STR$(lives),".0","")
 GR.HIDE ship
 GR.MODIFY destr, "x",xship
 GR.MODIFY destr, "y",1000
 GR.SHOW destr
 GR.HIDE cir
 shotflag=0
 GR.RENDER
 PAUSE 2000
 AUDIO.STOP
 GR.SHOW ship
 GR.HIDE destr
 IF lives=0 THEN finished=1
 IF finished=1 THEN
  GOSUB gameend
  IF points>=2000 THEN stars=1
  GOSUB savePoints
  IF selcted_action=1 THEN GOTO start
  IF selcted_action=2 THEN GOTO restartSpaceInvaders
 ENDIF
ENDIF
nnext5:
RETURN

! collision ship bomb witn castles
castlehit:
FOR i=1 TO 4
 a1=GR_COLLISION(cas[i],bomb)
 IF a1=1 THEN F_N.BREAK
NEXT i
IF a1=0 THEN GOTO nnext6
GR.RENDER
IF ((xbomb>68 & xbomb<112) | (xbomb>273 & xbomb<317) | (xbomb>478 & xbomb<522) | (xbomb>683 & xbomb<727)) & (ybomb>920) THEN GOTO ncollision

IF ( xbomb<42 | (xbomb<134 & xbomb>125) | (xbomb<334 & xbomb>326) | (xbomb<454 & xbomb>446) | (xbomb<254 & xbomb>245) | (xbomb<662 & xbomb>650) | (xbomb<542 & xbomb>532) ) & ybomb>=800 THEN GOTO ncollision

SOUNDPOOL.PLAY shootedid2, soushot , 0.9, 0.9, 1, 0, 1
ybomb=970
xbomb=xship+20
GR.MODIFY bomb,"x",xbomb
GR.MODIFY bomb,"y",ybomb
ncollision:
nnext6:
RETURN

! collision invaders - ship bomb
invaders_hitted:
! inv=clock()
FOR i=20 TO 1 STEP -1
 if dead[i]<>0 then goto nnext
  IF rot=1 THEN a=GR_COLLISION(invader1[i],bomb) ELSE a= GR_COLLISION( invader2[i],bomb)
  IF a<>1 THEN GOTO nnext
  SOUNDPOOL.PLAY shootedid, soushooted , 0.9, 0.9, 1, 0, 1
  points=points+20
  GR.MODIFY point,"text", "Points: "+REPLACE$(STR$(points),".0","")
  hitted=hitted+1
  GR.HIDE invader1[i]
  GR.HIDE invader2[i]
  dead[i]=1
  SOUNDPOOL.PLAY shootedid2, soushot , 0.9, 0.9, 1, 0, 1
  ybomb=970
  xbomb=xship+20
  GOSUB checklimits
  GR.MODIFY bomb,"x",xbomb
  GR.MODIFY bomb,"y",ybomb
  GR.RENDER
  IF hitted=20 THEN
   AUDIO.STOP
   IF level=3 THEN finished=1
   IF finished=1 THEN
    GOSUB gameend
    stars=2
    GOSUB savePoints
    IF selcted_action=1 THEN GOTO start
    IF selcted_action=2 THEN GOTO restartSpaceInvaders
   ENDIF
   level=level+1
   GR.TEXT.SIZE 90
   GR.TEXT.BOLD 1
   GR.TEXT.ALIGN 2
   GR.COLOR 255,0,255,255,1
   GR.TEXT.DRAW tx,400,615,"GET READY"
   GR.TEXT.DRAW tx,400,715,"FOR NEXT LEVEL"
   points=points+200
   GR.MODIFY point,"text", "Points: "+REPLACE$(STR$(points),".0","")
   GR.MODIFY lv,"text", "Lives: "+REPLACE$(STR$(lives),".0","")
   GR.RENDER
   PAUSE 4000
   GR.CLS
   GOTO nexlevel
  ENDIF
  F_N.BREAK
 nnext:
NEXT i

IF hitted=17 THEN extraspeed=15
! print clock()-inv
RETURN

! collision ufo-ship bomb
ufohit:
a1=GR_COLLISION(ufo,bomb)
IF a1=0 THEN GOTO nnext7
IF ybomb<70 THEN GOTO nnext7

 AUDIO.STOP
 AUDIO.PLAY au3
 x=CEIL(RND()*4)
 IF x=1 THEN extrapoints$="50"
 IF x=2 THEN extrapoints$="100"
 IF x=3 THEN extrapoints$="150"
 IF x=4 THEN extrapoints$="300"
 extrapoints=VAL(extrapoints$)
 points=points+extrapoints
 GR.MODIFY point,"text", "Points: "+REPLACE$(STR$(points),".0","")
 GR.SHOW ufopoints
 GR.TEXT.SIZE 30
 GR.COLOR 255,255,255,255,1
 GR.TEXT.DRAW tx, ufo_x+10, ufo_y+145,extrapoints$
 GR.MODIFY ufopoints,"x",ufo_x+7
 GR.MODIFY ufopoints,"y",ufo_y+100
 ufopointsflag=1
 ufopointsclk=CLOCK()
 GR.RENDER
 cl=CLOCK()
 ufoflag=0
 SOUNDPOOL.PLAY shootedid2, soushot , 0.9, 0.9, 1, 0, 1
 ybomb=970
 xbomb=xship+25
 GR.MODIFY bomb,"x",xbomb
 GR.MODIFY bomb,"y",ybomb
nnext7:
RETURN

! check left - right limits of invaders
checklimits:
FOR i=1 TO 4
 IF dead[i+0]=1 & dead[i+4]=1 & dead[i+8]=1 & dead[i+12]=1 & dead[i+16]=1 THEN col[i]=1
NEXT i
IF col[4]=1 THEN maxright=850
IF col[4]=1 & col[3]=1 THEN maxright=1000
IF col[4]=1 & col[3]=1 & col[2]=1 THEN maxright=1150

IF col[1]=1 THEN spaceleft=-100
IF col[1]=1 & col[2]=1 THEN spaceleft=-250
IF col[1]=1 & col[2]=1 & col[3]=1 THEN spaceleft=-400
RETURN

! check lower limit of invaders
checkdown:
FOR i=1 TO 5
 IF dead[4*(i-1)+1]=1 & dead[4*(i-1)+2]=1 & dead[4*(i-1)+3]=1 & dead[4*(i-1)+4]=1  THEN row[i]=1
NEXT i
IF row[5]=0 & y[20]>=950 THEN finished=1
IF row[5]=1 & row[4]=0 & y[16]>= 950 THEN finished=1
IF row[5]=1 & row[4]=1 & row[3]=0 & y[12]>= 950 THEN finished=1
IF row[5]=1 & row[4]=1 & row[3]=1 & row[2]=0 & y[8]>= 950 THEN finished=1
IF row[5]=1 & row[4]=1 & row[3]=1 & row[2]=1 & y[4]>= 950 THEN finished=1
IF finished=1 THEN
 GR.MODIFY ship,"bitmap",c0
 GR.RENDER
 GOSUB gameend
 IF points>=2000 THEN stars=1
 GOSUB savePoints
 IF selcted_action=1 THEN GOTO start
 IF selcted_action=2 THEN GOTO restartSpaceInvaders
ENDIF
RETURN
! End of SpaceInvaders

GameEnd:
GR.RENDER
GR.TEXT.SIZE 100
GR.TEXT.BOLD 1
GR.TEXT.ALIGN 2
GR.COLOR 255,0,255,255,1
GR.TEXT.DRAW tx1,400,615,"Game Over!"
IF hiscore<points THEN hiscore=points
GR.TEXT.DRAW tx2,400,715,"Hi Score:"+ REPLACE$(STR$(ROUND(hiscore)),".0","")
GR.RENDER
GR.TEXT.ALIGN 1
GR.RENDER
DO
 GR.TOUCH touched,x,y
UNTIL touched
DO
 GR.TOUCH touched,x,y
UNTIL !touched
GR.CLS
rerun=1
GOTO restartSpaceInvaders

! *********************
! End of SpaceInvaders
! *********************


