0 ------------------------------------------ $ Pixel Fandango Space Fighter X 0 ------------------------------------------ ( ChangeLog (over V1) 2 + Multicolour entities < + High Score F + Stars P + Better sounds .Z + Aliens dont bomb near bottom of screen d + 2nd alien design !n + 2nd aliens enter from RHS "x + Bonus collection and modes & + Fix player explosion disappear  + Fix alternate wave bug  + High wave 0 ------------------------------------------  1  _ShowError  Set sound envelopes... , 1,1,4,-4,4,10,20,10,127,0,0,-1,100,100 - 2,129,3,5,2,10,20,10,127,0,0,-5,126,126 - 3,129,0,0,0,10,10,10,127,5,0,-5,126,126  Set colour palette...  19,1,5,0,0,0  19,2,6,0,0,0  19,3,3,0,0,0 COL_EXPLODE=3  Visual parameters... "VIEWER_DIST=150 ,VIEWER_HEIGHT=1400 6VIEW_WIDTH=1280 @VIEW_Y_OFFSET=260 J Entity States... TDEAD_ENTITY=0 ,^ALIEN_LIVE=20:ALIEN_EXPLODE=ALIEN_LIVE-1 hALIEN_RND_WAVE=22 rBONUS_TIME=10 |MIN_BOMB_HEIGHT=420 1PLAYER_LIVE=250: PLAYER_EXPLODE=PLAYER_LIVE-1 " Base entity field offsets... eENTITY_SIZE=25 eTYPE=0 eSIZE=1 eIMAGE=2 eSTATE=6 eXPOS=7 eYPOS=11 eHWIDTH=15 eHHEIGHT=16 eXCENTRE=17 eYCENTRE=21 & Special fields above base entity %eFLIGHT_PATH_INDEX=eENTITY_SIZE+0 $eFLIGHT_PATH_SIDE=eENTITY_SIZE+1 & Entity types ;0ePLAYER=0:eBULLET=1:eBOMB=2:eALIEN=3:eBONUS=4:eSHIELD=5 &: Entity part drawing instructions $DdMOVE=1:dDRAW=2:dCOLOUR=3:dEND=0 N Bonus Modes 3XbmNONE=0:bmLIFE=1:bmSHIELD=2:bm2SHOT=3:bmCONT=4 7bbmMAX=bmCONT:bmTIME=500:bmTIMESHOW=50:bmMSGSHOW=100 l Other global settings... !vBOMB_SPEED=8: BULLET_SPEED=20 )PLAYER_START_X=600: PLAYER_START_Y=50 0 ------------------------------------------ # Populate static data for game 0 ------------------------------------------  & Create alien flight path data...  pathData% 550 FLIGHT_PATH_SIZE=255 FLIGHT_PATH_IX_LHS=220 FLIGHT_PATH_IX_RHS=1000 FLIGHT_PATH_IY=850 1endOfPathData%=_InitFlightPattern(pathData%)  starData% 64 STARS_SIZE=32 ) endOfStarDate%=_InitStars(starData%) & Add graphic image definitions...   images% 450 *workImage%=images% 4rocketImage%=workImage% ->workImage%=_AddRocketImage(rocketImage%) Halien1Image%=workImage% -RworkImage%=_AddAlien1Image(alien1Image%) \alien2Image%=workImage% -fworkImage%=_AddAlien2Image(alien2Image%) pbulletImage%=workImage% -zworkImage%=_AddBulletImage(bulletImage%) explosionImage%=workImage% 3workImage%=_AddExplosionImage(explosionImage%) !bigExplosionImage%=workImage% 9workImage%=_AddBigExplosionImage(bigExplosionImage%) bonusImage%=workImage% +workImage%=_AddBonusImage(bonusImage%) shieldImage%=workImage% -workImage%=_AddShieldImage(shieldImage%)  Allocate entity space... pNext%=0  entities% 2800 0 ------------------------------------------  Program control loop 0 ------------------------------------------ HighScore%=1000 HighWave%=10 $ . Player's rocket... 8pRocket%=entities% )BrX%=PLAYER_START_X:rY%=PLAYER_START_Y RLpNext%=_InitEntity(ePLAYER, 0, pRocket%, rocketImage%, PLAYER_LIVE, rX%, rY%) V Bonus object... `pBonus%=pNext% AjpNext%=_InitEntity(eBONUS, 0, pBonus%, bonusImage%, 0, 0, 0) t Shield object... ~pShield%=pNext% DpNext%=_InitEntity(eSHIELD, 0, pShield%, shieldImage%, 0, 0, 0)  Aliens... MaxAliens%=20 pAliens%=pNext%  A=0 MaxAliens% zpNext%=_InitAlien(eALIEN, pNext%, alien1Image%, DEAD_ENTITY, FLIGHT_PATH_IX_LHS, FLIGHT_PATH_IY, FLIGHT_PATH_SIZE, 0)  A  Bullets... MaxBullets%=30 pBullets%=pNext%  B=0 MaxBullets% BpNext%=_InitEntity(eBULLET, 0, pNext%, bulletImage%, 0, 0, 0)  B  pNextBullet%=pBullets% pEndBullets%=pNext%  Bombs... (MaxBombs%=50 2pBombs%=pNext% < B=0 MaxBombs% @FpNext%=_InitEntity(eBOMB, 0, pNext%, bulletImage%, 0, 0, 0) P B ZpNextBomb%=pBombs% dpEndBombs%=pNext% ncanFire%=0 x: 5  0, 328  0, 3 . Uncomment below to see object mem use... 3 PRINT "images: "; workImage%-images% " bytes" 3 PRINT "entities: "; pNext%-entities% " bytes" ; PRINT "fli-path: "; endOfPathData%-pathData% " bytes"  410,700:"PIXEL FANDANGO" & 300,120:"www.PIXELFANDANGO.com" ' 265,70:"youTube:@pixel_fandango"  0, 1 # 345,640:"3D-SPACE-FIGHTER-X"  0, 2 ' 425,1000: "HI SCORE:";HighScore% $ 475,950: "HI WAVE:";HighWave% ! 380,550:"(Z) (X) (RETURN)" ) Pause then clear keyboard buffer... "_Pause(100) ,*FX 15 &6 303,470:"PRESS ANY KEY TO PLAY" ;@ Init sound (some emulators pause on first sound call) J 0,-1,200,1: 1,-1,200,1 Ta%= ^ 1,1,100,50 h: 5 rscore%=0 |lastScore%=0 lives%=3 spawnSize%=4 wave%=0 bonusMode%=bmNONE bonusCountDown%=0 msgCountDown%=0 msgText$="" 0 ------------------------------------------  Outer game loop... 0 ------------------------------------------ cycle%=0  '_NewPlayer(pRocket%, rocketImage%) &_MoveEntityTo(pRocket%, rX%, rY%) alienSpawn%=0 . ---------------------------------------- & Inner game loop... .0 ---------------------------------------- : Dcycle%=cycle%+1 N_DrawStars(starData%, 0) PX score%>HighScore% 570,1000: 0,0: "HI:";HighScore%:HighScore%=score%: Sb score%<>lastScore% 200,1000: 0,0: "SCORE:";lastScore%:lastScore%=score% 0l msgCountDown%>1 460,550: 0,1: msgText$ 5v msgCountDown%>0 msgCountDown%=msgCountDown%-1 2 msgCountDown%=1 460,550: 0,0: msgText$ ^ bonusMode%=bmLIFE 870,1000: 0,0: "LIVES:";lives%:lives%=lives%+1:bonusMode%=bmNONE ] bonusCountDown%>0 bonusMode%>bmLIFE 0,0: 360,500: bonusCountDown% bmTIMESHOW 7 bonusCountDown%=1 bonusMode%=bmNONE: 1,1,60,10 ; bonusCountDown%>0 bonusCountDown%=bonusCountDown%-1 ] bonusCountDown%>0 bonusMode%>bmLIFE 0,2: 360,500: bonusCountDown% bmTIMESHOW i bonusCountDown%>0 bonusCountDown% bmTIMESHOW = 0 3,-15,200 - bonusCountDown% bmTIMESHOW,5  0,3  200,1000: "SCORE:";score%  870,1000: "LIVES:";lives%  score%=HighScore% 0,2 ! 570,1000: "HI:";HighScore% !pPlayerState%=pRocket%+eSTATE  draw aliens...  workAlien%=pAliens% nLiveAliens%=0   A=0 MaxAliens% 4* Update explosion count (if in exploding state) "4pAlienState%=workAlien%+eSTATE ~> ?(pAlienState%)=BONUS_TIME bonusMode%=0 (20)=1 _DropBonus(pBonus%,!(workAlien%+eXCENTRE),!(workAlien%+eYCENTRE)) JH ?(pAlienState%)=1 _ClearEntity(workAlien%):?(workAlien%+eSTATE)=0 qR ?(pAlienState%)>0 ?(pAlienState%)=ALIEN_LIVE f isAlive% ?(pPlayerState%)=PLAYER_LIVE !(workAlien%+eYPOS)>MIN_BOMB_HEIGHT (1000)<20 pNextBomb%=_DropBomb(workAlien%, pNextBomb%,pBombs%, pEndBombs%) p isAlive% workAlien%=_UpdateAlien(workAlien%, pBullets%, pathData%, explosionImage%) workAlien%=_NextEntity(workAlien%) ,z isAlive% nLiveAliens%=nLiveAliens%+1  A } nLiveAliens%=0 alienSpawn%=0 alienSpawn%=spawnSize%:wave%=wave%+1: spawnSize%0 _StartAlienForWave(pAliens%,wave%):alienSpawn%=alienSpawn%-1  draw bullets... workBullet%=pBullets%  B=0 MaxBullets% 9workBullet%=_UpdateBullet(workBullet%, BULLET_SPEED)  B workBomb%=pBombs%  B=0 MaxBombs% 3workBomb%=_UpdateBullet(workBomb%, BOMB_SPEED)  B  draw bonus object... $ _UpdateBonus(pBonus%, pRocket%)  handle user input...  newX%=rX% 3$ (-98) newX%=newX%-12: newX%<32 newX%=32 7. (-67) newX%=newX%+12: newX%>1150 newX%=1150 :8 (-74)=0 ?(pPlayerState%)=PLAYER_LIVE canFire%=1 aB bonusMode%=bmCONT ?(pPlayerState%)=PLAYER_LIVE canFire%=0 cycle% 5 = 0 canFire%=1 L bonusMode%=bm2SHOT canFire%=1 (-74) pNextBullet%=_SetWingBullets(pNextBullet%,pBullets%,pEndBullets%,1,rX%+52,rY%+95):canFire%=0 V bonusMode%<>bm2SHOT canFire%=1 (-74) pNextBullet%=_SetBullet(pNextBullet%,pBullets%,pEndBullets%,1,rX%+52,rY%+95):canFire%=0 G` bonusMode%=bmSHIELD ?(pShield%+eSTATE)=0 ?(pShield%+eSTATE)=1 `j bonusMode%<>bmSHIELD ?(pShield%+eSTATE)=1 ?(pShield%+eSTATE)=0:_ClearEntity(pShield%) %t Wait for screen refresh sync... ~ *FX19 ` newX%<>rX% ?(pPlayerState%)=PLAYER_LIVE _MoveEntityTo(pRocket%, newX%, rY%):rX%=newX% > bonusMode%=bmSHIELD _MoveEntityTo(pShield%, rX%, rY%) _ ?(pPlayerState%)bmSHIELD _IsPlayerCollision(pRocket%, pBombs%) _KillPlayer(pRocket%, bigExplosionImage%):canFire%=0  ?(pRocket%+eSTATE)=0 & 870,1000: 0,0: "LIVES:";lives%  lives%=lives%-1  lives%=0 0,128: 0,2  5: 505,500:"GAME OVER" 0,3 200,1000: "SCORE:";score% ! 870,1000: "HI:";HighScore% , wave%>HighWave% HighWave%=wave%:0,1 (( 350,600:"YOU REACHED WAVE ";wave% 2 _Pause(250) < 0 F 8P -------------------------------------------------- 3Z Functions to handle graphic image definitions 8d -------------------------------------------------- n x -------------------------- Function to add image defn  header information for  collision detection -------------------------- B _AddImageHeader(address%, centreX%, centreY%, collnRadius%)  ?(address%+0)=centreX%  ?(address%+1)=centreY%  ?(address%+2)=collnRadius%  =address%+3 --------------------------  Function to add an image  part to defn at address type: 0=end 1=MOVE, 2=DRAW  x,y are coords from TL  Returns next free address  -------------------------- -" _AddImagePart(address%, type%, x%, y%) , ?(address%+0)=type% 6 ?(address%+1)=x% @ ?(address%+2)=y% J =address%+3 T :^ _AddImagePartScaled(address%, type%, x%, y%, scale) h ?(address%+0)=type% r ?(address%+1)=(x%*scale) | ?(address%+2)=(y%*scale)  =address%+3  - _AddImagePartColour(address%, colour%)  ?(address%+0)=3  ?(address%+1)=colour%  =address%+2  --------------------------  Functions to add images -------------------------- _AddRocketImage(address%)  rScale=0.6 Q address%=_AddImageHeader(address%, (70*rScale), (55*rScale), (67*rScale)) . address%=_AddImagePartColour(address%, 2) B address%=_AddImagePartScaled(address%, dMOVE, 80, 40, rScale) C address%=_AddImagePartScaled(address%, dDRAW, 100, 20, rScale) A& address%=_AddImagePartScaled(address%, dDRAW, 80, 0, rScale) A0 address%=_AddImagePartScaled(address%, dDRAW, 60, 0, rScale) B: address%=_AddImagePartScaled(address%, dDRAW, 40, 20, rScale) BD address%=_AddImagePartScaled(address%, dDRAW, 60, 40, rScale) BN address%=_AddImagePartScaled(address%, dDRAW, 80, 40, rScale) BX address%=_AddImagePartScaled(address%, dDRAW, 80, 80, rScale) Cb address%=_AddImagePartScaled(address%, dDRAW, 100, 60, rScale) Cl address%=_AddImagePartScaled(address%, dDRAW, 70, 120, rScale) Bv address%=_AddImagePartScaled(address%, dDRAW, 80, 80, rScale) B address%=_AddImagePartScaled(address%, dDRAW, 60, 80, rScale) C address%=_AddImagePartScaled(address%, dDRAW, 70, 120, rScale) B address%=_AddImagePartScaled(address%, dDRAW, 40, 60, rScale) B address%=_AddImagePartScaled(address%, dDRAW, 60, 80, rScale) B address%=_AddImagePartScaled(address%, dDRAW, 60, 40, rScale)  left wing . address%=_AddImagePartColour(address%, 3) B address%=_AddImagePartScaled(address%, dMOVE, 40, 20, rScale) A address%=_AddImagePartScaled(address%, dDRAW, 5, 25, rScale) A address%=_AddImagePartScaled(address%, dDRAW, 5, 35, rScale) B address%=_AddImagePartScaled(address%, dDRAW, 40, 60, rScale) B address%=_AddImagePartScaled(address%, dDRAW, 40, 20, rScale)  right wing C address%=_AddImagePartScaled(address%, dMOVE, 100, 20, rScale) C address%=_AddImagePartScaled(address%, dDRAW, 135, 25, rScale) C address%=_AddImagePartScaled(address%, dDRAW, 135, 35, rScale) C address%=_AddImagePartScaled(address%, dDRAW, 100, 60, rScale) C* address%=_AddImagePartScaled(address%, dDRAW, 100, 20, rScale) 4 ?(address%)=dEND > =address%+1 H _AddShieldImage(address%) R rScale=0.8 Q\ address%=_AddImageHeader(address%, (70*rScale), (60*rScale), (64*rScale)) .f address%=_AddImagePartColour(address%, 1) Ap address%=_AddImagePartScaled(address%, dMOVE, 0, 90, rScale) Cz address%=_AddImagePartScaled(address%, dDRAW, 40, 130, rScale) D address%=_AddImagePartScaled(address%, dDRAW, 100, 130, rScale) C address%=_AddImagePartScaled(address%, dDRAW, 140, 90, rScale)  ?(address%)=dEND  =address%+1 _AddAlien1Image(address%)  aScale=1.6 Q address%=_AddImageHeader(address%, (25*aScale), (20*aScale), (24*aScale)) . address%=_AddImagePartColour(address%, 1) B address%=_AddImagePartScaled(address%, dMOVE, 40, 30, aScale) B address%=_AddImagePartScaled(address%, dDRAW, 40, 10, aScale) A address%=_AddImagePartScaled(address%, dDRAW, 50, 0, aScale) B address%=_AddImagePartScaled(address%, dDRAW, 50, 20, aScale) B address%=_AddImagePartScaled(address%, dDRAW, 30, 40, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 20, 40, aScale) Aaddress%=_AddImagePartScaled(address%, dDRAW, 0, 20, aScale) @address%=_AddImagePartScaled(address%, dDRAW, 0, 0, aScale) B$address%=_AddImagePartScaled(address%, dDRAW, 10, 10, aScale) B.address%=_AddImagePartScaled(address%, dDRAW, 10, 30, aScale) B8address%=_AddImagePartScaled(address%, dDRAW, 10, 10, aScale) ABaddress%=_AddImagePartScaled(address%, dDRAW, 20, 0, aScale) ALaddress%=_AddImagePartScaled(address%, dDRAW, 30, 0, aScale) BVaddress%=_AddImagePartScaled(address%, dDRAW, 40, 10, aScale) .`address%=_AddImagePartColour(address%, 3) Bjaddress%=_AddImagePartScaled(address%, dMOVE, 15, 20, aScale) Btaddress%=_AddImagePartScaled(address%, dDRAW, 35, 20, aScale) B~address%=_AddImagePartScaled(address%, dDRAW, 35, 30, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 25, 20, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 15, 30, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 15, 20, aScale) .address%=_AddImagePartColour(address%, 2) Baddress%=_AddImagePartScaled(address%, dDRAW, 25, 10, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 35, 20, aScale) ?(address%)=dEND =address%+1  _AddAlien2Image(address%) aScale=1.6 Qaddress%=_AddImageHeader(address%, (25*aScale), (20*aScale), (24*aScale)) .address%=_AddImagePartColour(address%, 1) Baddress%=_AddImagePartScaled(address%, dMOVE, 20, 40, aScale) B address%=_AddImagePartScaled(address%, dDRAW, 30, 40, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 40, 30, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 40, 10, aScale) A(address%=_AddImagePartScaled(address%, dDRAW, 30, 0, aScale) A2address%=_AddImagePartScaled(address%, dDRAW, 20, 0, aScale) B<address%=_AddImagePartScaled(address%, dDRAW, 10, 10, aScale) BFaddress%=_AddImagePartScaled(address%, dDRAW, 10, 30, aScale) BPaddress%=_AddImagePartScaled(address%, dDRAW, 20, 40, aScale) .Zaddress%=_AddImagePartColour(address%, 3) Bdaddress%=_AddImagePartScaled(address%, dMOVE, 15, 30, aScale) Bnaddress%=_AddImagePartScaled(address%, dDRAW, 25, 25, aScale) Bxaddress%=_AddImagePartScaled(address%, dDRAW, 35, 30, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 35, 20, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 15, 20, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 15, 30, aScale) .address%=_AddImagePartColour(address%, 2) Baddress%=_AddImagePartScaled(address%, dMOVE, 15, 15, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 35, 15, aScale) .address%=_AddImagePartColour(address%, 3) Aaddress%=_AddImagePartScaled(address%, dMOVE, 0, 10, aScale) Aaddress%=_AddImagePartScaled(address%, dDRAW, 5, 20, aScale) Aaddress%=_AddImagePartScaled(address%, dDRAW, 0, 30, aScale) Baddress%=_AddImagePartScaled(address%, dMOVE, 50, 10, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 45, 20, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 50, 30, aScale) ?(address%)=dEND =address%+1  _AddBulletImage(address%) 0"address%=_AddImageHeader(address%, 3, 8, 5) .,address%=_AddImagePartColour(address%, 3) 26address%=_AddImagePart(address%, dMOVE, 0, 0) 2@address%=_AddImagePart(address%, dDRAW, 6, 0) 3Jaddress%=_AddImagePart(address%, dDRAW, 6, 16) 3Taddress%=_AddImagePart(address%, dDRAW, 0, 16) 2^address%=_AddImagePart(address%, dDRAW, 0, 0) h?(address%)=dEND r=address%+1 #| _AddExplosionImage(address%) 3address%=_AddImageHeader(address%, 25, 25, 25) .address%=_AddImagePartColour(address%, 1) 2address%=_AddImagePart(address%, dMOVE, 0, 0) 4address%=_AddImagePart(address%, dDRAW, 10, 20) 3address%=_AddImagePart(address%, dDRAW, 0, 30) 4address%=_AddImagePart(address%, dDRAW, 15, 30) 4address%=_AddImagePart(address%, dDRAW, 20, 50) 4address%=_AddImagePart(address%, dDRAW, 30, 30) 4address%=_AddImagePart(address%, dDRAW, 50, 40) 4address%=_AddImagePart(address%, dDRAW, 40, 20) 4address%=_AddImagePart(address%, dDRAW, 50, 10) 4address%=_AddImagePart(address%, dDRAW, 35, 10) 3address%=_AddImagePart(address%, dDRAW, 30, 0) 4address%=_AddImagePart(address%, dDRAW, 20, 10) 2address%=_AddImagePart(address%, dDRAW, 0, 0) ?(address%)=dEND &=address%+1 &0 _AddBigExplosionImage(address%) 3:address%=_AddImageHeader(address%, 50, 50, 50) .Daddress%=_AddImagePartColour(address%, 2) 2Naddress%=_AddImagePart(address%, dMOVE, 0, 0) 4Xaddress%=_AddImagePart(address%, dDRAW, 20, 40) 3baddress%=_AddImagePart(address%, dDRAW, 0, 60) 4laddress%=_AddImagePart(address%, dDRAW, 30, 60) 5vaddress%=_AddImagePart(address%, dDRAW, 40, 100) 4address%=_AddImagePart(address%, dDRAW, 60, 60) 5address%=_AddImagePart(address%, dDRAW, 100, 80) 4address%=_AddImagePart(address%, dDRAW, 80, 40) 5address%=_AddImagePart(address%, dDRAW, 100, 20) 4address%=_AddImagePart(address%, dDRAW, 70, 20) 3address%=_AddImagePart(address%, dDRAW, 60, 0) 4address%=_AddImagePart(address%, dDRAW, 40, 20) 2address%=_AddImagePart(address%, dDRAW, 0, 0) ?(address%)=dEND =address%+1  _AddBonusImage(address%) 3address%=_AddImageHeader(address%, 20, 20, 20) .address%=_AddImagePartColour(address%, 2) 4address%=_AddImagePart(address%, dMOVE, 20, 40) 3 address%=_AddImagePart(address%, dDRAW, 0, 20) 3address%=_AddImagePart(address%, dDRAW, 20, 0) 4 address%=_AddImagePart(address%, dDRAW, 40, 20) 4*address%=_AddImagePart(address%, dDRAW, 20, 40) 44address%=_AddImagePart(address%, dDRAW, 10, 10) 4>address%=_AddImagePart(address%, dDRAW, 30, 10) 4Haddress%=_AddImagePart(address%, dDRAW, 20, 40) R?(address%)=dEND \=address%+1 f p -------------------------- z Proc to draw image from  data at address in pos x,y  -------------------------- " _DrawImage(pImage%, x%, y%) $ Skip the header information... pImage%=pImage%+3  Draw each image part...  ,pImage%=_DrawImagePart(pImage%, x%, y%)  pImage%=0   --------------------------  Proc to clear image  -------------------------- # _ClearImage(pImage%, x%, y%) $ Skip the header information... pImage%=pImage%+3 $ Clear each image part... . 0,0 8 -BpImage%=_ClearImagePart(pImage%, x%, y%) L pImage%=0 V ` j -------------------------- t Function to draw part ~ -------------------------- % _DrawImagePart(pPart%, x%, y%) &=_RenderImagePart(pPart%, x%, y%)  --------------------------  Function to clear part  -------------------------- & _ClearImagePart(pPart%, x%, y%) ' Ignore colour change instructions # ?(pPart%)=dCOLOUR =pPart%+2 &=_RenderImagePart(pPart%, x%, y%)  --------------------------  Function to draw single  part of an image defn  and return next address   or 0 if its the last part  -------------------------- ' _RenderImagePart(pPart%, x%, y%) ,( Return 0 if this item is an end marker 2 ?pPart%=dEND =0 9< Either move or draw to a point in background colour 5F ?(pPart%)=dCOLOUR 0, ?(pPart%+1): =pPart%+2 Padjx=(?(pPart%+1)+x%) Zadjy=?(pPart%+2)+y% dY=adjy/(adjy+VIEWER_DIST) (nadjy=Y*VIEWER_HEIGHT - VIEW_Y_OFFSET xscale=1.5 Badjx=Y*(VIEW_WIDTH*scale/2)+((1-Y)*adjx*scale)- (VIEW_WIDTH/4) $ ?(pPart%)=dMOVE adjx, adjy $ ?(pPart%)=dDRAW adjx, adjy   return next address =pPart%+3  8 -------------------------------------------------- ' Functions to handle game entities 8 --------------------------------------------------   --------------------------  Initialise a new entity  Return next address  -------------------------- H _InitEntity(typeId%, addSize%, pEntity%, pImage%, state%, x%, y%) $" Record basic entity parameters ,?pEntity%=typeId% +6?(pEntity%+eSIZE)=eENTITY_SIZE+addSize% @!(pEntity%+eIMAGE)=pImage% J?(pEntity%+eSTATE)=state% T!(pEntity%+eXPOS)=x% ^!(pEntity%+eYPOS)=y% -h Calc offsets for collision detection... /r?(pEntity%+eHWIDTH)=?(!(pEntity%+eIMAGE)+0) 0|?(pEntity%+eHHEIGHT)=?(!(pEntity%+eIMAGE)+1) + Reserve space for centreX and centreY + calcs on move for collision detection !(pEntity%+eXCENTRE)=0 !(pEntity%+eYCENTRE)=0 4 Anything after this is specific to entity type =pEntity%+?(pEntity%+eSIZE)  --------------------------  Draw or clear an entity  --------------------------  _DrawEntity(pEntity%) I_DrawImage(!(pEntity%+eIMAGE), !(pEntity%+eXPOS), !(pEntity%+eYPOS))   _ClearEntity(pEntity%)  0,0 J_ClearImage(!(pEntity%+eIMAGE), !(pEntity%+eXPOS), !(pEntity%+eYPOS))  & 0 -------------------------- : Calc collision range D based on position, width, N height and radius. X -------------------------- b _SetCollnCentre(pEntity%) >l!(pEntity%+eXCENTRE)=!(pEntity%+eXPOS)+?(pEntity%+eHWIDTH) ?v!(pEntity%+eYCENTRE)=!(pEntity%+eYPOS)+?(pEntity%+eHHEIGHT)    --------------------------  Move an entity (relative)  -------------------------- $ _MoveEntity(pEntity%, dx, dy) ( Only move if state > 0 (is active) 8 ?(pEntity%+eSTATE)=0 =pEntity%+?(pEntity%+eSIZE) _ClearEntity(pEntity%) pX%=!(pEntity%+eXPOS)+dx pY%=!(pEntity%+eYPOS)+dy  pX%>1280 pX%=pX%-1280  pX%<0 pX%=pX%+1280  pY%>1024 pY%=pY%-1024   pY%<0 pY%=pY%+1024 !(pEntity%+eXPOS)=pX%  !(pEntity%+eYPOS)=pY% *_SetCollnCentre(pEntity%) 4_DrawEntity(pEntity%) >=pEntity%+?(pEntity%+eSIZE) H R -------------------------- \ Move an entity (absolute) f -------------------------- &p _MoveEntityTo(pEntity%, x%, y%) (z Only move if state > 0 (is active)  ?(pEntity%+eSTATE)=0 _ClearEntity(pEntity%) !(pEntity%+eXPOS)=x% !(pEntity%+eYPOS)=y% _SetCollnCentre(pEntity%) _DrawEntity(pEntity%)    --------------------------  Get pointer to next entity  --------------------------  _NextEntity(pEntity%) =pEntity%+?(pEntity%+eSIZE)   --------------------------  Collision Detection "$ lhs, rhs, top, bot collision %. range pre calc'd on entity move 8 -------------------------- 2B _IsCollision(pEntity1%, pEntity2%, radius%) ,L Only check if both entities are active 7V ?(pEntity1%+eSTATE)=0 ?(pEntity2%+eSTATE)=0 = 0 5`dX=(!(pEntity1%+eXCENTRE)-!(pEntity2%+eXCENTRE)) 5jdY=(!(pEntity1%+eYCENTRE)-!(pEntity2%+eYCENTRE)) t dX1000 !(pBullet%+eYPOS)<24 ?(pState%)=3 =pBullet%+?(pBullet%+eSIZE) 8 -------------------------------------------------- C  _SetBullet(pBullet%, pStartBMem%, pEndBMem%, state%, x%, y%) ?(pBullet%+eSTATE)=state% !(pBullet%+eXPOS)=x% (!(pBullet%+eYPOS)=y% 2_SetCollnCentre(pBullet%) < state%=1 2,2,100,1 ;F(pBullet%+?(pBullet%+eSIZE)>=pEndBMem%) =pStartBMem% P=pBullet%+?(pBullet%+eSIZE) 8Z -------------------------------------------------- Hd _SetWingBullets(pBullet%, pStartBMem%, pEndBMem%, state%, x%, y%) NnpNext%=_SetBullet(pBullet%, pStartBMem%, pEndBMem%, state%, x%-50, y%-50) Fx=_SetBullet(pNext%, pStartBMem%, pEndBMem%, state%, x%+50, y%-50) 8 -------------------------------------------------- R _InitAlien(type%, pEntity%, pImage%, state%, x%, y%, pathIndex%, pathSide%) IendAddress%=_InitEntity(type%, 2, pEntity%, pImage%, state%, x%, y%) -?(pEntity%+eFLIGHT_PATH_INDEX)=pathIndex% +?(pEntity%+eFLIGHT_PATH_SIDE)=pathSide% =endAddress% 8 -------------------------------------------------- # _AlienHit(pAlien%, pBullet%) _ClearEntity(pAlien%) #?(pAlien%+eSTATE)=ALIEN_EXPLODE &!(pAlien%+eIMAGE)=pExplosionImage% ?(pBullets%+eSTATE)=3  0,3,75,1 score%=score%+10  8 -------------------------------------------------- A" _CheckAlienCollision(pAlien%, pBullets%, pExplosionImage%) 1, If alien is exploding (or dead) then ignore #6cRadius%=?(!(pAlien%+eIMAGE)+2) $@ ?(pAlien%+eSTATE)0 _IsCollision(workAlien%, pBullets%, cRadius%) _AlienHit(pAlien%, pBullets%): *^pBullets%=pBullets%+?(pBullets%+eSIZE) h B r 8| -------------------------------------------------- , _IsPlayerCollision(pRocket%, pBombs%) $cRadius%=?(!(pRocket%+eIMAGE)+2)  B=0 MaxBombs% ` ?(pBombs%+eSTATE)>0 _IsCollision(pRocket%, pBombs%, cRadius%) ?(pBombs%+eSTATE)=3: =1 $pBombs%=pBombs%+?(pBombs%+eSIZE)  B =0 8 -------------------------------------------------- G _UpdateAlien(pAlien%, pBullets%, pFlightPath%, pExplosionImage%) >_CheckAlienCollision(pAlien%, pBullets%, explosionImage%) &fpi%=?(pAlien%+eFLIGHT_PATH_INDEX) fpi%=fpi%+1 % fpi%>=FLIGHT_PATH_SIZE fpi%=0 h fpi%=0 ?(pAlien%+eFLIGHT_PATH_SIDE)=0 _MoveEntityTo(pAlien%,FLIGHT_PATH_IX_RHS, FLIGHT_PATH_IY) h fpi%=0 ?(pAlien%+eFLIGHT_PATH_SIDE)=1 _MoveEntityTo(pAlien%,FLIGHT_PATH_IX_LHS, FLIGHT_PATH_IY) &?(pAlien%+eFLIGHT_PATH_INDEX)=fpi% "&pLookUp%=pFlightPath%+(fpi%*2) '0dX=?(pLookUp%): dX>128 dX=128-dX -: ?(pAlien%+eFLIGHT_PATH_SIDE)=0 dX=-dX )DdY=?(pLookUp%+1): dY>128 dY=128-dY "N=_MoveEntity(pAlien%, dX, dY) 8X -------------------------------------------------- ;b _DropBomb(pAlien%,pNextBomb%,pStartBMem%, pEndBMem%) cl=_SetBullet(pNextBomb%,pStartBMem%, pEndBMem%,2,!(workAlien%+eXCENTRE),!(workAlien%+eYCENTRE)) 8v -------------------------------------------------- . _KillPlayer(pPlayer%, pExplosionImage%) _ClearEntity(pPlayer%) ( ?(pPlayer%+eSTATE) _InitFlightPattern(address%) H N=0 FLIGHT_PATH_SIZE RyBase=(((N/4)+5)/7.8) !\X=(yBase*18): X<0 X=128-X (fY=((yBase/0.4)*16): Y<0 Y=128-Y !p?(address%)=X:?(address%+1)=Y zaddress%=address%+2  N =address%  * _StartAlienForWave(pAliens%, wave%) pNext%=pAliens% F(wave%0 y%<400 I8pNext%=_InitEntity(eBONUS, 0, pBonus%, !(pBonus%+eIMAGE), 1, x%, y%) B L &V _UpdateBonus(pBonus%, pPlayer%) ` ?(pBonus%+eSTATE)=0 Hj !(pBonus%+eYPOS)<10 ?(pBonus%+eSTATE)=0:_ClearEntity(pBonus%): %tpNext%=_MoveEntity(pBonus%,0,-3) &~radius%=25+?(!(pPlayer%+eIMAGE)+2) ( ?(pPlayer%+eSTATE)bmLIFE bonusCountDown%=bmTIME 8 bonusMode%=bmLIFE _ShowMessage(" EXTRA LIFE!") : bonusMode%=bmSHIELD _ShowMessage(" SHIELDS UP!") 9 bonusMode%=bm2SHOT _ShowMessage(" DOUBLE SHOT!") 7 bonusMode%=bmCONT _ShowMessage(" SUPER FIRE!") .?(pBonus%+eSTATE)=0:_ClearEntity(pBonus%)  8 --------------------------------------------------  Star background functions 8  --------------------------------------------------  _InitStars(address%)  N=1 STARS_SIZE (?(address%)=(255) 2?(address%+1)=(255) <address%=address%+2 F N P=address% Z $d _DrawStars(address%, offset%) noffset%=offset% 1024 x N=0 STARS_SIZE sX%=?(address%)*5 /sY%=1024-((?(address%+1)+offset%)*4) 1024 0 Don't show stars at bottom where player is 0 otherwise we have to keep redrawing player $ sY%>146 0,0: 69,sX%,sY%+4 0 sY%>150 0,(N+offset%) 8: 69,sX%,sY% address%=address%+2  N  8 --------------------------------------------------  Other useful procedures 8 --------------------------------------------------  _ShowMessage(message$)  msgCountDown%>0 msgCountDown%=bmMSGSHOW msgText$=message$ " , _Pause(cycles%) 6 C=1 cycles% @*FX19 J C T ^ _ShowError h 0 r*FX15 '| "-------------------------------" ' "PIXEL FANDANGO SPACE FIGHTER X" " " www.PixelFandango.com" ' "-------------------------------" : " at line ";