Share via


Snake in Small Basic

This week's featured sample is the arcade classic Snake!  And it comes from PlayDeez, who has also written other interesting Small Basic games (check out the Small Basic forums for more such hotness.)

Here's the screenshot, followed by the source listing. 

 Initialize()
While (GameState <> "")
    DoGameLoop()
EndWhile
Program.End()

Sub Initialize
    InitializeVariables()
    InitializeScreen()
EndSub

Sub InitializeVariables
    Array.SetValue("DeltaX","North",0)
    Array.SetValue("DeltaX","East",1)
    Array.SetValue("DeltaX","South",0)
    Array.SetValue("DeltaX","West",-1)
    Array.SetValue("DeltaY","North",-1)
    Array.SetValue("DeltaY","East",0)
    Array.SetValue("DeltaY","South",1)
    Array.SetValue("DeltaY","West",0)
    Array.SetValue("NorthFlag","North",1)
    Array.SetValue("NorthFlag","East",0)
    Array.SetValue("NorthFlag","South",0)
    Array.SetValue("NorthFlag","West",0)
    Array.SetValue("SouthFlag","North",0)
    Array.SetValue("SouthFlag","East",0)
    Array.SetValue("SouthFlag","South",1)
    Array.SetValue("SouthFlag","West",0)
    Array.SetValue("EastFlag","North",0)
    Array.SetValue("EastFlag","East",1)
    Array.SetValue("EastFlag","South",0)
    Array.SetValue("EastFlag","West",0)
    Array.SetValue("WestFlag","North",0)
    Array.SetValue("WestFlag","East",0)
    Array.SetValue("WestFlag","South",0)
    Array.SetValue("WestFlag","West",1)
    Array.SetValue("DirectionInput","N","North")
    Array.SetValue("DirectionInput","E","East")
    Array.SetValue("DirectionInput","S","South")
    Array.SetValue("DirectionInput","W","West")
    GameDelay = 100
    Score = 0
    HighScore = 0
    GameState = "TitleScreen"
    ScreenDirty = 1
    CurrentDirectory = Text.GetSubText(File.GetSettingsFilePath(),0,Text.GetLength(File.GetSettingsFilePath())-26)
EndSub

Sub InitializeScreen
    GraphicsWindow.Show()
    GraphicsWindow.Width = 640
    GraphicsWindow.Height = 480
    'TODO: remove hack when able to do so
    GraphicsWindow.Width = 640
    GraphicsWindow.KeyDown = HandleKeyPress
EndSub

Sub HandleTitleScreenKeyPress
    Key = GraphicsWindow.LastKey
    If (Key = "Escape") Then
        GameState=""
    Else
        If (Key="F2") Then
            GameState = "Play"
            ScreenDirty = 1
        Else
            If (Key="F1") Then
                GameState = "Instructions"
                ScreenDirty = 1
                DoInstructionLoop()
            EndIf
        EndIf
    EndIf
EndSub

Sub HandleInstructionsKeyPress
    Key = GraphicsWindow.LastKey
    If (Key = "Escape") Then
        GameState = "TitleScreen"
        ScreenDirty = 1
        DoTitleScreenLoop()
    EndIf
EndSub

Sub HandlePlayKeyPress
    Key = GraphicsWindow.LastKey
    If (Key = "Left") Then
        DirectionInput = DirectionInput + "W"
    Else
        If (Key = "Right") Then
            DirectionInput = DirectionInput + "E"
        Else
            If (Key = "Up") Then
                DirectionInput = DirectionInput + "N"
            Else
                If (Key = "Down") Then
                    DirectionInput = DirectionInput + "S"
                EndIf
            EndIf
        EndIf
    EndIf
EndSub

Sub HandleGameOverKeyPress
    Key = GraphicsWindow.LastKey
    If (Key = "Escape") Then
        GameState=""
    Else
        If (Key="F2") Then
            GameState = "Play"
            ScreenDirty = 1
            DoPlayLoop()
        Else
            If (Key="F1") Then
                GameState = "Instructions"
                ScreenDirty = 1
                DoInstructionLoop()
            EndIf
        EndIf
    EndIf
