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.