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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With