I am trying to recreate snake in pygame (python 3) and what I am trying to do is every frame, check the velocity of the snake by checking keypress, but it very rarely realises that I am pressing a key, what am I doing wrong/what should I do instead (code is below), I don't see why this isn't working as everything else can run instantly, e.g the clear function, and even handle() which does a very similar thing, so it makes no sense to me as to why it doesn't work
import pygame
from pygame.locals import *
import math
import random
pygame.init()
display = pygame.display.set_mode((512, 512))
pygame.display.set_caption("Snake")
display.fill((255, 255, 255))
def handle():
global x, y
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
def make_apple():
x, y = random.randint(0, 502), random.randint(0, 502)
pygame.draw.rect(display, (255, 0, 0), (x, y, 10, 10))
return x, y
# -- COLLISION DETECTION -- #
def r(fox, foy, cR, sox, soy):
dx = abs(fox - sox)
dy = abs(foy - soy)
if dx < cR and dy < cR:
return True
else:
return False
def clear(aX, aY):
global x, y
display.fill((255, 255, 255))
pygame.draw.rect(display, (255, 0, 0), (aX, aY, 10, 10))
draw_snake(x, y)
def draw_snake(x, y):
pygame.draw.rect(display, (0, 255, 0), (x, y, 10, 10))
def set_vel():
for event in pygame.event.get():
if event.type == KEYDOWN:
print("KEY")
if event.key == K_LEFT:
yVel = 0
xVel = -1
elif event.key == K_RIGHT:
yVel = 0
xVel = 1
elif event.key == K_UP:
yVel = -1
xVel = 0
elif event.key == K_DOWN:
yVel = 1
xVel = 0
return xVel, yVel
return 0, 0
def update_pos(x, y, xV, yV):
x += xV
y += yV
return x, y
aX, aY = make_apple()
x, y = 256, 256
length = 1
eaten = False
while True:
velX, velY = set_vel()
clear(aX, aY)
handle()
x, y = update_pos(x, y, velX, velY)
if eaten:
aX, aY = make_apple()
eaten = False
pygame.display.update()
if r(x, y, 3, aX, aY):
display.fill((255, 255, 255))
eaten = True
Your problem is that when you call pygame.event.get()
, that function not only gets the events, but also removes them from the queue. This means calling it twice per frame (as you do in set_vel
and handle
) can give weird results.
When I write pygame, I have one for event in pygame.event.get()
loop in my while True
. Try doing this and move the quit handling and velocity changing into the True
loop instead of their own functions.