EndSub

Sub HandleKeyPress
    If (GameState="TitleScreen") Then
      HandleTitleScreenKeyPress()
    Else 
        If (GameState="Instructions") Then
            HandleInstructionsKeyPress()
        Else
            If (GameState="Play") Then
                HandlePlayKeyPress()
            Else
                If (GameState="GameOver") Then
                    HandleGameOverKeyPress()
                Else
                EndIf
            EndIf
        EndIf
    EndIf    
EndSub

Sub DoTitleScreenLoop
    If (ScreenDirty = 1) Then
        ScreenDirty = 0
        GraphicsWindow.Clear()
        GraphicsWindow.BrushColor = "#000000"
        GraphicsWindow.FontSize = 32
        GraphicsWindow.DrawText(0,0,"SBSnake!")
        GraphicsWindow.FontSize = 16
        GraphicsWindow.DrawText(0,64," for instructions")
        GraphicsWindow.DrawText(0,80," for a new game")
        GraphicsWindow.DrawText(0,96," to exit")
    EndIf
EndSub

Sub DoInstructionLoop
    If (ScreenDirty = 1) Then
        ScreenDirty = 0
        GraphicsWindow.Clear()
        GraphicsWindow.BrushColor = "#000000"
        GraphicsWindow.FontSize = 32
        GraphicsWindow.DrawText(0,0,"How To Play SBSnake!")
        GraphicsWindow.FontSize = 16
        GraphicsWindow.DrawText(0,64,"Use arrow keyss to move the snake")
        GraphicsWindow.DrawText(0,80,"Avoid hitting your own tail")
        GraphicsWindow.DrawText(0,96,"Avoid hitting the wall")
        GraphicsWindow.DrawText(0,112,"Collect red pellets to accumulate score")
        GraphicsWindow.DrawText(0,128," to return to main menu")
    EndIf
EndSub

Sub AddPellet
    PickPellet:
    PelletX = Math.GetRandomNumber(40)
    PelletY = Math.GetRandomNumber(30)
    Color = GraphicsWindow.GetPixel(PelletX * 16 + 8, PelletY * 16 + 8)
    If (Color = "#00FF00" Or Color="#FF0000") Then 
        Goto PickPellet
    EndIf
    GraphicsWindow.PenWidth = 0
    GraphicsWindow.BrushColor = "#FF0000"
    GraphicsWindow.FillRectangle(PelletX* 16+3, PelletY * 16+3,10,10)
EndSub

Sub DrawHead
    GraphicsWindow.PenWidth = 0
    GraphicsWindow.BrushColor = "#00FF00"
    GraphicsWindow.FillRectangle(SnakeHeadX * 16+2, SnakeHeadY * 16+2,12,12)
    If (Direction="South") Then
        GraphicsWindow.FillRectangle(SnakeHeadX * 16+4, SnakeHeadY*16,8,4)
    EndIf
    If (Direction="North") Then
        GraphicsWindow.FillRectangle(SnakeHeadX * 16+4, SnakeHeadY*16+12,8,4)
    EndIf
    If (Direction="East") Then
        GraphicsWindow.FillRectangle(SnakeHeadX * 16, SnakeHeadY*16+4,4,8)
    EndIf
    If (Direction="West") Then
        GraphicsWindow.FillRectangle(SnakeHeadX * 16+12, SnakeHeadY*16+4,4,8)
    EndIf
EndSub

