rem Snake Bite rem copyright Marc Gale (Xalthorn) 2001 rem rem A fun little game for one or two players gosub initialise gosub main_loop exit label main_loop quitgame=0 repeat gosub title_screen gosub main_menu until (quitgame=1) return label title_screen setdispbuf d setdrawbuf d clear window gosub draw_title setrgb 1,200,100,200 text 50,50,"Snake Bite - Copyright Marc Gale (Xalthorn) 2001","lb" gosub waitfornoinput setrgb 1,150,150,255 for a=1 to titlelines if title$(a)<>"" then for b=1 to len(title$(a)) text b*12+50,a*18+70,mid$(title$(a),b,1) buttons=or(peek("port1"),peek("port2")) if buttons=0 then wait 0.1 fi next b fi next a setrgb 1,255,255,255 text sw/2,sh-20,"Press the X button for the main menu","cc" repeat buttons=or(peek("port1"),peek("port2")) until (and(buttons,16384)=16384) return label help_screen setdispbuf d setdrawbuf d clear window gosub draw_title setrgb 1,200,100,200 text 50,50,"Snake Bite Help Screen","lb" gosub waitfornoinput setrgb 1,150,150,255 for a=1 to helplines if help$(a)<>"" then for b=1 to len(help$(a)) text b*12+50,a*18+70,mid$(help$(a),b,1) buttons=or(peek("port1"),peek("port2")) if buttons=0 then wait 0.1 fi next b fi next a setrgb 1,255,255,255 text sw/2,sh-20,"Press the X button to return to the main menu","cc" repeat buttons=or(peek("port1"),peek("port2")) until (and(buttons,16384)=16384) return label draw_title setrgb 1,0,0,100 setrgb 2,0,0,0 setrgb 3,0,0,100 gtriangle 0,0 to 0,sh to sw,0 setrgb 1,0,0,0 gtriangle 0,sh to sw,sh to sw,0 setrgb 1,255,255,255 line 50,60 to 600,60 return label main_menu option=0 repeat gosub waitfornoinput cursor=1 setdispbuf d setdrawbuf d gosub draw_title setrgb 1,200,100,200 text 50,50,"Snake Bite Main Menu","lb" for a=1 to numoptions draw_option(a,0) next a setrgb 1,255,255,255 text sw/2,500,"Move up and down to highlight an option and press X","cc" draw_option(cursor,1) repeat buttons=or(peek("port1"),peek("port2")) if and(buttons,16)=16 and cursor>1 then draw_option(cursor,0) cursor=cursor-1 draw_option(cursor,1) gosub waitfornoinput fi if and(buttons,64)=64 and cursor1 then draw_choice(cursor,0) cursor=cursor-1 draw_choice(cursor,1) gosub waitfornoinput fi if and(buttons,64)=64 and cursor1 then snake(1,12)=snake(1,12)-1 draw_choice_setting(cursor) fi if cursor=4 and snake(1,13)>1 then snake(1,13)=snake(1,13)-1 draw_choice_setting(cursor) fi if cursor=5 and snake(2,8)=2 then snake(2,8)=1 draw_choice_setting(cursor) fi if cursor=6 and snake(2,14)=2 then snake(2,14)=1 draw_choice_setting(cursor) fi if cursor=7 and snake(2,12)>1 then snake(2,12)=snake(2,12)-1 draw_choice_setting(cursor) fi if cursor=8 and snake(2,13)>1 then snake(2,13)=snake(2,13)-1 draw_choice_setting(cursor) fi gosub waitfornoinput fi if and(buttons,32)=32 then if cursor=1 and snake(1,8)=1 then snake(1,8)=2 draw_choice_setting(cursor) fi if cursor=2 and snake(1,14)=1 then snake(1,14)=2 draw_choice_setting(cursor) fi if cursor=3 and snake(1,12)<10 then snake(1,12)=snake(1,12)+1 draw_choice_setting(cursor) fi if cursor=4 and snake(1,13)<10 then snake(1,13)=snake(1,13)+1 draw_choice_setting(cursor) fi if cursor=5 and snake(2,8)=1 then snake(2,8)=2 draw_choice_setting(cursor) fi if cursor=6 and snake(2,14)=1 then snake(2,14)=2 draw_choice_setting(cursor) fi if cursor=7 and snake(2,12)<10 then snake(2,12)=snake(2,12)+1 draw_choice_setting(cursor) fi if cursor=8 and snake(2,13)<10 then snake(2,13)=snake(2,13)+1 draw_choice_setting(cursor) fi gosub waitfornoinput fi until (and(buttons,16384)=16384 and cursor=numchoices) choice=cursor until (choice=numchoices) return label waitfornoinput repeat padinput=or(peek("port1"),peek("port2")) until (padinput=0) return sub draw_option(a,s) if s=1 then setrgb 1,100,100,200 else setrgb 1,100,100,100 fi fill rectangle 200,a*100 to 400,a*100+50 if s=1 then setrgb 1,80,80,130 else setrgb 1,80,80,80 fi line 200,a*100 to 200,a*100+50 line 200,a*100+50 to 400,a*100+50 if s=1 then setrgb 1,200,200,250 else setrgb 1,200,200,200 fi line 200,a*100 to 400,a*100 line 400,a*100 to 400,a*100+50 setrgb 1,255,255,255 text 300,a*100+28,options$(a),"cc" end sub sub draw_choice(a,s) if s=1 then setrgb 1,100,100,200 else setrgb 1,100,100,100 fi fill rectangle 80,a*40+50 to 350,a*40+80 if s=1 then setrgb 1,80,80,130 else setrgb 1,80,80,80 fi line 80,a*40+50 to 80,a*40+80 line 80,a*40+80 to 350,a*40+80 if s=1 then setrgb 1,200,200,250 else setrgb 1,200,200,200 fi line 80,a*40+50 to 350,a*40+50 line 350,a*40+50 to 350,a*40+80 setrgb 1,255,255,255 text 220,a*40+70,choices$(a),"cc" setrgb 1,0,0,0 fill rectangle 0,480 to sw,sh setrgb 1,255,255,255 text sw/2,500,hints$(a),"cc" end sub sub draw_choice_setting(a) if a=1 or a=5 then if (a=1 and snake(1,8)=1) or (a=5 and snake(2,8)=1) then setrgb 1,100,100,200 else setrgb 1,100,100,100 fi fill rectangle 370,a*40+50 to 470,a*40+80 setrgb 1,0,0,0 rectangle 370,a*40+50 to 470,a*40+80 setrgb 1,255,255,255 text 420,a*40+70,"Human","cc" if (a=1 and snake(1,8)=2) or (a=5 and snake(2,8)=2) then setrgb 1,100,100,200 else setrgb 1,100,100,100 fi fill rectangle 470,a*40+50 to 570,a*40+80 setrgb 1,0,0,0 rectangle 470,a*40+50 to 570,a*40+80 setrgb 1,255,255,255 text 520,a*40+70,"Computer","cc" fi if a=2 or a=6 then if (a=2 and snake(1,14)=1) or (a=6 and snake(2,14)=1) then setrgb 1,100,100,200 else setrgb 1,100,100,100 fi fill rectangle 370,a*40+50 to 470,a*40+80 setrgb 1,0,0,0 rectangle 370,a*40+50 to 470,a*40+80 setrgb 1,255,255,255 text 420,a*40+70,"Turning","cc" if (a=2 and snake(1,14)=2) or (a=6 and snake(2,14)=2) then setrgb 1,100,100,200 else setrgb 1,100,100,100 fi fill rectangle 470,a*40+50 to 570,a*40+80 setrgb 1,0,0,0 rectangle 470,a*40+50 to 570,a*40+80 setrgb 1,255,255,255 text 520,a*40+70,"Cardinal","cc" fi if a=3 or a=7 then for b=1 to 10 if (a=3 and b=snake(1,12)) or (a=7 and b=snake(2,12)) then setrgb 1,100,100,200 else setrgb 1,100,100,100 fi fill rectangle 350+b*20,a*40+50 to 370+b*20,a*40+80 setrgb 1,0,0,0 rectangle 350+b*20,a*40+50 to 370+b*20,a*40+80 next b fi if a=4 or a=8 then for b=1 to 10 if (a=4 and b=snake(1,13)) or (a=8 and b=snake(2,13)) then setrgb 1,100,100,200 else setrgb 1,100,100,100 fi fill rectangle 350+b*20,a*40+50 to 370+b*20,a*40+80 setrgb 1,0,0,0 rectangle 350+b*20,a*40+50 to 370+b*20,a*40+80 next b fi end sub label game_loop quit=0 setrgb 0,50,100,50 gosub reset_players gosub countdown repeat gosub flip_screen clear window gosub draw_goodies gosub draw_parts rem human player if snake(1,8)=1 then buttons=peek("port1") player=1 gosub process_input fi rem computer player if snake(1,8)=2 then player=1 if snake(player,9)=0 then gosub acquire_target else gosub aim fi fi rem human player if snake(2,8)=1 then buttons=peek("port2") player=2 gosub process_input fi rem computer player if snake(2,8)=2 then player=2 if snake(player,9)=0 then gosub acquire_target else gosub aim fi fi gosub move_parts gosub collide gosub new_goodies buttons=or(peek("port1"),peek("port2")) if and(buttons,8)=8 then gosub quittest if quit=1 then return fi fi win=0 gosub check_win until (win>0) gosub win_screen return label countdown setdispbuf d setdrawbuf d for a=3 to 1 step -1 clear window gosub draw_goodies gosub draw_parts setrgb 1,255,255,255 text sw/2,sh/2-20,"Get Ready","cc" text sw/2,sh/2,str$(a),"cc" wait 1 next a return label quittest setdispbuf d setdrawbuf d gosub waitfornoinput setrgb 1,100,100,100 fill rectangle 220,200 to 420,300 setrgb 1,0,0,0 rectangle 220,200 to 420,300 setrgb 1,255,255,255 text 320,220,"Quit Game?","cc" gosub draw_yesno repeat buttons=or(peek("port1"),peek("port2")) if (and(buttons,128)=128) and quit=0 then quit=1 gosub draw_yesno fi if (and(buttons,32)=32) and quit=1 then quit=0 gosub draw_yesno fi until (and(buttons,16384)=16384) return label draw_yesno if quit=1 then setrgb 1,100,100,200 else setrgb 1,100,100,100 fi fill rectangle 240,240 to 300,280 setrgb 1,0,0,0 rectangle 240,240 to 300,280 setrgb 1,255,255,255 text 270,260,"Yes","cc" if quit=0 then setrgb 1,100,100,200 else setrgb 1,100,100,100 fi fill rectangle 340,240 to 400,280 setrgb 1,0,0,0 rectangle 340,240 to 400,280 setrgb 1,255,255,255 text 370,260,"No","cc" return label acquire_target if int(ran(10))player then if snake(a,5)>1 then snake(player,9)=1 snake(player,10)=a snake(player,11)=snake(a,5) fi fi next a if snake(player,9)>0 then return fi fi for a=1 to maxgoodies if goodies(a,3)>0 and goodies(a,3)<4 then snake(player,9)=2 snake(player,10)=a snake(player,11)=0 fi next a if snake(player,9)>0 then return fi change=snake(player,7) angle=parts(player,1,3)+(int(ran(change*2))-change) if angle>360 then angle=angle-360 fi if angle<0 then angle=angle+360 fi parts(player,1,3)=angle return label aim if int(ran(11))>snake(player,13) then snake(player,9)=0 return fi targtype=snake(player,9) targnum=snake(player,10) targsecnum=snake(player,11) if targtype=0 then return fi xpos=parts(player,1,1) ypos=parts(player,1,2) angle=parts(player,1,3) if targtype=1 then if snake(targnum,5)=0 then angle=angle-snake(player,7) else angle=angle+snake(player,7) fi else change=snake(player,7) angle=angle+(int(ran(change*2))-change) fi if angle>360 then angle=angle-360 fi if angle<0 then angle=angle+360 fi parts(player,1,3)=angle return label win_screen setdispbuf d setdrawbuf d clear window gosub draw_title setrgb 1,200,100,200 text 50,50,"Game Over","lb" setrgb 1,150,150,255 win$="Player "+str$(win)+" won the game, well done." text 60,100,win$ setrgb 1,255,255,255 text sw/2,sh-20,"Press the X button for the main menu","cc" gosub waitfornoinput repeat keyinput=or(peek("port1"),peek("port2")) until (and(keyinput,16384)=16384) return label check_win for player=1 to maxplayers if snake(player,5)=maxparts then win=player return fi next player return label reset_players snake(1,1)=100 snake(1,2)=0 snake(1,3)=0 snake(1,4)=0 snake(1,5)=3 snake(1,6)=0 snake(1,7)=spinspeed snake(1,9)=0 snake(1,10)=0 snake(1,11)=0 snake(2,1)=0 snake(2,2)=0 snake(2,3)=100 snake(2,4)=0 snake(2,5)=3 snake(2,6)=0 snake(2,7)=spinspeed snake(2,9)=0 snake(2,10)=0 snake(2,11)=0 for player=1 to maxplayers for part=1 to maxparts parts(player,part,1)=-400+(player*500) parts(player,part,2)=200 if part=1 then parts(player,part,3)=mod(player*180+180,360) else parts(player,part,3)=delay*(part-1) fi for a=0 to delay dirs(player,part,a)=0 next a next part next player return label draw_goodies for goodie=1 to maxgoodies if goodies(goodie,3) > 0 then goodietype=goodies(goodie,3) if goodietype=1 then setrgb 1,0,150,0 fill circle goodies(goodie,1),goodies(goodie,2),10 fi if goodietype=2 then setrgb 1,150,150,0 fill circle goodies(goodie,1),goodies(goodie,2),10 fi if goodietype=3 then setrgb 1,150,150,150 fill circle goodies(goodie,1),goodies(goodie,2),10 fi if goodietype=4 then setrgb 1,0,0,0 fill circle goodies(goodie,1),goodies(goodie,2),10 fi if goodies(goodie,4)>0 then goodies(goodie,4)=goodies(goodie,4)-1 else goodies(goodie,3)=0 fi fi next goodie return label new_goodies if (int(ran(100))<2) then place=0 for a=1 to maxgoodies if place=0 then if goodies(a,3)=0 then goodies(a,1)=int(ran(sw/2))+sw/4 goodies(a,2)=int(ran(sh/2))+sh/4 goodies(a,3)=int(ran(numgoodietypes))+1 goodies(a,4)=int(ran(4)+1)*100 place=1 fi fi next a fi return label process_input if snake(player,14)=1 then if and(buttons,32)=32 then parts(player,1,3)=parts(player,1,3)+int(snake(player,7)) if parts(player,1,3)>360 then parts(player,1,3)=parts(player,1,3)-360 fi fi if and(buttons,128)=128 then parts(player,1,3)=parts(player,1,3)-int(snake(player,7)) if parts(player,1,3)<0 then parts(player,1,3)=parts(player,1,3)+360 fi fi else xpos=parts(player,1,1) ypos=parts(player,1,2) angle=parts(player,1,3) up=0:down=0:right=0:left=0 if and(buttons,16)>0 then up=1 fi if and(buttons,32)>0 then right=1 fi if and(buttons,64)>0 then down=1 fi if and(buttons,128)>0 then left=1 fi if up=1 and left=0 and right=0 then tx=xpos+cosines(270) ty=ypos+sines(270) gosub turnto parts(player,1,3)=angle return fi if up=1 and right=1 then tx=xpos+cosines(315) ty=ypos+sines(315) gosub turnto parts(player,1,3)=angle return fi if up=0 and right=1 and down=0 then tx=xpos+cosines(0) ty=ypos+sines(0) gosub turnto parts(player,1,3)=angle return fi if right=1 and down=1 then tx=xpos+cosines(45) ty=ypos+sines(45) gosub turnto parts(player,1,3)=angle return fi if right=0 and down=1 and left=0 then tx=xpos+cosines(90) ty=ypos+sines(90) gosub turnto parts(player,1,3)=angle return fi if down=1 and left=1 then tx=xpos+cosines(135) ty=ypos+sines(135) gosub turnto parts(player,1,3)=angle return fi if down=0 and left=1 and up=0 then tx=xpos+cosines(180) ty=ypos+sines(180) gosub turnto parts(player,1,3)=angle return fi if left=1 and up=1 then tx=xpos+cosines(225) ty=ypos+sines(225) gosub turnto parts(player,1,3)=angle return fi fi return label turnto hx=cosines(angle) hy=sines(angle) dx=tx-xpos dy=ty-ypos normal=(hy*dx - hx*dy) if normal>=0 then angle=angle-int(snake(player,7)) else angle=angle+int(snake(player,7)) fi if angle>360 then angle=angle-360 fi if angle<0 then angle=angle+360 fi return label face_centre mempointer=1 repeat hx=cosines(angle) hy=sines(angle) dx=tx-xpos dy=ty-ypos normal=(hy*dx - hx*dy) memory(mempointer)=normal mempointer=mempointer+1 if mempointer=5 then mempointer=1 fi if normal>=0 then angle=angle-10 else angle=angle+10 fi if angle>360 then angle=angle-360 fi if angle<0 then angle=angle+360 fi until (memory(1)=memory(3) and memory(2)=memory(4)) return label collide for player=1 to maxplayers ta=parts(player,1,3) x=parts(player,1,1)+(partsize*cosines(ta)) y=parts(player,1,2)+(partsize*sines(ta)) for sp=1 to maxplayers if sp<>player then if snake(sp,4)=0 and snake(sp,5)>1 then for part=1 to snake(sp,5) if snake(sp,4)=0 then tx=parts(sp,part,1) ty=parts(sp,part,2) if x>tx-partsize and xty-partsize and y0 then tx=goodies(sp,1) ty=goodies(sp,2) if x>tx-partsize and xty-partsize and y1 then snake(player,5)=snake(player,5)-1 snake(player,4)=snake(player,4)+30 fi fi return label draw_parts for player=1 to maxplayers if snake(player,4)=0 then setrgb 1,snake(player,1),snake(player,2),snake(player,3) else if mod(snake(player,4),2)=1 then setrgb 1,snake(player,1),snake(player,2),snake(player,3) else setrgb 1,255,255,255 fi snake(player,4)=snake(player,4)-1 fi for part=snake(player,5) to 1 step -1 x=parts(player,part,1) y=parts(player,part,2) fill circle x,y,partsize if part=1 then setrgb 1,255,255,255 ta=parts(player,part,3)-eyespace if ta<0 then ta=ta+360 fi fill circle x+(partsize*cosines(ta)),y+(partsize*sines(ta)),eyesize ta=ta+(eyespace*2) if ta>360 then ta=ta-360 fi fill circle x+(partsize*cosines(ta)),y+(partsize*sines(ta)),eyesize fi next part next player return label move_parts for player=1 to maxplayers angle=parts(player,1,3) xpos=parts(player,1,1) ypos=parts(player,1,2) if xpos>sw or xpos<0 or ypos>sh or ypos<0 then tx=sw/2 ty=sh/2 gosub face_centre parts(player,1,3)=angle fi for part=snake(player,5) to 1 step-1 if part>1 then if parts(player,part,3)>0 then parts(player,part,3)=parts(player,part,3)-1 else dirs(player,part,2)=dirs(player,part,1) dirs(player,part,1)=dirs(player,part-1,2) angle=dirs(player,part,1) parts(player,part,1)=parts(player,part,1)+movecos(angle) parts(player,part,2)=parts(player,part,2)+movesin(angle) fi else dirs(player,part,2)=dirs(player,part,1) dirs(player,part,1)=parts(player,part,3) angle=dirs(player,part,1) parts(player,part,1)=parts(player,part,1)+movecos(angle) parts(player,part,2)=parts(player,part,2)+movesin(angle) fi next part if snake(player,7)>spinspeed then snake(player,7)=snake(player,7)-0.1 fi if snake(player,6)>0 then snake(player,6)=snake(player,6)-1 fi next player return label flip_screen setdispbuf d d=1-d setdrawbuf d return label initialise sw=640 sh=512 flashlength=30 maxparts=8 partsize=10 spinspeed=5 eyesize=partsize/3 eyespace=30 movespeed=4 delay=2 maxgoodies=3 numgoodietypes=4 goodiesize=10 dim goodies(maxgoodies,4) rem 1=x position rem 2=y position rem 3=type rem 0=inactive rem 1=extra tail rem 2=immunity rem 3=turn faster rem 4=lose a part rem 4=life for a=1 to maxgoodies goodies(a,3)=0 next a maxplayers=2 dim snake(maxplayers,14) rem 1=red rem 2=green rem 3=blue rem 4=flash rem 5=length rem 6=grow delay rem 7=turn speed rem 8=player type rem 0=none rem 1=player rem 2=computer rem 9=target type rem 0=none rem 1=player rem 2=goodie rem 10=target number rem 11=secondary target number rem 12=computer reactions rem 13=computer aggressiveness rem 14=control type rem 1=turning rem 2=cardinal dim parts(maxplayers, maxparts, 3) rem 1=x coord rem 2=y coord rem 3=angle/delay dim dirs(maxplayers, maxparts,delay) gosub reset_players snake(1,8)=1 snake(1,12)=5 snake(1,13)=5 snake(1,14)=1 snake(2,8)=2 snake(2,12)=5 snake(2,13)=5 snake(2,14)=1 d=1 dim cosines(360) dim sines(360) dim movecos(360) dim movesin(360) for a=0 to 360 cosines(a)=cos(a*(pi/180)) sines(a)=sin(a*(pi/180)) movecos(a)=movespeed*cosines(a) movesin(a)=movespeed*sines(a) next a titlelines=21 dim title$(titlelines) for a=1 to titlelines title$(a)="" next a title$(1)="Welcome to Snake Bite." title$(3)="Snake Bite is a game involving ... snakes." title$(5)="The object of the game is to make your snake" title$(6)="as large as possible by either eating the" title$(7)="green food lying around the screen, or by" title$(8)="hunting down and eating the other snake on" title$(9)="the screen. Of course, whilst you are doing" title$(10)="this, your opponent is trying to do the" title$(11)="same thing." title$(13)="As well as the green food, there are other" title$(14)="things that will appear on the screen. They" title$(15)="are yellow invulnerability snacks, white" title$(16)="super spin snacks, and nasty black poison." title$(18)="Be careful of the poison, it will cause the" title$(19)="end of your tail to drop off." title$(21)="Happy hunting." helplines=20 dim help$(helplines) for a=1 to helplines help$(a)="" next a help$(1)="The aim of the game is to have a snake that" help$(2)="is "+str$(maxparts)+" segments long." help$(4)="The only controls are left and right which" help$(5)="are used to turn the snake's head left and" help$(6)="right. The snake moves forwards on its own" help$(8)="The snakes mouth is between its eyes, so" help$(9)="don't get annoyed when you miss collecting a" help$(10)="piece of food because you side-swiped it." help$(12)="A quick reminder of the things you can collect:" help$(14)=" Green : Food, gain an extra body part" help$(15)=" Yellow : Temporary Invulnerability" help$(16)=" White : Increased turning ability" help$(17)=" Black : Poison, lose a body part" help$(19)="Don't forget you can gain extra body parts" help$(20)="by biting the tail of your opponent." numoptions=4 dim options$(numoptions) options$(1)="Play Game" options$(2)="Options" options$(3)="Help" options$(4)="Return to title" numchoices=9 dim choices$(numchoices) choices$(1)="Player 1 Type" choices$(2)="Player 1 Control" choices$(3)="Player 1 Reactions" choices$(4)="Player 1 Aggressiveness" choices$(5)="Player 2 Type" choices$(6)="Player 2 Control" choices$(7)="Player 2 Reactions" choices$(8)="Player 2 Aggressiveness" choices$(9)="Return to Menu" dim hints$(numchoices) hints$(1)="Controlled by Human or Computer" hints$(2)="Control method" hints$(3)="Computer reaction speed" hints$(4)="Computer aggressiveness and determination" hints$(5)="Controlled by Human or Computer" hints$(6)="Control method" hints$(7)="Computer reaction speed" hints$(8)="Computer aggressiveness and determination" hints$(9)="Press X to return to the Main Menu" dim memory(4) open window sw,sh clear window return