Volhout
 Guru
 Joined: 05/03/2018 Location: NetherlandsPosts: 6101 |
| Posted: 07:00pm 26 Jun 2023 |
|
|
|
SNAKE for Picomite VGA
In this game you control a snake (more a caterpillar with uncontrolled appetite) through a grass field, where fruit falls from the trees. The snake, ever hungry, eats all there is. Also thorny bushes, or even itself. Needless to say that these last 2 hurt him to death.
The game is progressive, as is the music. At scores of 50 and higher it comes to its full potential... so practise a lot...
There is a high score list that registers your achievements. But in this version it only remains as long as you keep this game in memory (VAR SAVE).
The game design is driven from a similar game I wrote 40 years ago for the ORIC-1. Initially I thought of using it as an entry in the programming competition, but I will think of something new by that time. Or become a judge... When you crunch the game it is not even 3 kbyte in size (just remove comments).
I tried to run this on MMB4W in mode 7 but that did not run, probably because the incompatibility in the sprite file. Conversion to LCD on the pico might work, but that is not my intention. Leave that to others...
Enjoy the game, and give feedback. En list your highscore here !!!
'snake for Picomite VGA 5.07.07 'play snake game using cursor keys. Avoid eating scrub and yourself 'eat all fruit to grow. 'version ' s1 = basic ASCII text snake ' s2 = using sprites for snake ' s3 = adding fruit and tone ' s4/s4_1 = 8 sprites ' s5/s5_1 = dynamic game experience, music ' s6/s6_1 = highscore + compressed music ' s7/S7_1 = add sprites to bas file, add intro ' snake8 = release 'init arrays and restore previous highscore list z=255:Dim s(z,1),n$(9):VAR restore 'start graphics and sound MODE 2 SetTick 120,music 'variables used, and default values ' s(x,y)=head coord, (v,w)=head motion, tail erase unless food ' h=head poiter, t=tail pointer, l=length snake = level ' z=max length snake, p=pixel ahead, n$()=highscore list ' c=food delay, (i,j)=food coordiates, u=field color dark green ' d=tick counter music, e=music pointer, m$=music, f=tone ' a$=input, b=key h=0:t=0:l=2:d=0:b=131:x=120:y=x:s(h,0)=x:s(h,1)=y:c=79:e=1:u=16384 'compressed sound score containing bass, metrum, and melody m$="QQE\STSE\Q\SOC\X\SC\\\QMA\STSA\Q\QL@\P\Q@\S\QQE\STSE\Q\SOC\X\SC\\\TMA\VXVA\T\VO@\[\XC\\\" 'create sprite file in filesystem and load 8 sprites Open "8.spr" For output As #1 Print #1,"8,8,8" For i=1 To 64 Read a$:Print #1,a$ Next Close #1 Sprite load "8.spr",1 'intro screen CLS u 'empty grass field 'game title j=3*Pi/2 For i=0 To 3*Pi Step Pi/16 'print S as a series of snake sprites Sprite write 1,80-40*Cos(i),(1+(i>j))*80-40*Sin(i+Pi*(i>j)) Pause 100 Next Sprite write 3,120,160 'append head Text 140,40,"nake",,,6,RGB(orange),u 'legend and enter player name For i=4 To 7 Sprite write i,120+i*12,110 Next Sprite write 1,168,130:Sprite write 8,180,130 Text 220,110,"good food",,,,,u Text 220,130,"death",,,,,u Text 168,165,"use cursor keys",,,,,u Text 168,200,"enter name ......",,,,,u n$(0)="" Do a$=Inkey$ If a$<>"" Then n$(0)=n$(0)+a$ Text 240,200,n$(0),,,,,u EndIf Loop Until a$=Chr$(13) 'Input n$(0) 'n(0) is new game info, n(1..9)=highscore 'playfield For i=0 To 39 'bushes around field For j=0 To 30 Sprite write 8,8*i,8*j Next :Next Box 8,8,304,224,1,u,u 'dark green ground 'main game loop Do If b>127 Then 'calculate movement when b<>0 v=(b=131)-(b=130) 'change only at key press w=(b=129)-(b=128) 'else keep moving same EndIf a$=Inkey$:b=Asc(a$) 'detect arrow keys If b=27 Then Save image "game.bmp" x=x+8*v:y=y+8*w 'new x,y no protection relies on fence p=Pixel(x+4,y+4) 'look ahead what is coming Text 0,0,Str$(l) 'show level = length If p=u Then 'when background then empty Sprite write 1,s(h,0),s(h,1) 'write body shape over old head h=(h+1) And z:s(h,0)=x:s(h,1)=y 'new head pointer and store x,y t=(h-l) And z 'new tail pointer Sprite write 2+(v=0),x,y,4+(v=1)+2*(w=1) Box s(t,0),s(t,1),8,8,1,u,u 'erase tail ElseIf p=65280 Or p=RGB(brown) Then 'if wall or body then die SetTick 0,0:Play stop Text 160,100,"HIGHSCORE",C,,,,u score Text 160,60,"You died, <CR> or 'q' to quit",C,,,,u Do :a$=Inkey$:Loop While a$="" If a$="q" Then End Else Run 'very brute end game control Else 'is food Box x,y,8,8,1,u,u 'erase food eaten l=Min(l+4,z):c=79 EndIf Inc c,1 'new food after 80 moves If c=80 Then 'after 80 snake moves provide new food Do 'find free location i=8*Int(1+Rnd()*38):j=8*Int(1+Rnd()*28) Loop Until Pixel(i+4,j+4)=u c=0:Sprite write 4+(l>50)+Int(Rnd()*4),i,j 'OK and plot EndIf Pause Max(180-l,80) 'dynamic speed Loop 'dynamic music play Sub music gn If f<700 And l>50 Then Play sound 1,B,Q,f,l/16 'melody sounds when l>50 If (d And 3) = 0 Then gn :Play sound 2,B,Q,f,l/16 'metrum increases EndIf If d=0 Or d=8 Then gn :Play sound 3,B,S,f 'bass always EndIf d=(d+1) And 15 'count in 1/16 note If e>Len(m$) Then e=1 'wrap score to beginning End Sub Sub gn f=110*2^((Asc(Mid$(m$,e,1))-59)/12) 'calc freq Inc e,1 'next note End Sub 'manages the highscore list, uses n$(0) for new entry, show n$(1..9) Sub score n$(0)=Right$("00"+Str$(l),3)+" "+n$(0) 'combine level and name Sort n$():VAR save n$() 'sort and save For i=1 To 9 Text 133,200-i*9,n$(i),,,,,u 'show list Next i End Sub 'sprite data Data 00EEEE00,0EECCEE0,EEECCEEE,ECCECCCE,ECCCECCE,EEECCEEE,0EECCEE0,00EEEE00 Data 00EEEEE0,0E77CCEE,47177CCE,4477CCCC,4477CCCC,47177CCE,0E77CCEE,00EEEEE0 Data 00444400,0E7447E0,E717717E,E777777E,EC7CC7CE,ECCCCCCE,EECCCCEE,0EECCEE0 Data 00009900,00229000,02AAA220,2AAA2AA2,2AAAAAA2,2AAAAAA2,02AAAA20,0028A200 Data 000000E0,000000E0,00000666,00006666,00066E60,00666600,E66E6000,06600000 Data 00009000,00009000,04444440,44444444,44444444,44444444,04444440,00444400 Data 00EEEE00,0ECCCCE0,EC7CCCCC,ECCCCCCC,ECCCCCCC,ECCCCCCC,0ECCCCC0,00CCCC00 Data A002020A,0A020A02,020A0202,00202002,202A2020,0A02A020,0022A200,000AAA00
Volhout
P.S. if you press <ESC> during the game, it saves the screen to a file "game.bmp" as proof that you achieved what you claim....
P.P.S. For Tom and Martin: the music compression is very simple: the lowest frequency is 147Hz, the highest 698Hz, all notes in between are calculated from an index that is derived from the ASCII value of each character. The Bass is 1/2 tempe, the Metrum is 1/4 tempo, and the melody is 1/16 tempo. All in one ASCII string. Edited 2023-06-27 05:11 by Volhout |