Sub EraseHead
    If (GraphicsWindow.GetPixel(SnakeHeadX*16+8,SnakeHeadY*16)="#00FF00") Then
        NorthFlag = 1
    Else
        NorthFlag = Array.GetValue("NorthFlag",Direction)
    EndIf
    If (GraphicsWindow.GetPixel(SnakeHeadX*16+8,SnakeHeadY*16+15)="#00FF00") Then
        SouthFlag = 1
    Else
        SouthFlag = Array.GetValue("SouthFlag",Direction)
    EndIf
    If (GraphicsWindow.GetPixel(SnakeHeadX*16,SnakeHeadY*16+8)="#00FF00") Then
        WestFlag = 1
    Else
        WestFlag = Array.GetValue("WestFlag",Direction)
    EndIf
    If (GraphicsWindow.GetPixel(SnakeHeadX*16+15,SnakeHeadY*16+8)="#00FF00") Then
        EastFlag = 1
    Else
        EastFlag = Array.GetValue("EastFlag",Direction)
    EndIf
    GraphicsWindow.BrushColor = "#FFFFFF"
    GraphicsWindow.FillRectangle(SnakeHeadX * 16, SnakeHeadY*16,16,16)
    GraphicsWindow.BrushColor = "#00FF00"
    If (AtePellet = 1) Then
        GraphicsWindow.FillRectangle(SnakeHeadX * 16+3, SnakeHeadY*16+3,10,10)
    Else
        GraphicsWindow.FillRectangle(SnakeHeadX * 16+4, SnakeHeadY*16+4,8,8)
    EndIf
    If (NorthFlag = 1) Then
        GraphicsWindow.FillRectangle(SnakeHeadX * 16+4, SnakeHeadY*16,8,4)
    EndIf
    If (SouthFlag = 1) Then
        GraphicsWindow.FillRectangle(SnakeHeadX * 16+4, SnakeHeadY*16+12,8,4)
    EndIf
    If (WestFlag = 1) Then
        GraphicsWindow.FillRectangle(SnakeHeadX * 16, SnakeHeadY*16+4,4,8)
    EndIf
    If (EastFlag = 1) Then
        GraphicsWindow.FillRectangle(SnakeHeadX * 16+12, SnakeHeadY*16+4,4,8)
    EndIf
EndSub

