I am helping my boyfriend with his school project. He is making snake using pygame but he is running into a problem. The problem is that every time you make an u-turn the snake dies because it checks if the head is in the same row and column but it does not check the right coordinates I think.
This is his code:
import pygame
import random
import time
pygame.init()
#colors
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
blue = (0, 0, 255)
green = (124,252,0)
pink = (255,105,180)
#display and variables
dis = pygame.display.set_mode((800, 600))
pygame.display.set_caption('Snake')
game_over = False
dis_width = 800
dis_height = 600
stop1 = False
stop2 = False
x1 = dis_width / 2
y1 = dis_height / 2
listx = [x1, x1, x1, x1, x1, x1, x1]
listy = [y1, y1, y1, y1, y1, y1, y1]
x1_change = 0
y1_change = 0
clock = pygame.time.Clock()
snake_block = 1
snake_speed = 25
#fruit
foodx = round(random.randrange(100, dis_width - snake_block) / 25) * 25
foody = round(random.randrange(100, dis_height - snake_block) / 25) * 25
# snake controls
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT and x1_change != snake_speed:
x1_change = -snake_speed
y1_change = 0
elif event.key == pygame.K_RIGHT and x1_change != -snake_speed:
x1_change = snake_speed
y1_change = 0
elif event.key == pygame.K_UP and y1_change != snake_speed:
y1_change = -snake_speed
x1_change = 0
elif event.key == pygame.K_DOWN and y1_change != -snake_speed:
y1_change = snake_speed
x1_change = 0
#grid movement
time.sleep(0.1)
# teleport to other side of map as you go through the map
if listx[0] > dis_width:
game_over = True
if listx[0] < 0:
game_over = True
if listy[0] > dis_height:
game_over = True
if listy[0] < 0:
game_over = True
# determine new value for x and y
newx = listx[0] + x1_change
newy = listy[0] + y1_change
# move list x and y to the right
listx.append(listx.pop(0))
listy.append(listy.pop(0))
# new x and y value for position first block
listx[0] = newx
listy[0] = newy
dis.fill(black)
for blockx, blocky in zip(listx, listy):
pygame.draw.rect(dis, green, [blockx, blocky, 25, 25])
pygame.draw.rect(dis, red, [foodx, foody, 25, 25])
pygame.display.update()
if listx[0] == foodx and listy[0] == foody:
print("yummy")
# new block comes in at the place of the food, only after passing it you see it there (as it should be)
listx.append(listx[-1])
listy.append(listy[-1])
foodx = round(random.randrange(100, dis_width - snake_block) / 25) * 25
foody = round(random.randrange(100, dis_height - snake_block) / 25) * 25
if foodx == listx[0:] and foody == listy[0:]:
foodx = round(random.randrange(100, dis_width - snake_block) / 25) * 25
foody = round(random.randrange(100, dis_height - snake_block) / 25) * 25
if x1_change != 0 or y1_change != 0:
if listy[0] in listy[1:]:
stop1 = True
else:
stop1 = False
if listx[0] in listx[1:]:
stop2 = True
else:
stop2 = False
if stop1 == True:
if stop2 == True:
game_over = True
print("go")
clock.tick(snake_speed)
clock.tick(30)
if game_over == True:
pygame.quit()
quit()
I tried to use this:
if (listx[0], listy[0] in zip(listx[1:], listy[1:])):
stop1 = True
else:
stop1 = False
But now the snake won't die when touching itself because stop2 is still false. But when you make stop2 true the snake just dies immediately.
We don't know how to fix this.