rem -------------------- rem Asteroid Escape rem Steve Engelhardt rem 10/27/2016 rem A 4k Game for bB rem -------------------- rem Set pfres rem --------- rem Set playfield resolution to 8 rather than the default of 11. It frees up 16 extra variables (var0-var15) const pfres=8 rem Description rem ----------- rem Caught in an endless asteroid belt, it's your mission to ram and destroy the escaping cargo ship rem without crashing into an asteroid yourself. Your heavily shielded fighter ship can easily take out the rem cargo ship. You gain a point each time you destoy the ship. If you're destroyed, the game is over. rem rem You fly on the outskirts of the asteroid belt, either above or below it. Your momentum requires an rem angled 45 degree attack, push up or down on the joystick to move to the other side of the asteroid belt. rem When on the outskirts, you can thrust forward or backward by pushing left or right. You can also turn on rem the afterburners by pushing down when youre on the bottom, and up when you're on top to fly faster. rem rem The game will continue as long as you can survive. rem Ideas rem ----- rem X add starfield effect with one of the missiles rem X add explosion for hitting block in the middle rem X add explosion for ship when it runs off the left side or hits a barrier rem gradual speed up of asteroids and cargo ship, change background color on level up? rem savekey support? rem X add audio rem X animate the player ship rem declare variables rem ----------------- dim High_Score01=a dim High_Score02=b dim High_Score03=c dim Save_Score01=d dim Save_Score02=e dim Save_Score03=f dim explodecounter = g dim counter = h dim linespeedcounter = i dim p1x = j dim p1y = k dim p0x = l dim p0y = m dim ts_active=n dim gameoverflag=o dim blockx=p dim blocky=q dim scrollcounter=r dim shipexplode=s dim explode=t dim enemyship=u dim scback=v dim moveup=w dim movedown=x dim barrier1=y dim placeblock1=z dim sc1=score dim sc2=score+1 dim sc3=score+2 dim starrand1=var0 dim starrand2=var1 dim starrand3=var2 dim starrand4=var3 dim starplacement=var4 dim starposition1=var5 dim starposition2=var6 dim starposition3=var7 dim starposition4=var8 dim ballmoveflagtop=var9 dim ballmoveflagbottom=var10 dim animate1=var11 dim placeblock2=var12 dim placeblock3=var13 dim audio1=var14 dim audio2=var15 rem Have var0-var15 due to pfres being set to 8 rem reset high score to 0 rem --------------------- High_Score01=0 High_Score02=0 High_Score03=0 rem jump to titlescreen rem ------------------- goto titlescreen init rem this is where the titlescreen returns to when you start the game rem initial sprite for player ship player0: %01000000 %00111100 %01111111 %00111100 %01000000 end rem initial sprite for cargo ship player1: %11110000 %01001000 %11111100 %01111110 %11111111 %01111111 %11111111 %01111110 %11111100 %01001000 %11110000 end rem initialize variables rem -------------------- moveup=0 :rem Set to zero when ship is not moving through the asteroid field movedown=0 :rem Set to zero when ship is not moving through the asteroid field COLUPF=$30 :rem Set playfield color score=000000 :rem Reset score to zero pfclear %00000000 :rem Clear the playfield counter=15 :rem Seed the counter variable with 15 linespeedcounter=0 :rem Reset asteroid speed counter const pfscore=1 :rem Activate pfscore pfscore1=0 :rem set to zero pfscore2=0 :rem set to zero barrier1=80 :rem Initial Y location of ball barrier explode=0 :rem Explode variable triggers explosion animation when it's set to 1 p0x=25:p0y=80 :rem Initial location of player's ship blockx=25:blocky=80 :rem Initial location of player's ship enemyship=39 :rem Initial Y location of cargo ship audio1=1 :rem Seed audio counter with a value of 1 rem Create first set of asteroids rem ----------------------------- gosub makeasteroids main rem Audio for player ship rem --------------------- if joy0up then AUDF0=20:AUDC0=8:AUDV0=4 if joy0down then AUDF0=20:AUDC0=8:AUDV0=4 if joy0left then AUDF0=20:AUDC0=8:AUDV0=4 if joy0right then AUDF0=20:AUDC0=8:AUDV0=4 rem Counter for the audio when ship is moving up or down rem ---------------------------------------------------- audio1=audio1+1 if audio1>31 then audio1=1 rem Background rumble/up-down ship movement sound rem --------------------------------------------- if moveup=0 || movedown=0 then AUDF1=31:AUDC1=8:AUDV1=2 if moveup=1 || movedown=1 then AUDF1=audio1:AUDC1=12:AUDV1=7 rem Counter for player ship animation rem --------------------------------- animate1=animate1+1 if animate1>30 then animate1=0 rem Change ship sprite when moving up or down rem ----------------------------------------- if movedown=1 then player0: %00000001 %00001110 %00111111 %11111100 %11110000 end if moveup=1 then player0: %11110000 %11111100 %00111111 %00001110 %00000001 end rem Don't animate the ship if you're moving up or down through the asteroid field rem ----------------------------------------------------------------------------- if moveup=1 || movedown=1 then goto skipanim rem Animate player ship rem ------------------- if animate1=10 then player0: %00100000 %00111100 %00111111 %00111100 %00100000 end if animate1=20 then player0: %10100000 %10111100 %10111111 %10111100 %10100000 end if animate1=30 then player0: %01100000 %01111100 %01111111 %01111100 %01100000 end skipanim rem Sound when cargo ship explodes rem ---------------------------------- if collision(player0,player1) then animate1=22:AUDF0=31:AUDC0=8:AUDV0=12 rem Scroll counter rem -------------- scrollcounter=scrollcounter+1 if scrollcounter>250 then scrollcounter=0 if scrollcounter=250 then gosub makeasteroids: rem makeasteroids creates new random asteroid field rem Create ball barrier rem ------------------- rem the ball bounces up and down at the far right side of the screen rem hitting it results in death ballheight=8 ballx=158:bally=barrier1 if bally>79 then ballmoveflagbottom=1:ballmoveflagtop=0 if bally<8 then ballmoveflagbottom=0:ballmoveflagtop=1 if ballmoveflagbottom=1 then barrier1=barrier1-1 if ballmoveflagtop=1 then barrier1=barrier1+1 rem Set cargo ship sprite to Quad width rem ----------------------------------- NUSIZ1=$07 rem Move Cargo ship up and down rem --------------------------- shipmove if counter<160 then goto skipship enemyship=(rand&63)+35 if enemyship<35 then goto shipmove if enemyship>59 then goto shipmove skipship rem if enemyship>55 then enemyship=39 rem move player1, which is the barrier you break through p1x=counter:p1y=enemyship rem p1x=p1x-1:p1y=47 rem reset the game rem -------------- if switchreset then reboot rem set the color bar behind the score rem ---------------------------------- scback=$42 rem set the playfield score color rem ----------------------------- pfscorecolor=$18 rem set colors rem ---------- rem Colors for player0/player1/background/playfield COLUP0=$08:COLUP1=$08:COLUBK=0:COLUPF=$30 rem set player variables rem -------------------- player0x=p0x:player0y=p0y player1x=p1x:player1y=p1y rem set score color to black rem ------------------------ scorecolor=0 rem this sets the ball to 8 pixels wide rem ----------------------------------- NUSIZ0=$10 rem move the player ship rem -------------------- rem you can't change the direction of the ship once you're rem committed to going up or down if moveup=1 || movedown=1 then goto skip1 if joy0up then moveup=1 if joy0down then movedown=1 skip1 rem Speed up player ship if you push left or right rem ---------------------------------------------- if joy0left then blockx=blockx-1 if joy0right then blockx=blockx+1 rem move ship up or down rem -------------------- rem Once you start your diagonal path up or down, you cannot change directions mid-flight if moveup=1 && blocky<79 then blockx=blockx+2:blocky=blocky-2 if movedown=1 && blocky>14 then blockx=blockx+2:blocky=blocky+2 rem plot player ship onscreen rem ------------------------- p0x=blockx p0y=blocky rem Faster Ship when on the outskirts of the asteroid belt rem ------------------------------------------------------ rem push up when you're at the top or down when you're at the bottom rem to speed up your ship. It also increases the speed of the stars. if blocky>78 then blocky=78:var5=var5-2:var7=var7-2 if blocky<15 then blocky=15:var5=var5-2:var7=var7-2 rem once you reach the top or bottom, movement flags are reset rem ---------------------------------------------------------- if blocky=78 then moveup=0:movedown=0 if blocky=15 then moveup=0:movedown=0 rem You cannot move off the left side of the screen rem ----------------------------------------------- if blockx<1 then blockx=1 rem if you scroll off the right side of the screen, you reappear on the left side. rem ------------------------------------------------------------------------------ if blockx>155 then blockx=20 rem pressing the fire button increases your speed to the right rem ---------------------------------------------------------- if joy0fire then blockx=blockx+1 rem starfield movement rem ------------------ rem create four variable starting locations for the missiles that make up the moving starfield starrand1 = (rand&127)+10 starrand2 = (rand&127)+10 starrand3 = (rand&127)+10 starrand4 = (rand&127)+10 rem randomize star starting locations based on counter rem -------------------------------------------------- if starplacement=1 then starposition1=starrand1 : starposition2=starrand4 : starposition3=starrand3: starposition4=starrand4 if starplacement=7 then starposition1=starrand2 : starposition2=starrand3 : starposition3=starrand2: starposition4=starrand1 if starplacement=14 then starposition1=starrand3 : starposition2=starrand2 : starposition3=starrand1: starposition4=starrand2 if starplacement=21 then starposition1=starrand4 : starposition2=starrand1 : starposition3=starrand4: starposition4=starrand3 rem counter for changing location of stars rem -------------------------------------- starplacement=starplacement+1 if starplacement>21 then starplacement=1 rem place stars on screen rem --------------------- missile1x=starposition3:missile1y=starposition4+5 missile1x=starposition1:missile1y=starposition2-8 missile0x=starposition1+5:missile0y=starposition2 missile0x=starposition3-5:missile0y=starposition4 rem move starts from right to left onscreen rem --------------------------------------- starposition1=starposition1-3:starposition3=starposition3-3 rem end star movement drawscreen rem Counter rem ------- counter=counter+1 if counter>160 then counter=1 rem Asteroid speed counter rem ------------------ linespeedcounter=linespeedcounter+1 if linespeedcounter>4 then linespeedcounter=0 rem Scroll left based on line speed counter rem --------------------------------------- if linespeedcounter=0 then pfscroll left: blockx=blockx-1 rem Set ball to one pixel width w/normal playfield rem ---------------------------------------------- CTRLPF=$11 rem Collision Detection rem ------------------- rem player ship hits the cargo ship if collision(player0,player1) then explodecounter=0:explode=1 rem player ship hits an asteroid (the playfield) if collision(player0,playfield) then pfclear %00000000:goto gameover rem player ship hits the moving barrier on the right side (ball) if collision(player0,ball) then pfclear %00000000:goto gameover rem Explosion counter for Cargo ship rem -------------------------------- explodecounter=explodecounter+1 if explodecounter>40 then explodecounter=0:explode=0:gosub resetcargoship if explode=0 then goto main if explodecounter=5 then player1: %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 end if explodecounter=10 then player1: %00000000 %00000000 %00010000 %00111000 %00111000 %00010000 %00000000 %00000000 end if explodecounter=15 then player1: %00000000 %00010000 %01000100 %00001000 %10100000 %01000100 %00010000 %00000000 end if explodecounter=20 then player1: %00001000 %01000000 %00000001 %00010100 %10101000 %00000100 %01000001 %00001000 end if explodecounter=25 then player1: %10001000 %00000001 %00010100 %00000001 %10100000 %00010100 %00000001 %10010100 end if explodecounter=30 then player1: %10001001 %01010100 %00000010 %01000001 %10000010 %00100000 %01001010 %10010001 end if explodecounter=35 then player1: %01010010 %00001000 %00000001 %10000010 %00000000 %01000000 %00000001 %01001000 end if explodecounter=40 then score=score+1:player1: %01000010 %00000001 %10000000 %00000000 %00000000 %00000000 %00000000 %10000001 end goto main makeasteroids rem Clear the asteroids (playfield) rem ------------------------------- pfclear %00000000 rem Create random locations for asteroids rem ------------------------------------- placeblock1 = (rand&31)-4 placeblock2 = (rand&31)-4 placeblock3 = (rand&31)-4 rem Use random locations to plot asteroids rem -------------------------------------- pfhline placeblock1 3 placeblock1+4 on pfhline placeblock2 4 placeblock2+4 on pfhline placeblock3 2 placeblock3+4 on return gameover rem reset screen items after death rem ------------------------------ NUSIZ1=$07 player1: %00000000 end missile0x=0:missile0y=0 missile1x=0:missile1y=0 AUDV0=0:AUDV1=0 gameover2 drawscreen rem Play the explosion sound during the explosion animation rem ------------------------------------------------------- if gameoverflag=0 then AUDF0=31:AUDC0=counter:AUDV0=8 else AUDV0=0 ballx=0:bally=0 COLUP0=$08:COLUP1=$08:COLUPF=$30:COLUBK=$00 counter=counter+1 if counter>31 then counter=0 explodecounter=explodecounter+1 if switchreset then reboot if explodecounter>44 then explodecounter=0:gameoverflag=1 if joy0fire then gameoverflag=0:goto startup if gameoverflag=1 then goto gameover2 if explodecounter=5 then player0: %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 end if explodecounter=10 then player0: %00000000 %00000000 %00010000 %00111000 %00111000 %00010000 %00000000 %00000000 end if explodecounter=15 then player0: %00000000 %00010000 %01000100 %00001000 %10100000 %01000100 %00010000 %00000000 end if explodecounter=20 then player0: %00001000 %01000000 %00000001 %00010100 %10101000 %00000100 %01000001 %00001000 end if explodecounter=25 then player0: %10001000 %00000001 %00010100 %00000001 %10100000 %00010100 %00000001 %10010100 end if explodecounter=30 then player0: %10001001 %01010100 %00000010 %01000001 %10000010 %00100000 %01001010 %10010001 end if explodecounter=35 then player0: %01010010 %00001000 %00000001 %10000010 %00000000 %01000000 %00000001 %01001000 end if explodecounter=40 then player0: %01000010 %00000001 %10000000 %00000000 %00000000 %00000000 %00000000 %10000001 end if explodecounter>41 then player0: %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 end drawscreen goto gameover2 startup if !joy0fire then gosub HighScoreCalc:goto titlescreen drawscreen goto startup resetcargoship AUDV0=0 player1: %11110000 %01001000 %11111100 %01111110 %11111111 %01111111 %11111111 %01111110 %11111100 %01001000 %11110000 end return titlescreen AUDV0=0 ballx=25:bally=90 pfclear %00000000 pfscore1=0 pfscore2=0 counter=200 k=1 ts_active=1 missile0x=0:missile1x=0:missile0y=0:missile1y=0 player0: %00000000 end player1: %00000000 end titlescreen2 ballheight=90 ballx=j:bally=90 if ballx=16 then k=1 if ballx=150 then k=0 if k=1 then j=j+1 if k=0 then j=j-1 PF0=counter NUSIZ0=$05:NUSIZ1=$05 counter=counter+1 linespeedcounter=linespeedcounter+1 if linespeedcounter>6 then linespeedcounter=0 player0x=84:player0y=78 player1x=68:player1y=78 COLUP0=28:COLUP1=28 COLUBK=0:COLUPF=$86 scback=$C6 pfscorecolor=$18 drawscreen if joy0fire then goto startgame rem color behind "press fire to start" pfhline 13 5 20 on pfhline 13 6 20 on rem stars var0 = (rand&127)+18 var1 = (rand&127)+18 var2 = (rand&127)+18 var3 = (rand&127)+18 if var4=1 then var5=var0 : var6=var3 : var7=var2: var8=var3 if var4=7 then var5=var1 : var6=var2 : var7=var1: var8=var0 if var4=14 then var5=var2 : var6=var1 : var7=var0: var8=var1 if var4=21 then var5=var3 : var6=var0 : var7=var3: var8=var2 var4=var4+1 if var4>21 then var4=1 missile1x=var7:missile1y=var8+5 missile1x=var5:missile1y=var6-8 missile0x=var5+5:missile0y=var6 missile0x=var7-5:missile0y=var8 var5=var5-5:var7=var7-5 player0: %10101110 %11001000 %11101100 %10101000 %11101110 %00000000 %11111111 %00000000 %11011011 %10001001 %11011011 %10010010 %11011011 %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 %01111111 %01000000 %01000000 %01111000 %01000000 %01000000 %01111100 %00000000 %01000000 %01000000 %01111100 %01000100 %01111100 %00000000 %01000100 %01000100 %01111100 %01000100 %00111000 %00000000 %00111100 %01000000 %01000000 %01000000 %01000000 %00111100 %00000000 %01111100 %00000100 %01111100 %01000000 %01111100 %00000000 %01111100 %01000000 %01000000 %01111000 %01000000 %01000000 %01111111 %00000000 %00000000 %00000000 %00000000 end player1: %01001110 %01000100 %01100100 %01000100 %01101110 %00000000 %11111111 %00000000 %10001010 %10001010 %11101100 %10101010 %11101110 %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 %01111000 %01000100 %01000100 %01000100 %01111000 %00000000 %01111100 %00010000 %00010000 %00010000 %01111100 %00000000 %00111000 %01000100 %01000100 %01000100 %00111000 %00000000 %01000100 %01001000 %01111000 %01000100 %01111000 %00000000 %01111100 %01000000 %01110000 %01000000 %01111100 %00000000 %00010000 %00010000 %00010000 %00010000 %01111100 %00000000 %01111100 %00000100 %01111100 %01000000 %01111100 %00000000 %01000100 %01000100 %01111100 %01000100 %00111000 end sc1=High_Score01:sc2=High_Score02:sc3=High_Score03 goto titlescreen2 startgame player0: %00000000 end player1: %00000000 end COLUBK=0:COLUPF=0 if !joy0fire then ts_active=0:goto init drawscreen goto startgame HighScoreCalc Save_Score01=sc1 Save_Score02=sc2 Save_Score03=sc3 rem Checks for a new high score. if sc1 > High_Score01 then goto New_High_Score if sc1 < High_Score01 then goto Skip_High_Score rem First byte equal. Do the next test. if sc2 > High_Score02 then goto New_High_Score if sc2 < High_Score02 then goto Skip_High_Score rem Second byte equal. Do the next test. if sc3 > High_Score03 then goto New_High_Score if sc3 < High_Score03 then goto Skip_High_Score rem All bytes equal. Current score is the same as the high score. goto Skip_High_Score New_High_Score rem Save new high score. High_Score01 = sc1 : High_Score02 = sc2 : High_Score03 = sc3 Skip_High_Score return asm minikernel sta WSYNC lda scback sta COLUBK rts end rem NUSIZ rem m = 0 1 pixel wide missile. rem m = 1 2 pixel wide missile. rem m = 2 4 pixel wide missile. rem m = 3 8 pixel wide missile. rem p = 0 1 copy of player and missile. x0 rem p = 1 2 close-spaced copies of player and missile. x1 rem p = 2 2 medium-spaced copies of player and missile. x2 rem p = 3 3 close-spaced copies of player and missile. x3 rem p = 4 2 wide-spaced copies of player and missile. x4 rem p = 0 5 Double-sized player. x5 rem p = 6 3 medium-spaced copies of player and missile. x6 rem p = 0 7 Quad-sized player. x7 rem CTRLPF rem b = 0 1 pixel wide ball. rem b = 1 2 pixel wide ball. rem b = 2 4 pixel wide ball. rem b = 3 8 pixel wide ball. rem p = 1 Normal bB playfield. rem p = 3 Split color playfield where left half of PF gets player0 color, rem right half gets player1 color. rem p = 5 Players move behind playfield. rem p = 7 Both split color and players behind playfield.