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  Entity States... "DEAD_ENTITY=0 ,,ALIEN_LIVE=20:ALIEN_EXPLODE=ALIEN_LIVE-1 6ALIEN_RND_WAVE=22 @BONUS_TIME=10 JMIN_BOMB_HEIGHT=420 1TPLAYER_LIVE=250: PLAYER_EXPLODE=PLAYER_LIVE-1 "^ Base entity field offsets... heENTITY_SIZE=25 reTYPE=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 ;ePLAYER=0:eBULLET=1:eBOMB=2:eALIEN=3:eBONUS=4:eSHIELD=5 & Entity part drawing instructions $dMOVE=1:dDRAW=2:dCOLOUR=3:dEND=0  Bonus Modes 3&bmNONE=0:bmLIFE=1:bmSHIELD=2:bm2SHOT=3:bmCONT=4 70bmMAX=bmCONT:bmTIME=500:bmTIMESHOW=50:bmMSGSHOW=100 : Other global settings... "DBOMB_SPEED=12: BULLET_SPEED=20 )NPLAYER_START_X=600: PLAYER_START_Y=40 0X ------------------------------------------ #b Populate static data for game 0l ------------------------------------------ v & Create alien flight path data...  pathData% 550 FLIGHT_PATH_SIZE=255 FLIGHT_PATH_IX_LHS=220 FLIGHT_PATH_IX_RHS=1000 FLIGHT_PATH_IY=950 1endOfPathData%=_InitFlightPattern(pathData%)  starData% 64 STARS_SIZE=32 )endOfStarDate%=_InitStars(starData%) & Add graphic image definitions...  images% 450 workImage%=images% rocketImage%=workImage% - workImage%=_AddRocketImage(rocketImage%) alien1Image%=workImage% - workImage%=_AddAlien1Image(alien1Image%) *alien2Image%=workImage% -4workImage%=_AddAlien2Image(alien2Image%) >bulletImage%=workImage% -HworkImage%=_AddBulletImage(bulletImage%) RexplosionImage%=workImage% 3\workImage%=_AddExplosionImage(explosionImage%) !fbigExplosionImage%=workImage% 9pworkImage%=_AddBigExplosionImage(bigExplosionImage%) zbonusImage%=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... pRocket%=entities% )rX%=PLAYER_START_X:rY%=PLAYER_START_Y RpNext%=_InitEntity(ePLAYER, 0, pRocket%, rocketImage%, PLAYER_LIVE, rX%, rY%) $ Bonus object... .pBonus%=pNext% A8pNext%=_InitEntity(eBONUS, 0, pBonus%, bonusImage%, 0, 0, 0) B Shield object... LpShield%=pNext% DVpNext%=_InitEntity(eSHIELD, 0, pShield%, shieldImage%, 0, 0, 0) ` Aliens... jMaxAliens%=20 tpAliens%=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 pBombs%=pNext%   B=0 MaxBombs% @pNext%=_InitEntity(eBOMB, 0, pNext%, bulletImage%, 0, 0, 0)  B (pNextBomb%=pBombs% 2pEndBombs%=pNext% <canFire%=0 F: 5 P 0, 328 Z 0, 3 .d Uncomment below to see object mem use... 3n PRINT "images: "; workImage%-images% " bytes" 3x 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  395,640:"SPACE-FIGHTER-X"  0, 2 ' 420,1000: "HI SCORE:";HighScore% $ 480,950: "HI WAVE:";HighWave% ! 380,550:"(Z) (X) (RETURN)" ) Pause then clear keyboard buffer... _Pause(100) *FX 15 & 303,470:"PRESS ANY KEY TO PLAY" ; Init sound (some emulators pause on first sound call)  0,-1,200,1: 1,-1,200,1 "a%= , 1,1,100,50 6: 5 @score%=0 JlastScore%=0 Tlives%=3 ^spawnSize%=4 hwave%=0 rbonusMode%=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... . ----------------------------------------  cycle%=cycle%+1 "_DrawStars(starData%, cycle%) P& score%>HighScore% 570,1000: 0,0: "HI:";HighScore%:HighScore%=score%: S0 score%<>lastScore% 200,1000: 0,0: "SCORE:";lastScore%:lastScore%=score% 0: msgCountDown%>1 460,550: 0,1: msgText$ 5D msgCountDown%>0 msgCountDown%=msgCountDown%-1 2N msgCountDown%=1 460,550: 0,0: msgText$ ^X bonusMode%=bmLIFE 870,1000: 0,0: "LIVES:";lives%:lives%=lives%+1:bonusMode%=bmNONE ]b bonusCountDown%>0 bonusMode%>bmLIFE 0,0: 360,500: bonusCountDown% bmTIMESHOW 7l bonusCountDown%=1 bonusMode%=bmNONE: 1,1,60,10 ;v 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) "pAlienState%=workAlien%+eSTATE ~  ?(pAlienState%)=BONUS_TIME bonusMode%=0 (20)=1 _DropBonus(pBonus%,!(workAlien%+eXCENTRE),!(workAlien%+eYCENTRE)) J ?(pAlienState%)=1 _ClearEntity(workAlien%):?(workAlien%+eSTATE)=0 q  ?(pAlienState%)>0 ?(pAlienState%)=ALIEN_LIVE 4 isAlive% ?(pPlayerState%)=PLAYER_LIVE !(workAlien%+eYPOS)>MIN_BOMB_HEIGHT (1000)<20 pNextBomb%=_DropBomb(workAlien%, pNextBomb%,pBombs%, pEndBombs%) > isAlive% workAlien%=_UpdateAlien(workAlien%, pBullets%, pathData%, explosionImage%) workAlien%=_NextEntity(workAlien%) ,H isAlive% nLiveAliens%=nLiveAliens%+1 R A }\ nLiveAliens%=0 alienSpawn%=0 alienSpawn%=spawnSize%:wave%=wave%+1: spawnSize%0 _StartAlienForWave(pAliens%,wave%):alienSpawn%=alienSpawn%-1 p draw bullets... zworkBullet%=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 : (-74)=0 ?(pPlayerState%)=PLAYER_LIVE canFire%=1 a bonusMode%=bmCONT ?(pPlayerState%)=PLAYER_LIVE canFire%=0 cycle% 5 = 0 canFire%=1  bonusMode%=bm2SHOT canFire%=1 (-74) pNextBullet%=_SetWingBullets(pNextBullet%,pBullets%,pEndBullets%,1,rX%+52,rY%+95):canFire%=0 $ 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 `8 bonusMode%<>bmSHIELD ?(pShield%+eSTATE)=1 ?(pShield%+eSTATE)=0:_ClearEntity(pShield%) %B Wait for screen refresh sync... L *FX19 `V newX%<>rX% ?(pPlayerState%)=PLAYER_LIVE _MoveEntityTo(pRocket%, newX%, rY%):rX%=newX% >` bonusMode%=bmSHIELD _MoveEntityTo(pShield%, rX%, rY%) _j ?(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%  _Pause(250)  0  8 -------------------------------------------------- 3 Functions to handle graphic image definitions 8( -------------------------------------------------- 2 < -------------------------- F Function to add image defn P header information for Z collision detection d -------------------------- Bn _AddImageHeader(address%, centreX%, centreY%, collnRadius%) x ?(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%  ?(address%+1)=x%  ?(address%+2)=y%  =address%+3  :" _AddImagePartScaled(address%, type%, x%, y%, scale) , ?(address%+0)=type% 6 ?(address%+1)=(x%*scale) @ ?(address%+2)=(y%*scale) J =address%+3 T -^ _AddImagePartColour(address%, colour%) h ?(address%+0)=3 r ?(address%+1)=colour% | =address%+2  --------------------------  Functions to add images -------------------------- _AddRocketImage(address%)  rScale=0.8 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) A address%=_AddImagePartScaled(address%, dDRAW, 60, 0, rScale) B address%=_AddImagePartScaled(address%, dDRAW, 40, 20, rScale) B address%=_AddImagePartScaled(address%, dDRAW, 60, 40, rScale) B address%=_AddImagePartScaled(address%, dDRAW, 80, 40, rScale) B address%=_AddImagePartScaled(address%, dDRAW, 80, 80, rScale) C& address%=_AddImagePartScaled(address%, dDRAW, 100, 60, rScale) C0 address%=_AddImagePartScaled(address%, dDRAW, 70, 120, rScale) B: address%=_AddImagePartScaled(address%, dDRAW, 80, 80, rScale) BD address%=_AddImagePartScaled(address%, dDRAW, 60, 80, rScale) CN address%=_AddImagePartScaled(address%, dDRAW, 70, 120, rScale) BX address%=_AddImagePartScaled(address%, dDRAW, 40, 60, rScale) Bb address%=_AddImagePartScaled(address%, dDRAW, 60, 80, rScale) Bl address%=_AddImagePartScaled(address%, dDRAW, 60, 40, rScale) v 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)  ?(address%)=dEND  =address%+1 _AddShieldImage(address%)  rScale=0.8 Q address%=_AddImageHeader(address%, (70*rScale), (60*rScale), (64*rScale)) .* address%=_AddImagePartColour(address%, 1) A4 address%=_AddImagePartScaled(address%, dMOVE, 0, 90, rScale) C> address%=_AddImagePartScaled(address%, dDRAW, 40, 130, rScale) DH address%=_AddImagePartScaled(address%, dDRAW, 100, 130, rScale) CR address%=_AddImagePartScaled(address%, dDRAW, 140, 90, rScale) \ ?(address%)=dEND f =address%+1 p _AddAlien1Image(address%) z aScale=1.4 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) B address%=_AddImagePartScaled(address%, dDRAW, 20, 40, aScale) A address%=_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) B address%=_AddImagePartScaled(address%, dDRAW, 10, 10, aScale) Aaddress%=_AddImagePartScaled(address%, dDRAW, 20, 0, aScale) Aaddress%=_AddImagePartScaled(address%, dDRAW, 30, 0, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 40, 10, aScale) .$address%=_AddImagePartColour(address%, 3) B.address%=_AddImagePartScaled(address%, dMOVE, 15, 20, aScale) B8address%=_AddImagePartScaled(address%, dDRAW, 35, 20, aScale) BBaddress%=_AddImagePartScaled(address%, dDRAW, 35, 30, aScale) BLaddress%=_AddImagePartScaled(address%, dDRAW, 25, 20, aScale) BVaddress%=_AddImagePartScaled(address%, dDRAW, 15, 30, aScale) B`address%=_AddImagePartScaled(address%, dDRAW, 15, 20, aScale) .jaddress%=_AddImagePartColour(address%, 2) Btaddress%=_AddImagePartScaled(address%, dDRAW, 25, 10, aScale) B~address%=_AddImagePartScaled(address%, dDRAW, 35, 20, aScale) ?(address%)=dEND =address%+1  _AddAlien2Image(address%) aScale=1.4 Qaddress%=_AddImageHeader(address%, (25*aScale), (20*aScale), (24*aScale)) .address%=_AddImagePartColour(address%, 1) Baddress%=_AddImagePartScaled(address%, dMOVE, 20, 40, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 30, 40, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 40, 30, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 40, 10, aScale) Aaddress%=_AddImagePartScaled(address%, dDRAW, 30, 0, aScale) Aaddress%=_AddImagePartScaled(address%, dDRAW, 20, 0, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 10, 10, aScale) B address%=_AddImagePartScaled(address%, dDRAW, 10, 30, aScale) Baddress%=_AddImagePartScaled(address%, dDRAW, 20, 40, aScale) .address%=_AddImagePartColour(address%, 3) B(address%=_AddImagePartScaled(address%, dMOVE, 15, 30, aScale) B2address%=_AddImagePartScaled(address%, dDRAW, 25, 25, aScale) B<address%=_AddImagePartScaled(address%, dDRAW, 35, 30, aScale) BFaddress%=_AddImagePartScaled(address%, dDRAW, 35, 20, aScale) BPaddress%=_AddImagePartScaled(address%, dDRAW, 15, 20, aScale) BZaddress%=_AddImagePartScaled(address%, dDRAW, 15, 30, aScale) .daddress%=_AddImagePartColour(address%, 2) Bnaddress%=_AddImagePartScaled(address%, dMOVE, 15, 15, aScale) Bxaddress%=_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%) 0address%=_AddImageHeader(address%, 3, 8, 5) .address%=_AddImagePartColour(address%, 3) 2address%=_AddImagePart(address%, dMOVE, 0, 0) 2address%=_AddImagePart(address%, dDRAW, 6, 0) 3address%=_AddImagePart(address%, dDRAW, 6, 16) 3address%=_AddImagePart(address%, dDRAW, 0, 16) 2"address%=_AddImagePart(address%, dDRAW, 0, 0) ,?(address%)=dEND 6=address%+1 #@ _AddExplosionImage(address%) 3Jaddress%=_AddImageHeader(address%, 25, 25, 25) .Taddress%=_AddImagePartColour(address%, 1) 2^address%=_AddImagePart(address%, dMOVE, 0, 0) 4haddress%=_AddImagePart(address%, dDRAW, 10, 20) 3raddress%=_AddImagePart(address%, dDRAW, 0, 30) 4|address%=_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 & _AddBigExplosionImage(address%) 3address%=_AddImageHeader(address%, 50, 50, 50) .address%=_AddImagePartColour(address%, 2) 2address%=_AddImagePart(address%, dMOVE, 0, 0) 4address%=_AddImagePart(address%, dDRAW, 20, 40) 3&address%=_AddImagePart(address%, dDRAW, 0, 60) 40address%=_AddImagePart(address%, dDRAW, 30, 60) 5:address%=_AddImagePart(address%, dDRAW, 40, 100) 4Daddress%=_AddImagePart(address%, dDRAW, 60, 60) 5Naddress%=_AddImagePart(address%, dDRAW, 100, 80) 4Xaddress%=_AddImagePart(address%, dDRAW, 80, 40) 5baddress%=_AddImagePart(address%, dDRAW, 100, 20) 4laddress%=_AddImagePart(address%, dDRAW, 70, 20) 3vaddress%=_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) 3address%=_AddImagePart(address%, dDRAW, 0, 20) 3address%=_AddImagePart(address%, dDRAW, 20, 0) 4address%=_AddImagePart(address%, dDRAW, 40, 20) 4address%=_AddImagePart(address%, dDRAW, 20, 40) 4address%=_AddImagePart(address%, dDRAW, 10, 10) 4address%=_AddImagePart(address%, dDRAW, 30, 10) 4 address%=_AddImagePart(address%, dDRAW, 20, 40) ?(address%)=dEND  =address%+1 * 4 -------------------------- > Proc to draw image from H data at address in pos x,y R -------------------------- "\ _DrawImage(pImage%, x%, y%) $f Skip the header information... ppImage%=pImage%+3 z 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  -pImage%=_ClearImagePart(pImage%, x%, y%)  pImage%=0  $ . -------------------------- 8 Function to draw part B -------------------------- %L _DrawImagePart(pPart%, x%, y%) &V=_RenderImagePart(pPart%, x%, y%) ` -------------------------- j Function to clear part t -------------------------- &~ _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  ?pPart%=dEND =0 9 Either move or draw to a point in background colour 8  ?(pPart%)=dMOVE ?(pPart%+1)+x%, ?(pPart%+2)+y% 8 ?(pPart%)=dDRAW ?(pPart%+1)+x%, ?(pPart%+2)+y% 5 ?(pPart%)=dCOLOUR 0, ?(pPart%+1): =pPart%+2 ( return next address 2=pPart%+3 < 8F -------------------------------------------------- 'P Functions to handle game entities 8Z -------------------------------------------------- d n -------------------------- x Initialise a new entity  Return next address  -------------------------- H _InitEntity(typeId%, addSize%, pEntity%, pImage%, state%, x%, y%) $ Record basic entity parameters ?pEntity%=typeId% +?(pEntity%+eSIZE)=eENTITY_SIZE+addSize% !(pEntity%+eIMAGE)=pImage% ?(pEntity%+eSTATE)=state% !(pEntity%+eXPOS)=x% !(pEntity%+eYPOS)=y% - Calc offsets for collision detection... /?(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 6=pEntity%+?(pEntity%+eSIZE) @ -------------------------- J Draw or clear an entity T -------------------------- ^ _DrawEntity(pEntity%) Ih_DrawImage(!(pEntity%+eIMAGE), !(pEntity%+eXPOS), !(pEntity%+eYPOS)) r | _ClearEntity(pEntity%)  0,0 J_ClearImage(!(pEntity%+eIMAGE), !(pEntity%+eXPOS), !(pEntity%+eYPOS))    --------------------------  Calc collision range  based on position, width,  height and radius.  --------------------------  _SetCollnCentre(pEntity%) >!(pEntity%+eXCENTRE)=!(pEntity%+eXPOS)+?(pEntity%+eHWIDTH) ?!(pEntity%+eYCENTRE)=!(pEntity%+eYPOS)+?(pEntity%+eHHEIGHT)    --------------------------  Move an entity (relative) & -------------------------- $0 _MoveEntity(pEntity%, dx, dy) (: Only move if state > 0 (is active) 8D ?(pEntity%+eSTATE)=0 =pEntity%+?(pEntity%+eSIZE) N_ClearEntity(pEntity%) XpX%=!(pEntity%+eXPOS)+dx bpY%=!(pEntity%+eYPOS)+dy l pX%>1280 pX%=pX%-1280 v pX%<0 pX%=pX%+1280  pY%>1024 pY%=pY%-1024  pY%<0 pY%=pY%+1024 !(pEntity%+eXPOS)=pX% !(pEntity%+eYPOS)=pY% _SetCollnCentre(pEntity%) _DrawEntity(pEntity%) =pEntity%+?(pEntity%+eSIZE)   --------------------------  Move an entity (absolute)  -------------------------- & _MoveEntityTo(pEntity%, x%, y%) ( Only move if state > 0 (is active)  ?(pEntity%+eSTATE)=0  _ClearEntity(pEntity%) !(pEntity%+eXPOS)=x%  !(pEntity%+eYPOS)=y% *_SetCollnCentre(pEntity%) 4_DrawEntity(pEntity%) > H R -------------------------- \ Get pointer to next entity f -------------------------- p _NextEntity(pEntity%) z=pEntity%+?(pEntity%+eSIZE)   --------------------------  Collision Detection " lhs, rhs, top, bot collision % range pre calc'd on entity move  -------------------------- 2 _IsCollision(pEntity1%, pEntity2%, radius%) , Only check if both entities are active 7 ?(pEntity1%+eSTATE)=0 ?(pEntity2%+eSTATE)=0 = 0 5dX=(!(pEntity1%+eXCENTRE)-!(pEntity2%+eXCENTRE)) 5dY=(!(pEntity1%+eYCENTRE)-!(pEntity2%+eYCENTRE))  dX1000 !(pBullet%+eYPOS)<24 ?(pState%)=3 t=pBullet%+?(pBullet%+eSIZE) 8~ -------------------------------------------------- C _SetBullet(pBullet%, pStartBMem%, pEndBMem%, state%, x%, y%) ?(pBullet%+eSTATE)=state% !(pBullet%+eXPOS)=x% !(pBullet%+eYPOS)=y% _SetCollnCentre(pBullet%)  state%=1 2,2,100,1 ;(pBullet%+?(pBullet%+eSIZE)>=pEndBMem%) =pStartBMem% =pBullet%+?(pBullet%+eSIZE) 8 -------------------------------------------------- H _SetWingBullets(pBullet%, pStartBMem%, pEndBMem%, state%, x%, y%) NpNext%=_SetBullet(pBullet%, pStartBMem%, pEndBMem%, state%, x%-50, y%-50) F=_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% 2=endAddress% 8< -------------------------------------------------- #F _AlienHit(pAlien%, pBullet%) P_ClearEntity(pAlien%) #Z?(pAlien%+eSTATE)=ALIEN_EXPLODE &d!(pAlien%+eIMAGE)=pExplosionImage% n?(pBullets%+eSTATE)=3 x 0,3,75,1 score%=score%+10  8 -------------------------------------------------- A _CheckAlienCollision(pAlien%, pBullets%, pExplosionImage%) 1 If alien is exploding (or dead) then ignore #cRadius%=?(!(pAlien%+eIMAGE)+2)  ?(pAlien%+eSTATE)<20  B=0 MaxBullets% m ?(pBullets%+eSTATE)>0 _IsCollision(workAlien%, pBullets%, cRadius%) _AlienHit(pAlien%, pBullets%): *pBullets%=pBullets%+?(pBullets%+eSIZE)  B  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) 6 B @=0 8J -------------------------------------------------- GT _UpdateAlien(pAlien%, pBullets%, pFlightPath%, pExplosionImage%) >^_CheckAlienCollision(pAlien%, pBullets%, explosionImage%) &hfpi%=?(pAlien%+eFLIGHT_PATH_INDEX) rfpi%=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) 'dX=?(pLookUp%): dX>128 dX=128-dX - ?(pAlien%+eFLIGHT_PATH_SIDE)=0 dX=-dX )dY=?(pLookUp%+1): dY>128 dY=128-dY "=_MoveEntity(pAlien%, dX, dY) 8 -------------------------------------------------- ; _DropBomb(pAlien%,pNextBomb%,pStartBMem%, pEndBMem%) c=_SetBullet(pNextBomb%,pStartBMem%, pEndBMem%,2,!(workAlien%+eXCENTRE),!(workAlien%+eYCENTRE)) 8 -------------------------------------------------- . _KillPlayer(pPlayer%, pExplosionImage%) _ClearEntity(pPlayer%) ( ?(pPlayer%+eSTATE) alienType%=1 pAlienImage%=alien1Image% pAlienImage%=alien2Image% JH alienType%=1 startX=FLIGHT_PATH_IX_RHS startX=FLIGHT_PATH_IX_LHS R A=0 MaxAliens% \ ?(pNext%+eSTATE)=0 pNext%=_InitAlien(eALIEN, pNext%, pAlienImage%, ALIEN_LIVE, startX, FLIGHT_PATH_IY, FLIGHT_PATH_SIZE, alienType%): fpNext%=_NextEntity(pNext%) p A z 8 --------------------------------------------------  Bonus functions 8 -------------------------------------------------- " _DropBonus(pBonus%, x%, y%) & ?(pBonus%+eSTATE)>0 y%<400 IpNext%=_InitEntity(eBONUS, 0, pBonus%, !(pBonus%+eIMAGE), 1, x%, y%)   & _UpdateBonus(pBonus%, pPlayer%)  ?(pBonus%+eSTATE)=0 H !(pBonus%+eYPOS)<10 ?(pBonus%+eSTATE)=0:_ClearEntity(pBonus%): %pNext%=_MoveEntity(pBonus%,0,-3) &radius%=25+?(!(pPlayer%+eIMAGE)+2) ( ?(pPlayer%+eSTATE)bmLIFE bonusCountDown%=bmTIME 88 bonusMode%=bmLIFE _ShowMessage(" EXTRA LIFE!") :B bonusMode%=bmSHIELD _ShowMessage(" SHIELDS UP!") 9L bonusMode%=bm2SHOT _ShowMessage(" DOUBLE SHOT!") 7V bonusMode%=bmCONT _ShowMessage(" SUPER FIRE!") .`?(pBonus%+eSTATE)=0:_ClearEntity(pBonus%) j 8t -------------------------------------------------- ~ Star background functions 8 --------------------------------------------------  _InitStars(address%)  N=1 STARS_SIZE ?(address%)=(255) ?(address%+1)=(255) address%=address%+2  N =address%  $ _DrawStars(address%, offset%) offset%=offset% 1024  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 02 sY%>150 0,(N+offset%) 8: 69,sX%,sY% <address%=address%+2 F N P 8Z -------------------------------------------------- d Other useful procedures 8n -------------------------------------------------- x _ShowMessage(message$)  msgCountDown%>0 msgCountDown%=bmMSGSHOW msgText$=message$   _Pause(cycles%)  C=1 cycles% *FX19  C   _ShowError  0 *FX15 ' "-------------------------------" ' "PIXEL FANDANGO SPACE FIGHTER X" " " www.PixelFandango.com" ' "-------------------------------" ": " at line "; ,