10 REM ------------------------------------------ 20 REM Pixel Fandango Space Fighter X 30 REM ------------------------------------------ 40 DIM images% 280 50 workImage%=images% 60 MODE 1 70 REM Set colour palette... 80 VDU 19,1,2,0,0,0 90 VDU 19,2,6,0,0,0 100 VDU 19,3,3,0,0,0 110 COL_EXPLODE=3 120 REM Create alien flight path data... 130 DIM pathData% 550 140 FLIGHT_PATH_SIZE=255 150 FLIGHT_PATH_IX=220 160 FLIGHT_PATH_IY=950 170 endOfPathData%=FN_InitFlightPattern(pathData%) 180 REM Add graphic image definitions... 190 rocketImage%=workImage% 200 workImage%=FN_AddRocketImage(rocketImage%) 210 alien1Image%=workImage% 220 workImage%=FN_AddAlien1Image(alien1Image%) 230 bulletImage%=workImage% 240 workImage%=FN_AddBulletImage(bulletImage%) 250 explosionImage%=workImage% 260 workImage%=FN_AddExplosionImage(explosionImage%) 270 bigExplosionImage%=workImage% 280 workImage%=FN_AddBigExplosionImage(bigExplosionImage%) 290 REM Entity States... 300 DEAD_ENTITY=0 310 ALIEN_LIVE=20 320 ALIEN_EXPLODE=ALIEN_LIVE-1 330 PLAYER_LIVE=200 340 PLAYER_EXPLODE=PLAYER_LIVE-1 350 REM Base entity field offsets... 360 eENTITY_SIZE=26 370 eTYPE=0 380 eSIZE=1 390 eIMAGE=2 400 eSTATE=6 410 eCOLOUR=7 420 eXPOS=8 430 eYPOS=12 440 eHWIDTH=16 450 eHHEIGHT=17 460 eXCENTRE=18 470 eYCENTRE=22 480 REM Special fields above base entity 490 eFLIGHT_PATH_INDEX=eENTITY_SIZE+0 500 REM Entity types 510 ePLAYER=0 520 eBULLET=1 530 eBOMB=2 540 eALIEN=3 550 REM Other global settings... 560 BOMB_SPEED=12 570 BULLET_SPEED=20 580 PLAYER_START_X=600 590 PLAYER_START_Y=40 600 REM Add entities... 610 pNext%=0 620 DIM entities% 2500 630 REPEAT 640 REM Player's rocket... 650 pRocket%=entities% 660 rX%=PLAYER_START_X:rY%=PLAYER_START_Y 670 pNext%=FN_InitEntity(ePLAYER, 0, pRocket%, rocketImage%, PLAYER_LIVE, 2, rX%, rY%) 680 REM Aliens... 690 MaxAliens%=20 700 pAliens%=pNext% 710 FOR A=0 TO MaxAliens% 720 pNext%=FN_InitAlien(eALIEN, pNext%, alien1Image%, DEAD_ENTITY, 3, FLIGHT_PATH_IX, FLIGHT_PATH_IY, FLIGHT_PATH_SIZE) 730 NEXT A 740 REM Bullets... 750 MaxBullets%=10 760 pBullets%=pNext% 770 FOR B=0 TO MaxBullets% 780 pNext%=FN_InitEntity(eBULLET, 0, pNext%, bulletImage%, 0, 2, 0, 0) 790 NEXT B 800 pNextBullet%=pBullets% 810 pEndBullets%=pNext% 820 REM Bombs... 830 MaxBombs%=50 840 pBombs%=pNext% 850 FOR B=0 TO MaxBombs% 860 pNext%=FN_InitEntity(eBOMB, 0, pNext%, bulletImage%, 0, 3, 0, 0) 870 NEXT B 880 pNextBomb%=pBombs% 890 pEndBombs%=pNext% 900 canFire%=0 910 CLS:VDU 5 920 MOVE 0, 128 930 GCOL 0,1 940 PRINT "Used Image Space:" workImage%-images% 950 PRINT "Used Entity Space:" pNext%-entities% 960 PRINT "Used F-Path Data:" endOfPathData%-pathData% 970 MOVE 410,650:PRINT"PIXEL FANDANGO" 980 MOVE 395,600:PRINT"SPACE-FIGHTER-X" 990 REM Clear keyboard buffer... 1000 *FX 15 1010 MOVE 430,550:PRINT"PRESS ANY KEY" 1020 a%=GET 1030 CLS:VDU 5 1040 score%=0 1050 lastScore%=0 1060 lives%=3 1070 spawnSize%=4 1080 REM Game loop... 1090 REPEAT 1100 PROC_NewPlayer(pRocket%, rocketImage%) 1110 PROC_MoveEntityTo(pRocket%, rX%, rY%) 1120 cycle%=0 1130 alienSpawn%=0 1140 REPEAT 1150 cycle%=cycle%+1 1160 IF score%<>lastScore% THEN MOVE 300,1000:GCOL 0,0:PRINT "SCORE:";lastScore%:lastScore%=score% 1170 MOVE 300,1000:GCOL 0,3:PRINT "SCORE:";score% 1180 MOVE 800,1000:GCOL 0,3:PRINT "LIVES:";lives% 1190 pPlayerState%=pRocket%+eSTATE 1200 REM draw aliens... 1210 workAlien%=pAliens% 1220 nLiveAliens%=0 1230 FOR A=0 TO MaxAliens% 1240 REM Update explosion count (if in exploding state) 1250 pAlienState%=workAlien%+eSTATE 1260 IF ?(pAlienState%)=1 PROC_DrawEntity(workAlien%, 0):?(workAlien%+eSTATE)=0 1270 IF ?(pAlienState%)>0 AND ?(pAlienState%)<20 THEN ?(pAlienState%)=?(pAlienState%)-1:PROC_DrawEntity(workAlien%, COL_EXPLODE) 1280 isAlive%=?(pAlienState%)>=20 1290 IF isAlive% AND ?(pPlayerState%)=PLAYER_LIVE AND RND(1000)<15 THEN pNextBomb%=FN_DropBomb(workAlien%, pNextBomb%):IF pNextBomb%>=pEndBombs% THEN pNextBomb%=pBombs% 1300 IF isAlive% THEN workAlien%=FN_UpdateAlien(workAlien%, pBullets%, pathData%, explosionImage%) ELSE workAlien%=FN_NextEntity(workAlien%) 1310 IF isAlive% THEN nLiveAliens%=nLiveAliens%+1 1320 NEXT A 1330 IF nLiveAliens%=0 AND alienSpawn%=0 THEN alienSpawn%=spawnSize%:IF spawnSize%0 THEN PROC_StartAlien(pAliens%):alienSpawn%=alienSpawn%-1 1350 REM draw bullets... 1360 workBullet%=pBullets% 1370 FOR B=0 TO MaxBullets% 1380 workBullet%=FN_UpdateBullet(workBullet%, BULLET_SPEED) 1390 NEXT B 1400 workBomb%=pBombs% 1410 FOR B=0 TO MaxBombs% 1420 workBomb%=FN_UpdateBullet(workBomb%, BOMB_SPEED) 1430 NEXT B 1440 REM handle user input... 1450 newX%=rX% 1460 IF INKEY(-98) THEN newX%=newX%-12:IF newX%<32 THEN newX%=32 1470 IF INKEY(-67) THEN newX%=newX%+12:IF newX%>1150 THEN newX%=1150 1480 IF INKEY(-74)=0 AND ?(pPlayerState%)=PLAYER_LIVE THEN canFire%=1 1490 IF canFire%=1 AND INKEY(-74) THEN pNextBullet%=FN_SetBullet(pNextBullet%,1,rX%+50,rY%+90):canFire%=0 1500 IF pNextBullet%>=pEndBullets% THEN pNextBullet%=pBullets% 1510 REM Wait for screen refresh sync... 1520 *FX19 1530 IF newX%<>rX% AND ?(pPlayerState%)=PLAYER_LIVE THEN PROC_MoveEntityTo(pRocket%, newX%, rY%):rX%=newX% 1540 IF ?(pPlayerState%) 0 (is active) 3870 IF ?(pEntity%+eSTATE)=0 THEN =pEntity%+?(pEntity%+eSIZE) 3880 PROC_DrawEntity(pEntity%, 0) 3890 pX%=!(pEntity%+eXPOS)+dx 3900 pY%=!(pEntity%+eYPOS)+dy 3910 IF pX%>1280 THEN pX%=pX%-1280 3920 IF pX%<0 THEN pX%=pX%+1280 3930 IF pY%>1024 THEN pY%=pY%-1024 3940 IF pY%<0 THEN pY%=pY%+1024 3950 !(pEntity%+eXPOS)=pX% 3960 !(pEntity%+eYPOS)=pY% 3970 PROC_SetCollnCentre(pEntity%) 3980 PROC_DrawEntity(pEntity%, ?(pEntity%+eCOLOUR)) 3990 =pEntity%+?(pEntity%+eSIZE) 4000 REM 4010 REM -------------------------- 4020 REM Move an entity (absolute) 4030 REM -------------------------- 4040 DEF PROC_MoveEntityTo(pEntity%, x%, y%) 4050 REM Only move if state > 0 (is active) 4060 IF ?(pEntity%+eSTATE)=0 THEN =pEntity+?(pEntity%+eSIZE) 4070 PROC_DrawEntity(pEntity%, 0) 4080 !(pEntity%+eXPOS)=x% 4090 !(pEntity%+eYPOS)=y% 4100 PROC_SetCollnCentre(pEntity%) 4110 PROC_DrawEntity(pEntity%, ?(pEntity%+eCOLOUR)) 4120 ENDPROC 4130 REM 4140 REM -------------------------- 4150 REM Get pointer to next entity 4160 REM -------------------------- 4170 DEF FN_NextEntity(pEntity%) 4180 =pEntity%+?(pEntity%+eSIZE) 4190 REM 4200 REM -------------------------- 4210 REM Collision Detection 4220 REM lhs, rhs, top, bot collision 4230 REM range pre calc'd on entity move 4240 REM -------------------------- 4250 DEF FN_IsCollision(pEntity1%, pEntity2%, radius%) 4260 REM Only check if both entities are active 4270 IF ?(pEntity1%+eSTATE)=0 OR ?(pEntity2%+eSTATE)=0 = 0 4280 dX=ABS(!(pEntity1%+eXCENTRE)-!(pEntity2%+eXCENTRE)) 4290 dY=ABS(!(pEntity1%+eYCENTRE)-!(pEntity2%+eYCENTRE)) 4300 IF dX1000 OR !(pBullet%+eYPOS)<24 THEN ?(pState%)=3 4430 =pBullet%+?(pBullet%+eSIZE) 4440 REM -------------------------------------------------- 4450 DEF FN_SetBullet(pBullet%, state%, x%, y%) 4460 ?(pBullet%+eSTATE)=state% 4470 !(pBullet%+eXPOS)=x% 4480 !(pBullet%+eYPOS)=y% 4490 PROC_SetCollnCentre(pBullet%) 4500 IF state%=1 THEN SOUND 1,-15,100,1 4510 REM IF state%=2 THEN SOUND 1,-10,50,5 4520 =pBullet%+?(pBullet%+eSIZE) 4530 REM -------------------------------------------------- 4540 DEF FN_InitAlien(type%, pEntity%, pImage%, state%, colour%, x%, y%, pathIndex%) 4550 endAddress%=FN_InitEntity(type%, 1, pEntity%, pImage%, state%, colour%, x%, y%) 4560 ?(pEntity%+eFLIGHT_PATH_INDEX)=pathIndex% 4570 =endAddress% 4580 REM -------------------------------------------------- 4590 DEF PROC_AlienHit(pAlien%, pBullet%) 4600 PROC_DrawEntity(pAlien%, 0) 4610 ?(pAlien%+eSTATE)=ALIEN_EXPLODE 4620 !(pAlien%+eIMAGE)=pExplosionImage% 4630 ?(pBullets%+eSTATE)=3 4640 SOUND 0,-15,150,1 4650 score%=score%+10 4660 ENDPROC 4670 REM -------------------------------------------------- 4680 DEF PROC_CheckAlienCollision(pAlien%, pBullets%, pExplosionImage%) 4690 REM If alien is exploding (or dead) then ignore 4700 cRadius%=?(!(pAlien%+eIMAGE)+2) 4710 IF ?(pAlien%+eSTATE)<20 ENDPROC 4720 FOR B=0 TO MaxBullets% 4730 IF ?(pBullets%+eSTATE)>0 AND FN_IsCollision(workAlien%, pBullets%, cRadius%) PROC_AlienHit(pAlien%, pBullets%):ENDPROC 4740 pBullets%=pBullets%+?(pBullets%+eSIZE) 4750 NEXT B 4760 ENDPROC 4770 REM -------------------------------------------------- 4780 DEF FN_IsPlayerCollision(pRocket%, pBombs%) 4790 cRadius%=?(!(pRocket%+eIMAGE)+2) 4800 FOR B=0 TO MaxBombs% 4810 IF ?(pBombs%+eSTATE)>0 AND FN_IsCollision(pRocket%, pBombs%, cRadius%) THEN ?(pBombs%+eSTATE)=3: =1 4820 pBombs%=pBombs%+?(pBombs%+eSIZE) 4830 NEXT B 4840 =0 4850 REM -------------------------------------------------- 4860 DEF FN_UpdateAlien(pAlien%, pBullets%, pFlightPath%, pExplosionImage%) 4870 PROC_CheckAlienCollision(pAlien%, pBullets%, explosionImage%) 4880 fpi%=?(pAlien%+eFLIGHT_PATH_INDEX) 4890 fpi%=fpi%+1 4900 IF fpi%>=FLIGHT_PATH_SIZE fpi%=0:PROC_MoveEntityTo(pAlien%,FLIGHT_PATH_IX, FLIGHT_PATH_IY) 4910 ?(pAlien%+eFLIGHT_PATH_INDEX)=fpi% 4920 pLookUp%=pFlightPath%+(fpi%*2) 4930 dX=?(pLookUp%):IF dX>128 THEN dX=128-dX 4940 dY=?(pLookUp%+1):IF dY>128 THEN dY=128-dY 4950 =FN_MoveEntity(pAlien%, dX, dY) 4960 REM -------------------------------------------------- 4970 DEF FN_DropBomb(pAlien%,pNextBomb%) 4980 =FN_SetBullet(pNextBomb%,2,!(workAlien%+eXCENTRE),!(workAlien%+eYCENTRE)) 4990 REM -------------------------------------------------- 5000 DEF PROC_KillPlayer(pPlayer%, pExplosionImage%) 5010 PROC_DrawEntity(pPlayer%, 0) 5020 IF ?(pPlayer%+eSTATE)