Sub EraseTail
    If (GraphicsWindow.GetPixel(SnakeTailX*16+8,SnakeTailY*16)="#00FF00") Then
        NorthFlag = 1
    Else
        NorthFlag = 0
    EndIf
    If (GraphicsWindow.GetPixel(SnakeTailX*16+8,SnakeTailY*16+15)="#00FF00") Then
        SouthFlag = 1
    Else
        SouthFlag = 0
    EndIf
    If (GraphicsWindow.GetPixel(SnakeTailX*16,SnakeTailY*16+8)="#00FF00") Then
        WestFlag = 1
    Else
        WestFlag = 0
    EndIf
    If (GraphicsWindow.GetPixel(SnakeTailX*16+15,SnakeTailY*16+8)="#00FF00") Then
        EastFlag = 1
    Else
        EastFlag = 0
    EndIf
    GraphicsWindow.BrushColor = "#FFFFFF"
    GraphicsWindow.FillRectangle(SnakeTailX * 16, SnakeTailY*16,16,16)
    
    If (NorthFlag = 1) Then
        TailDirection = "North"
    EndIf
    If (SouthFlag = 1) Then
        TailDirection = "South"
    EndIf
    If (EastFlag = 1) Then
        TailDirection = "East"
    EndIf
    If (WestFlag = 1) Then
        TailDirection = "West"
    EndIf
    SnakeTailX = SnakeTailX + Array.GetValue("DeltaX",TailDirection)
    SnakeTailY = SnakeTailY + Array.GetValue("DeltaY",TailDirection)
    If (GraphicsWindow.GetPixel(SnakeTailX*16+3,SnakeTail*16+3)="#00FF00") Then
        TailPellet = 1
    Else
        TailPellet = 0
    EndIf 
    If (GraphicsWindow.GetPixel(SnakeTailX*16+8,SnakeTailY*16)="#00FF00") Then
        NorthFlag = 1
    Else
        NorthFlag = 0
    EndIf
    If (GraphicsWindow.GetPixel(SnakeTailX*16+8,SnakeTailY*16+15)="#00FF00") Then
        SouthFlag = 1
    Else
        SouthFlag = 0
    EndIf
    If (GraphicsWindow.GetPixel(SnakeTailX*16,SnakeTailY*16+8)="#00FF00") Then
        WestFlag = 1
    Else
        WestFlag = 0
    EndIf
    If (GraphicsWindow.GetPixel(SnakeTailX*16+15,SnakeTailY*16+8)="#00FF00") Then
        EastFlag = 1
    Else
        EastFlag = 0
    EndIf
    If (TailDirection="North") Then
        SouthFlag = 0
    EndIf
    If (TailDirection="South") Then
        NorthFlag = 0
    EndIf
    If (TailDirection="East") Then
        WestFlag = 0
    EndIf
    If (TailDirection="West") Then
        EastFlag = 0
    EndIf
    GraphicsWindow.FillRectangle(SnakeTailX * 16, SnakeTailY*16,16,16)
    GraphicsWindow.BrushColor = "#00FF00"
    If (TailPellet = 1) Then
        GraphicsWindow.FillRectangle(SnakeTailX * 16+3, SnakeTailY*16+3,10,10)
    Else
        GraphicsWindow.FillRectangle(SnakeTailX * 16+4, SnakeTailY*16+4,8,8)
    EndIf
    If (NorthFlag = 1) Then
        GraphicsWindow.FillRectangle(SnakeTailX * 16+4, SnakeTailY*16,8,4)
    EndIf
    If (SouthFlag = 1) Then
        GraphicsWindow.FillRectangle(SnakeTailX * 16+4, SnakeTailY*16+12,8,4)
    EndIf
    If (WestFlag = 1) Then
        GraphicsWindow.FillRectangle(SnakeTailX * 16, SnakeTailY*16+4,4,8)
    EndIf
    If (EastFlag = 1) Then
        GraphicsWindow.FillRectangle(SnakeTailX * 16+12, SnakeTailY*16+4,4,8)
    EndIf
EndSub

Sub ProcessDirectionInput
    If (Text.GetLength(DirectionInput)>0) Then
        Temp = Text.GetSubText(DirectionInput,0,1)
        DirectionInput = Text.GetSubText(DirectionInput,1,Text.GetLength(DirectionInput)-1)
        Direction = Array.GetValue("DirectionInput",Temp)
    EndIf
EndSub

Sub StartGame
    Direction=""
    DirectionInput=""
    SnakeLength = 1
    SnakeMaximumLength = 4
    SnakeHeadX = 20
    SnakeHeadY = 15
    SnakeTailX = 20
    SnakeTailY = 15
    AtePellet = 0
    Score = 0
    GraphicsWindow.Clear()
    DrawHead()
    AddPellet()
    UpdateScore()
EndSub

Sub UpdateScore
    GraphicsWindow.Title = "SBSnake - "+Score
EndSub

Sub DoPlayLoop
    If (ScreenDirty = 1) Then
        ScreenDirty = 0
        StartGame()
    Else
        If (Direction <> "" Or DirectionInput<>"") Then
            ProcessDirectionInput()
            EraseHead()
            SnakeHeadX = SnakeHeadX + Array.GetValue("DeltaX",Direction)
            SnakeHeadY = SnakeHeadY + Array.GetValue("DeltaY",Direction)
            If (SnakeHeadX<0 Or SnakeHeadX>39 Or SnakeHeadY < 0 Or SnakeHeadY > 29) Then
                GameState = "GameOver"
                ScreenDirty = 1
            Else
                If (GraphicsWindow.GetPixel(SnakeHeadX*16+8,SnakeHeadY*16+8)="#FF0000") Then
                    Score = Score + 1
                    UpdateScore()
                    AtePellet = 1
                    SnakeMaximumLength = SnakeMaximumLength + 2
                    AddPellet()
                Else
                    AtePellet = 0
                EndIf
                If (GraphicsWindow.GetPixel(SnakeHeadX*16+8,SnakeHeadY*16+8)="#00FF00") Then
                    GameState = "GameOver"
                    DrawHead()
                    ScreenDirty = 1
                Else
                    SnakeLength = SnakeLength + 1
                    DrawHead()
                    While (SnakeLength>SnakeMaximumLength)
                        EraseTail()
                        SnakeLength = SnakeLength - 1
                    EndWhile
                    Program.Delay(GameDelay)
                EndIf
            EndIf
        EndIf
    EndIf
