#Region Project Attributes
#ApplicationLabel: Snake Game
#VersionCode: 1
#VersionName:
'SupportedOrientations possible values: unspecified, landscape or portrait.
#SupportedOrientations: portrait
#CanInstallToExternalStorage: False
#End Region
#Region Activity Attributes
#FullScreen: False
#IncludeTitle: True
#End Region
#Region Project Attributes
' #MainFormWidth: 320
' #MainFormHeight: 480
#End Region
Sub Process_Globals
Private tmr As Timer
Private GridSize As Int = 20
Private Snake As List
Private Direction As String = "RIGHT"
Private FoodX, FoodY As Int
Private NumCols, NumRows As Int
Private Score As Int = 0
Private IsDead As Boolean = False
Private mpEat As MediaPlayer
Private mpGameOver As MediaPlayer
End Sub
Sub Globals
Private xui As XUI
Private pnlGame As Panel
Private cvs As B4XCanvas
Private btnRestart As Button
Private lblScore As Label
Private GamePaused As Boolean = False
Private btnPauseResume As Button
Private HighScore As Int = 0
Private Obstacles As List
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("layout")
pnlGame.Color = xui.Color_Black
cvs.Initialize(pnlGame)
NumCols = pnlGame.Width / GridSize
NumRows = pnlGame.Height / GridSize
InitGame
tmr.Initialize("tmr", 150)
tmr.Enabled = True
mpEat.Initialize
mpGameOver.Initialize
LoadHighScore
'mpEat.Load(File.DirAssets, "eat.mp3")
'mpGameOver.Load(File.DirAssets, "gameover.mp3")
End Sub
Sub InitGame
Snake.Initialize
Snake.Add(CreatePoint(5, 5))
Snake.Add(CreatePoint(4, 5))
Snake.Add(CreatePoint(3, 5))
Direction = "RIGHT"
CreateFood
IsDead = False
Score = 0
End Sub
Sub CreatePoint(x As Int, y As Int) As Int()
Return Array As Int(x, y)
End Sub
Sub CreateFood
Dim valid As Boolean = False
Do While valid = False
FoodX = Rnd(0, NumCols)
FoodY = Rnd(0, NumRows)
valid = True
For Each p() As Int In Snake
If p(0) = FoodX And p(1) = FoodY Then
valid = False
Exit
End If
Next
Loop
End Sub
Sub tmr_Tick
If IsDead Then Return
Dim head() As Int = Snake.Get(0)
Dim nx = head(0), ny = head(1)
Select Direction
Case "UP": ny = ny - 1
Case "DOWN": ny = ny + 1
Case "LEFT": nx = nx - 1
Case "RIGHT": nx = nx + 1
End Select
If nx < 0 Or ny < 0 Or nx >= NumCols Or ny >= NumRows Then
GameOver
Return
End If
For Each p() As Int In Snake
If p(0) = nx And p(1) = ny Then
GameOver
Return
End If
Next
Snake.InsertAt(0, CreatePoint(nx, ny))
If nx = FoodX And ny = FoodY Then
Score = Score + 1
mpEat.Play
CreateFood
Else
Snake.RemoveAt(Snake.Size - 1)
End If
If Score Mod 5 = 0 Then
tmr.Interval = Max(100, tmr.Interval - 50) ' Speed up the game
End If
' If Score Mod 10 = 0 Then
' ' Add a new level (e.g., faster snake or more obstacles)
' ' You can increase speed or add new challenges
' tmr.Interval = Max(50, tmr.Interval - 30)
' End If
DrawGame
End Sub
Sub DrawGame
cvs.ClearRect(cvs.TargetRect)
' Draw food
cvs.DrawRect(GridRect(FoodX, FoodY), xui.Color_Red, True, 0)
' Draw snake
For i = 0 To Snake.Size - 1
Dim p() As Int = Snake.Get(i)
Dim color As Int
If i = 0 Then
color = xui.Color_Green
Else
color = xui.Color_RGB(0, 180, 0)
End If
'cvs.DrawRect(GridRect(p(0), p(1)), color, True, 0)
Dim r As B4XRect = GridRect(p(0), p(1))
cvs.DrawRect(r, color, True, 1dip)
Next
cvs.Invalidate
lblScore.Text = $"Score: ${Score}"$
End Sub
Sub GridRect(x As Int, y As Int) As B4XRect
Dim left As Float = x * GridSize
Dim top As Float = y * GridSize
Dim right As Float = left + GridSize
Dim bottom As Float = top + GridSize
Dim r As B4XRect
r.Initialize(left, top, right, bottom)
Return r
End Sub
Sub Activity_KeyUp(KeyCode As Int) As Boolean
Select KeyCode
Case KeyCodes.KEYCODE_DPAD_UP
If Direction <> "DOWN" Then Direction = "UP"
Case KeyCodes.KEYCODE_DPAD_DOWN
If Direction <> "UP" Then Direction = "DOWN"
Case KeyCodes.KEYCODE_DPAD_LEFT
If Direction <> "RIGHT" Then Direction = "LEFT"
Case KeyCodes.KEYCODE_DPAD_RIGHT
If Direction <> "LEFT" Then Direction = "RIGHT"
End Select
Return True
End Sub
Sub GameOver
IsDead = True
tmr.Enabled = False
mpGameOver.Play
ToastMessageShow($"Game Over! Score: ${Score}"$, True)
SaveHighScore
End Sub
Sub btnRestart_Click
InitGame
tmr.Enabled = True
End Sub
Private Sub lblScore_Click
End Sub
Sub btnPauseResume_Click
If GamePaused Then
tmr.Enabled = True
btnPauseResume.Text = "Pause"
GamePaused = False
Else
tmr.Enabled = False
btnPauseResume.Text = "Resume"
GamePaused = True
End If
End Sub
Sub LoadHighScore
If File.Exists(File.DirInternal, "highscore.txt") = True Then
HighScore = File.ReadString(File.DirInternal, "highscore.txt")
End If
End Sub
Sub SaveHighScore
File.WriteString(File.DirInternal, "highscore.txt", HighScore)
End Sub