192 lines
4.0 KiB
Plaintext
192 lines
4.0 KiB
Plaintext
' ================================
|
|
' 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
|