For some reason when I try to run my snake game, it always says not responding. It used to work before but it seems to have stopped now. It also doesn't seem to work in replit. I'm pretty new to pygame so I've never had this issue before. I've tried re-running it and making small edits but nothing has worked thus far. Why is this and how can I fix it?
Here's the code:
import random
# initialize pygame
pygame.init()
# defining colour variables using rgb
white = (255, 255, 255)
pink = (255, 158, 208)
black = (0, 0, 0)
red = (213, 50, 80)
yellow = (237, 255, 41)
blue = (50, 153, 213)
# screen width and height
WIN_WIDTH = 600
WIN_HEIGHT = 400
# set the window, valid arguments are width and height
WIN = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))
pygame.display.set_caption('snake game')
clock = pygame.time.Clock()
# size the snake (rectangle)
snake_block = 10
# set the snakes velocity (speed)
VEL = 15
# define fonts, valid arguments are the font name and size
font_style = pygame.font.SysFont('bahnschrift', 25)
score_font = pygame.font.SysFont('impact', 30)
# score function
def score(score):
text = score_font.render(' Score: ' str(score), True, pink) # create the score
WIN.blit(text, [0, 0]) # using blit to add the text to the screen
# snake function, passing in snake block and snake list (see game loop)
def snake(snake_block, snake_list):
for x in snake_list:
pygame.draw.rect(WIN, black, [x[0], x[1], snake_block, snake_block]) # creating the snake rectangle
def message(msg, colour):
msg = font_style.render(msg, True, colour) # renders a font
WIN.blit(msg, [WIN_WIDTH / 6, WIN_HEIGHT / 3]) # blits the msg coordinates
# main gameloop function
def gameLoop():
# boolean variables
game_over = False
game_close = False
# x and y variables for where the snake will be placed
x1 = WIN_WIDTH / 2
y1 = WIN_HEIGHT / 2
# create x and y change variables to update the coordinates
x1_change = 0
y1_change = 0
# creating an empty list for the snakes length
snake_List = []
Length_of_snake = 1
# add a randomly placed rectangle that will act as the food (x, y)
foodx = round(random.randrange(0, WIN_WIDTH - snake_block) / 10.0) * 10.0
foody = round(random.randrange(0, WIN_HEIGHT - snake_block) / 10.0) * 10.0
# while the game isn't over
while not game_over:
# while game close is true
while game_close:
# turn the screen blue
WIN.fill(blue)
# add losing text
message('You Lost! Press C to Play Again or Q to Quit', red)
# sets the score for when you lost
score(Length_of_snake - 1)
pygame.display.update()
# pygame events
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit() # making it so when the user clicks the x the game closes
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q: # same thing as the x in the corner, but you can press q
game_over = True
game_close = False
if event.key == pygame.K_c: # replay the game
gameLoop() # calls the main function (restarts)
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
if event.type == pygame.KEYDOWN: # keydown is another event, for using the keyboard to do stuff
if event.key == pygame.K_a: # if the a key is pressed, x1_change = -snake_block, which is equal to 10. this moves the rectangle to the left
x1_change = -snake_block
y1_change = 0
if event.key == pygame.K_d: # if the d key is pressed, x1_change = snake_block, which is equal to 10. this moves the rectangle to the right
x1_change = snake_block
y1_change = 0
if event.key == pygame.K_w: # if the w key is pressed, y1_change = -snake_block, which is equal to 10. this moves the rectangle up
y1_change = -snake_block
x1_change = 0
if event.key == pygame.K_s: # if the s key is pressed, y1_change = snake_block, which is equal to 10. this moves the rectangle down
y1_change = snake_block
x1_change = 0
if x1 >= WIN_WIDTH or x1 < 0 or y1 >= WIN_HEIGHT or y1 < 0: # if the x or y positions of the snake go over the screen width or height
game_close = True # you lose
x1 = x1_change
y1 = y1_change
WIN.fill(blue)
pygame.draw.rect(WIN, yellow, [foodx, foody, snake_block, snake_block])
snake_Head = [] # create a snake head empty list
snake_Head.append(
x1) # append lets us add something to a list, in this case x1 and y1 are added to the snake_head list
snake_Head.append(y1)
snake_List.append(snake_Head) # add snake head to snake list
if len(snake_List) > Length_of_snake: # len returns the length of something, in this case snake list, so if snake list is greater than the snakes length
del snake_List[0] # del means delete, so delete the first value in snake list, index 0
for i in snake_List[:-1]:
if i == snake_Head: # if the snake head hits itself
game_close = True # you lose
snake(snake_block, snake_List)
score(Length_of_snake - 0)
pygame.display.update() # update the screen
if x1 == foodx and y1 == foody: # if you hit the food
foodx = round(
random.randrange(0, WIN_WIDTH - snake_block) / 10.0) * 10.0 # generate a new random food position
foody = round(random.randrange(0, WIN_HEIGHT - snake_block) / 10.0) * 10.0
Length_of_snake = 1 # add 1 to the snakes length
clock.tick(VEL) # valid arguments are a number (frames per second)
# oposite of pygame.init, quit
pygame.quit()
# quit the program
quit()
# call the gameloop function
gameLoop()
CodePudding user response:
See Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?. pygame.event.get()
get all the messages and remove them from the queue. See the documentation:
This will get all the messages and remove them from the queue. [...]
If pygame.event.get()
is called in multiple event loops, only one loop receives the events, but never all loops receive all events. As a result, some events appear to be missed. Only implement 1 event loop.
Do not call the gameLoop
recursively, but run the game in a loop. Calling the main function recursively will mess up your variables and actually result in a game running within a game.
e.g.:
def gameLoop():
# run the game in a loop multiple times
game_close = False
while not game_close:
# init game states
x1 = WIN_WIDTH / 2
y1 = WIN_HEIGHT / 2
# [...]
# application loop
game_over = False
while not game_over:
# [...]
# pygame events
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
game_close = True
if event.type == pygame.KEYDOWN: # keydown is another event, for using the keyboard to do stuff
if event.key == pygame.K_q: # same thing as the x in the corner, but you can press q
game_over = True
game_close = True
if event.key == pygame.K_c: # replay the game
game_over = True
if event.key == pygame.K_a: # if the a key is pressed, x1_change = -snake_block, which is equal to 10. this moves the rectangle to the left
x1_change = -snake_block
y1_change = 0
# [...]
CodePudding user response:
From my experience having a while loop inside of a while loop does tend to cause crashes and freezes. Try avoid that and it should be fine.