Home > Enterprise >  Pygame is not responding when code is run
Pygame is not responding when code is run

Time:03-01

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.

  • Related