EndSub

Sub DoGameOverLoop
    If (ScreenDirty = 1) Then
        ScreenDirty = 0
        GraphicsWindow.BrushColor = "#000000"
        GraphicsWindow.FontSize = 32
        GraphicsWindow.DrawText(0,0,"Game Over!")
        GraphicsWindow.FontSize = 16
        GraphicsWindow.DrawText(0,64," for instructions")
        GraphicsWindow.DrawText(0,80," for a new game")
        GraphicsWindow.DrawText(0,96," to exit")
    EndIf
EndSub

Sub DoGameLoop
    If (GameState = "TitleScreen") Then
        DoTitleScreenLoop()
    Else
        If (GameState = "Instructions") Then
            DoInstructionLoop()
        Else
            If (GameState = "Play") Then
                DoPlayLoop()
            Else
                If (GameState = "GameOver") Then
                    DoGameOverLoop()
                EndIf
            EndIf
        EndIf
    EndIf
EndSub

Do you want your samples to be featured here? Post them in our forums and we'll pick one each week.

Comments

  • Anonymous
    December 08, 2008
    PingBack from http://www.alvinashcraft.com/2008/12/08/dew-drop-december-8-2008/

  • Anonymous
    December 08, 2008
    They made Snake in Small Basic, and didn't call it Nibbles? For shame.

  • Anonymous
    August 27, 2009
    It is Not working.. It says, "Sorry, We found some errors... 284,49: The variable 'snaketail' is used, but its value is not assigned. Are you sure you have spelled correctly? " What does it means? I have just simply copied and pasted the text more than three times.. If you have corrected or want to correct the mistake done by me, mail me at gughasrinivas@yahoo.co.in Sure I am new to programming...

  • Anonymous
    November 08, 2009
    Gugha, I've just bug-fixed the sample version of this snake game at: http://wiki.smallbasic.com/smallbasic.com/wiki/Snake.ashx I have tested it in v0.7 after copy/pasting it from that page and it all works.

  • Anonymous
    January 28, 2010
    you forgot to put a Y on the end of one of your snaketails

  • Anonymous
    May 28, 2010
    The comment has been removed

  • Anonymous
    July 05, 2011
    i'll try to run your code but it says that there is an error found.

  • Anonymous
    July 05, 2011
    are you sure your code is correct...i fixed all 3 times but its not working

  • Anonymous
    August 11, 2012
    I had to fix a bug in EraseTail subroutine, but it still won't run.  How about a functioning version?

  • Anonymous
    May 11, 2013
    its got errors

  • Anonymous
    July 28, 2013
    I am not here to copy the game, but to understand it from a programmer's view. I've seen other programmers add explanations in the form of comments in the code-you would be a lifesaver if you did that! You can either just comment back here or, as I prefer, e-mail me at karrowallstrom@gmail.com Thank you!

  • Anonymous
    December 15, 2013
    The error of the variable snaketail is that it should be snaketailY

  • Anonymous
    December 23, 2013
    yeni başlayanlar ve orta seviye kullanıcıları için güzel bir kaynak microsoftsmallbasic.blogspot.com

  • Anonymous
    February 16, 2014
    I'm new to programing and when that error message came up, it took me a while to figure out it was supposed to say SnakeTailY , but with over 400 lines of code, it had to some errors.