Pygame Snake, Pt. 4
Source: Dev.to
Introduction
In Parts 1, 2, & 3 we assembled everything except the actual game logic. Now we’ll add the snake mechanics.
Replace the single dot with a snake list
Change the original definition:
dot = pygame.Vector2(W / 2, H / 2)
to:
snake = [pygame.Vector2(W / 2, H / 2)]
Add a growth counter
Just above the while loop, introduce:
grow = 3
This starts the snake with a length of 4.
Update the game loop
Compute the new head position
Replace dot += vel with:
new_head = snake[-1] + vel
Detect self‑collision
if new_head in snake:
print("hit self")
break
Append the new head
snake.append(new_head)
Handle growth vs. normal movement
if grow > 0:
grow -= 1
else:
snake.pop(0)
Draw the whole snake
Find the two lines that previously drew the single dot:
square = pygame.Rect(dot * S, (S, S))
screen.fill("black", square)
Replace them with a loop that draws every segment:
for dot in snake:
square = pygame.Rect(dot * S, (S, S))
screen.fill("black", square)
Full code at this point
import pygame
import random
W = 30
H = 30
S = 20
# pygame setup
pygame.init()
screen = pygame.display.set_mode((W * S, H * S))
clock = pygame.time.Clock()
running = True
# game setup
snake = [pygame.Vector2(W / 2, H / 2)]
vel = pygame.Vector2(1, 0)
key_vel = {
pygame.K_RIGHT: pygame.Vector2(1, 0),
pygame.K_DOWN: pygame.Vector2(0, 1),
pygame.K_LEFT: pygame.Vector2(-1, 0),
pygame.K_UP: pygame.Vector2(0, -1)
}
grow = 3
def place_food():
global food_pos
food_pos = pygame.Vector2(
random.randrange(W),
random.randrange(H)
)
while food_pos in snake:
food_pos = pygame.Vector2(
random.randrange(W),
random.randrange(H)
)
place_food()
while running:
# poll for events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and event.key in key_vel:
vel = key_vel[event.key]
# clear screen
screen.fill("white")
new_head = snake[-1] + vel
if new_head in snake:
print("hit self")
break
if new_head == food_pos:
grow += 1
place_food()
snake.append(new_head)
if grow > 0:
grow -= 1
else:
snake.pop(0)
for dot in snake:
square = pygame.Rect(dot * S, (S, S))
screen.fill("black", square)
square = pygame.Rect(food_pos * S, (S, S))
screen.fill("green", square)
# update display
pygame.display.flip()
# limit FPS
clock.tick(20)
pygame.quit()
Next steps
Continue with the next part of the tutorial: Part 5.