(07-20-2024, 06:50 PM)aliensoldier Wrote:(07-20-2024, 09:23 AM)Marcus Wrote: Here's a port of an n6 example game. Hopefully you can find some clues by looking at the code I don't remember why I implemented the game like this, and probably there are smarter ways.I'll see if I can understand the code where the body follows the head, thank you.
Code:' Port of n6 example game.
SNAKE_MAX_LENGTH = 30*40
UP = 1
DOWN = 2
LEFT = 3
RIGHT = 4
snake = dim(SNAKE_MAX_LENGTH, 2)
level = dim(40, 30)
set window "Smape", 320, 240, false, 2
set redraw off
do
snakeLength = 1
snakeHead = 0
snakeDirection = 0
speed = 10
speedCounter = speed
snake[snakeHead][0] = 20
snake[snakeHead][1] = 15
for y = 0 to 29 for x = 0 to 39 level[x][y] = 0
gameOver = false
nextPlupTime = clock()
do
if clock() >= nextPlupTime
if rnd(3) = 0 level[rnd(40)][rnd(30)] = 2
else level[rnd(40)][rnd(30)] = 1
nextPlupTime = clock() + 2000 + rnd(2000)
endif
if keydown(38) and snakeDirection <> DOWN snakeDirection = UP
if keydown(40) and snakeDirection <> UP snakeDirection = DOWN
if keydown(37) and snakeDirection <> RIGHT snakeDirection = LEFT
if keydown(39) and snakeDirection <> LEFT snakeDirection = RIGHT
speedCounter = speedCounter - 1
if speedCounter = 0
prev = snakeHead
if snakeDirection > 0 snakeHead = (snakeHead + 1)%SNAKE_MAX_LENGTH
speedCounter = speed
if snakeDirection = UP
snake[snakeHead][0] = snake[prev][0]
snake[snakeHead][1] = snake[prev][1] - 1
elseif snakeDirection = DOWN
snake[snakeHead][0] = snake[prev][0]
snake[snakeHead][1] = snake[prev][1] + 1
elseif snakeDirection = LEFT
snake[snakeHead][0] = snake[prev][0] - 1
snake[snakeHead][1] = snake[prev][1]
elseif snakeDirection = RIGHT
snake[snakeHead][0] = snake[prev][0] + 1
snake[snakeHead][1] = snake[prev][1]
endif
x = snake[snakeHead][0]
y = snake[snakeHead][1]
if x < 0 or x >= 40 or y < 0 or y >= 30
gameOver = true
else
if level[x][y] > 0
snakeLength = snakeLength + 1
if level[x][y] = 2 speed = max(speed - 1, 0)
level[x][y] = 0
endif
endif
endif
set color 0, 0, 0
cls
for y = 0 to 29
for x = 0 to 39
if level[x][y] = 1
set color 0, 255, 0
draw rect x*8, y*8, 8, 8 , true
elseif level[x][y] = 2
set color 255, 0, 0
draw rect x*8, y*8, 8, 8, true
endif
next
next
set color 255, 255, 255
set caret 0, 0
x = snake[snakeHead][0]
y = snake[snakeHead][1]
for i = snakeHead to snakeHead - snakeLength + 1
j = i
if j < 0 then j = j + SNAKE_MAX_LENGTH
draw rect snake[j][0]*8, snake[j][1]*8, 8, 8, true
if i <> snakeHead
if snake[j][0] = x and snake[j][1] = y then gameOver = true
endif
next
wait 10
redraw
until gameOver
loop
I barely looked at the code. But I believe the snake "moves" through the 'snake' array. Every element in the array contains a position (x and y value). The snake's head is a moving index in the array. Every time the snake moves one step, the head index increases and a new position is added to the array. That way, the tail is always present as earlier indexes in the array. So if the length of the snake is 4, the positions drawn are those at snake[snakeHead], snake[snakeHead - 1] .. snake[snakeHead - 3].
Edit: The % operator is used to keep the indexes within the array size. When the snake head index reaches the end of the array it starts over at 0. The length of the array is exactly enough for the snake to cover the entire screen
You can probably write smarter code that just stores the turns that the snake does or something. But that would require more complicated code ... I think