' ================================ ' SIMPLE SNAKE GAME - Liberty BASIC ' ================================ ' Graphics constants global cellSize, gridWidth, gridHeight global snakeLength, foodX, foodY, gamespeed global gridOffsetY, score cellSize = 20 gridWidth = 20 gridHeight = 20 gridOffsetY = 20 foodX = 0 foodY = 0 gamespeed = 333 score = 0 ' Movement directions global dirX, dirY dirX = 1 : dirY = 0 ' start moving right ' Snake body array dim snakeX(400) dim snakeY(400) snakeLength = 5 ' Initialize snake position in center for i = 1 to snakeLength snakeX(i) = 10 - i snakeY(i) = 10 next ' Create first food position call newFood ' Open graphics window WindowWidth = cellSize * gridWidth + 10 WindowHeight = cellSize * gridHeight + 60 open "SNAKE GAME - WASD to Move" for graphics_nsb_nf as #g #g "trapclose [quit]" #g "down; fill white; flush" ' Force focus #g "setfocus" ' Enable character input #g "when characterInput [keypress]" ' Start game timer [startGame] timer gamespeed, [gameTick] wait [gameTick] ' Move snake segments for i = snakeLength to 2 step -1 snakeX(i) = snakeX(i-1) snakeY(i) = snakeY(i-1) next ' Head moves in current direction snakeX(1) = snakeX(1) + dirX snakeY(1) = snakeY(1) + dirY ' Wall collision ends game if snakeX(1) < 0 or snakeX(1) >= gridWidth _ or snakeY(1) < 0 or snakeY(1) >= gridHeight then call gameOver wait end if ' Check self collision for i = 2 to snakeLength if snakeX(1) = snakeX(i) and snakeY(1) = snakeY(i) then call gameOver wait end if next ' Check food collision if snakeX(1) = foodX and snakeY(1) = foodY then snakeLength = snakeLength + 1 score = score + 10 ' Initialize new tail segment at same spot as previous tail snakeX(snakeLength) = snakeX(snakeLength - 1) snakeY(snakeLength) = snakeY(snakeLength - 1) ' Speed up the game timer 0 gamespeed = max(gamespeed - 5, 150) timer gamespeed, [gameTick] call newFood end if call redraw wait [keypress] key$ = Inkey$ key$ = lower$(key$) select case key$ case "w" if dirY <> 1 then dirX = 0 : dirY = -1 case "a" if dirX <> 1 then dirX = -1 : dirY = 0 case "s" if dirY <> -1 then dirX = 0 : dirY = 1 case "d" if dirX <> -1 then dirX = 1 : dirY = 0 case chr$(27) ' ESC call gameOver wait end select wait [quit] close #g end sub redraw ' Clear screen #g "cls" ' Draw top banner background #g "color lightgray" #g, "backcolor lightgray" #g "place 0 0" #g "boxfilled "; (gridWidth * cellSize); " "; gridOffsetY ' Draw banner text #g "color black" #g "font Courier_New 10" #g "place 5 15" #g "\"; "Score: "; score; " Speed: "; gamespeed; "ms" ' Draw food call drawBlock foodX, foodY, "red" ' Draw snake for i = 1 to snakeLength call drawBlock snakeX(i), snakeY(i), "green" next #g "flush" end sub sub drawBlock x, y, color$ x1 = x * cellSize y1 = gridOffsetY + y * cellSize x2 = x1 + cellSize y2 = y1 + cellSize #g "color "; color$ #g, "backcolor "; color$ #g "place "; x1; " "; y1 #g "boxfilled "; x2; " "; y2 end sub sub newFood overlap = 1 while overlap = 1 foodX = int(rnd(0) * gridWidth) foodY = int(rnd(0) * gridHeight) overlap = 0 for i = 1 to snakeLength if foodX = snakeX(i) and foodY = snakeY(i) then overlap = 1 exit for end if next wend end sub sub gameOver timer 0 #g "cls" #g "color black" #g, "backcolor white" #g "place 110 200" #g "font Courier_New 24 bold" #g "\"; "GAME OVER!" #g "place 110 250" #g "font Courier_New 16" #g "\"; "Score: "; score #g "flush" end sub