10 REM BASIC Week 3: Under the Sea 20 REM http://reddit.com/r/RetroBattlestations 30 REM Written by FozzTexx 40 REM BBC Basic version by lolbar 100 MODE 4 110 VDU 4 120 VDU 12 130 VDU 23,1,0;0;0;0: REM CURSOR OFF 150 REM CLEAR SCREEN AND SETUP VARIABLES 160 CLS 170 DIM SEA$(2): 180 DIM ENEMYW(3),ENEMYX(3),ENEMYY(3),ENEMYXV(3),ENEMYYV(3),ENEMYC(3),ENEMYHIT(3),ENEMYERASE$(3),ENEMY$(3) 190 DIM BUBBLEX(3),BUBBLEY(3),BUBBLE$(3),FOOD$(3),FOODX(3),FOODY(3) 200 TURTLE=1:DEAD=3:OVER=11:NUMFOOD=0:NUMENEMIES=0 210 COLS = 38:ROWS = 30:REM COLUMNS AND ROWS OF SCREEN 220 GOSUB 2010:TURTLE$ = SP$:TURTLEWIDTH = SC:TURTLEHEIGHT = SR 230 TURTLEERASE$ = SE$:GOSUB 2010:TURTLEDEAD$ = SP$ 240 FOR EE = 1 TO 3:GOSUB 2010:ENEMY$(EE) = SP$ 250 ENEMYERASE$(EE) = SE$ 260 ENEMYW(EE) = SC:NEXT EE 270 GOSUB 2010:GAMEOVER$ = SP$:GOWIDTH = SC:GOHEIGHT = SR 280 AIRMAX = 10:SEA$ = "-_." 290 TURTLEY = 18:SURFACE = 4:GOSUB 4100:SCORE = -10:GOSUB 4510 300 REM PLAY GAME 310 X = 1:Y = SURFACE:GOSUB 1010 320 FOR I = 1 TO COLS:PRINT MID$(SEA$, RND(3), 1);:NEXT I 330 GOSUB 5140:GOSUB 6660:GOSUB 6140 340 LASTY = TURTLEY 350 FOR TURTLEX = 1 TO COLS 360 IF LASTY <> TURTLEY THEN GOSUB 3510 370 GOSUB 5010:GOSUB 6510:GOSUB 6010 380 SP$ = TURTLE$:X = TURTLEX:Y = TURTLEY:GOSUB 1510 390 LASTY = TURTLEY:GOSUB 2510 400 IF KE$ = "A" OR KE$ = "a" THEN D = -1:GOSUB 3010 410 IF KE$ = "Z" OR KE$ = "z" THEN D = 1: GOSUB 3010 420 IF KE$ = "Q" OR KE$ = "q" THEN END 430 IF TURTLEY = SURFACE + 1 THEN GOTO 450 440 IF TURTLEX = INT(COLS / 4) OR TURTLEX = INT(COLS / 4 * 3) THEN GOSUB 4010 450 IF TURTLEY = SURFACE + 1 AND AIR < AIRMAX THEN GOSUB 4100 460 NEXT TURTLEX 470 GOTO 310 1000 REM POSITION CURSOR AT X,Y 1010 VDU 31,X,Y 1020 RETURN 1500 REM DRAW SPRITE IN SP$ AT X,Y 1510 SE = 1:SB = 1 1520 IF X < 1 OR X > COLS OR Y < 1 OR Y > ROWS THEN RETURN 1530 SE = INSTR(SP$, CHR$(13),SB) 1540 IF SE = 0 THEN SE = LEN(SP$) + 1 1550 GOSUB 1010 1560 SL = SE - SB:IF SL + X - 1 > COLS THEN SL = COLS - X + 1 1570 PRINT MID$(SP$, SB, SL); 1580 IF SE >= LEN(SP$) THEN RETURN 1590 IF ASC(MID$(SP$, SE)) = 13 THEN SE = SE + 1 1600 SB = SE:Y = Y + 1:GOTO 1520 2000 REM LOAD A SPRITE FROM DATA INTO SP$ 2010 SP$ = "":SE$ = "":SR = 0:SC = 0 2020 READ T$,S$:IF LEN(SP$) > 0 THEN SP$ = SP$ + CHR$(13) 2030 SP$ = SP$ + S$:SR = SR + 1:IF LEN(S$) > SC THEN SC = LEN(S$) 2040 BL$ = "":FOR I = 1 TO LEN(S$):BL$ = BL$ + " ":NEXT I 2050 IF LEN(SE$) > 0 THEN SE$ = SE$ + CHR$(13) 2060 SE$ = SE$ + BL$ 2070 IF T$ <> "SE" THEN GOTO 2020 2080 RETURN 2500 REM READ THE KEYBOARD 2510 KE$ = INKEY$(1) 2520 RETURN 3000 REM PLAYER WANTS TO MOVE TURTLE UP OR DOWN 3010 TURTLEY = TURTLEY + D 3020 IF TURTLEY <= SURFACE THEN TURTLEY = SURFACE + 1 3030 IF TURTLEY > ROWS - TURTLEHEIGHT + 1 THEN TURTLEY = ROWS - TURTLEHEIGHT + 1 3040 RETURN 3500 REM TURTLE MOVED UP OR DOWN, ERASE FROM PREVIOUS LINE 3510 Y = LASTY:IF LASTY > TURTLEY THEN Y = Y + TURTLEHEIGHT - 1 3520 X = TURTLEX:SP$ = TURTLEERASE$:GOSUB 1510 3530 RETURN 4000 REM SHOW REMAINING AIR 4010 AIR = AIR - 1:IF AIR < 0 THEN AIR = 0 4020 IF AIR > AIRMAX THEN AIR = AIRMAX 4030 X = COLS - 7 - AIRMAX:Y = 2:GOSUB 1010 4040 PRINT "AIR: |"; 4050 FOR I = 1 TO AIR:PRINT "#";:NEXT I 4060 IF AIR < AIRMAX THEN FOR I = AIR + 1 TO AIRMAX:PRINT " ";:NEXT I 4070 PRINT "|"; 4080 IF AIR = 0 THEN GOTO 4110 4090 RETURN 4100 AIR = AIRMAX:GOTO 4030 4110 FOR I = TURTLEY TO SURFACE + 1 STEP -1 4120 X = TURTLEX:Y = I:SP$ = TURTLEDEAD$:GOSUB 1510 4130 Y = Y + 1:SP$ = TURTLEERASE$:GOSUB 1510 4140 NEXT I 4150 X = (COLS - GOWIDTH) / 2:Y = (ROWS - GOHEIGHT) / 2 4160 SP$ = GAMEOVER$:GOSUB 1510 4170 X = 1:Y = ROWS - 2:GOSUB 1010 4180 END 4500 REM DISPLAY SCORE 4510 SCORE = SCORE + 10:OX = X:OY = Y 4520 X = 2:Y = 2:GOSUB 1010:PRINT "SCORE: ";SCORE; 4540 X = OX:Y = OY:RETURN 5000 REM TAKE CARE OF BUBBLES 5010 FOR BB = 1 TO NUMBUBBLES 5020 IF INT(BUBBLEY(BB)) <= SURFACE THEN GOTO 5120 5030 NEWY = BUBBLEY(BB) - ((ROWS-SURFACE) / COLS) 5040 X = BUBBLEX(BB):Y = INT(BUBBLEY(BB)) 5050 GOSUB 5510:IF HIT = 0 THEN GOTO 5080 5060 AIR = AIR + 2:IF BUBBLE$(BB) = "o" THEN AIR = AIR + 1 5070 GOSUB 4010:NEWY = ROWS + COLS 5080 IF INT(NEWY) = Y THEN GOTO 5110 5090 SP$ = " ":X = BUBBLEX(BB):Y = INT(BUBBLEY(BB)):GOSUB 1510:SP$ = BUBBLE$(BB):Y = INT(NEWY) 5100 IF Y > SURFACE THEN GOSUB 1510 5110 BUBBLEY(BB) = NEWY 5120 NEXT BB 5130 RETURN 5140 NUMBUBBLES = RND(3):FOR BB = 1 TO NUMBUBBLES 5150 BUBBLEX(BB) = RND(COLS):BUBBLEY(BB) = ROWS - RND(3) - 1 5160 BUBBLE$(BB) = CHR$(79 + INT(RND(1)*2)*32) 5170 NEXT BB:RETURN 5500 REM HIT DETECTION 5510 HIT = 0 5520 IF X < TURTLEX + TURTLEWIDTH - 2 THEN RETURN 5530 IF X > TURTLEX + TURTLEWIDTH + 1 THEN RETURN 5540 IF Y < TURTLEY - 1 THEN RETURN 5550 IF Y > TURTLEY + 1 THEN RETURN 5560 HIT = 1:RETURN 6000 REM TAKE CARE OF ENEMIES 6010 FOR EE = 1 TO NUMENEMIES 6020 IF INT(ENEMYY(EE)) <= SURFACE THEN GOTO 6120 6030 NEWX = ENEMYX(EE) + ENEMYXV(EE):NEWY = ENEMYY(EE) + ENEMYYV(EE) 6040 X = INT(ENEMYX(EE)):Y = INT(ENEMYY(EE)) 6070 IF INT(NEWX) = X AND INT(NEWY) = Y THEN GOTO 6110 6080 SP$ = ENEMYERASE$(ENEMYC(EE)):GOSUB 1510 6085 IF ENEMYHIT(EE) = 1 THEN GOTO 6090 6086 GOSUB 5510:IF HIT = 1 THEN GOSUB 4010:ENEMYHIT(EE) = 1 6090 SP$ = ENEMY$(ENEMYC(EE)):X = INT(NEWX):Y = INT(NEWY) 6100 IF Y > SURFACE THEN GOSUB 1510 6110 ENEMYX(EE) = NEWX:ENEMYY(EE) = NEWY 6120 NEXT EE 6130 RETURN 6140 FOR EE = 1 TO NUMENEMIES:SP$ = ENEMYERASE$(ENEMYC(EE)) 6150 X = INT(ENEMYX(EE)):Y = INT(ENEMYY(EE)):GOSUB 1510:NEXT EE 6160 NUMENEMIES = RND(3):FOR EE = 1 TO NUMENEMIES 6170 ENEMYX(EE)=INT(RND(1)*COLS)+1:ENEMYY(EE)=ROWS-INT(RND(1)*(ROWS - SURFACE)) 6180 ENEMYXV(EE) = RND(1):ENEMYYV(EE) = RND(1) * ((ROWS - SURFACE) / COLS) 6190 ENEMYC(EE) = INT(RND(1) * 3) + 1:ENEMYHIT(EE) = 0 6200 IF ENEMYX(EE) > COLS / 2 THEN ENEMYXV(EE) = - ENEMYXV(EE) 6210 IF ENEMYY(EE) > ROWS / 2 THEN ENEMYYV(EE) = - ENEMYYV(EE) 6220 NEXT EE:RETURN 6500 REM TAKE CARE OF FOOD 6510 FOR FF = 1 TO NUMFOOD 6520 X = FOODX(FF):Y = INT(FOODY(FF)):GOSUB 5510 6530 IF HIT = 1 THEN GOSUB 4510:SP$ = " ":X = FOODX(FF):Y = FOODY(FF):GOSUB 1510:FOODY(FF) = ROWS + COLS 6640 NEXT FF 6650 RETURN 6660 SP$=" ":FOR FF=1 TO NUMFOOD:X = FOODX(FF):Y = FOODY(FF):GOSUB 1510:NEXT FF 6670 NUMFOOD = INT(RND(1) * 3) + 1:FOR FF = 1 TO NUMFOOD 6680 FOODX(FF)=INT(RND(1) * COLS) + 1:FOODY(FF)=ROWS - INT(RND(1) * (ROWS - SURFACE)) 6690 FOOD$(FF) = CHR$(120 + INT(RND(1) * 2)) 6700 X = FOODX(FF):Y = FOODY(FF):SP$ = FOOD$(FF):GOSUB 1510 6710 NEXT FF:RETURN 9000 DATA SP," _-%#%#}O" 9010 DATA SE," )" 9020 DATA SE," -OOOO}X" 9030 DATA SE,"^;;^" 9040 DATA SE,"<><" 9050 DATA SE,"$" 9060 DATA SP," _ _ __ _ __ _ " 9070 DATA SP,"/ \ / \ |\/| | / \ | | | | \" 9080 DATA SP,"| _ |_| | | |-- * | | \ / |-- |_/" 9090 DATA SE,"\_/ | | | | |__ \_/ V |__ | \"