Picomite VGA games


Author Message
Volhout

Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 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