Skip to content
Advertisement

Trying to program a basic snake game in python (keeps “crashing”)

So I’m trying to teach myself a little bit of python for fun following this tutorial: https://www.youtube.com/watch?v=8dfePlONtls

I made it to the point where the dot keeps moving automatically (left, right, up or down) depending on which arrow key I pressed last. But for some reason it all stops after a few seconds unless I keep inputting random keys or even just hovering the mouse over the window will do the trick. If I stop doing anything, the program “stops”.

I also noticed the CPU usage going up to 22% for the program when I stop doing anything, but goes back down when I start inputting keys or moving the mouse again.

I’ve tried following exactly what was done in the video but I can’t find any error and pycharm doesn’t detect any obvious error in my code.

Here is what I have so far:

import pygame
from pygame.locals import *
import time


class Snake:
    def __init__(self, parent_screen):
        self.parent_screen = parent_screen
        self.block = pygame.image.load("resources/block.jpg").convert()
        self.x = 100
        self.y = 100
        self.direction = 'down'

    def move_left(self):
        self.direction = 'left'

    def move_right(self):
        self.direction = 'right'

    def move_up(self):
        self.direction = 'up'

    def move_down(self):
        self.direction = 'down'

    def draw(self):
        self.parent_screen.fill((117, 17, 8))
        self.parent_screen.blit(self.block, (self.x, self.y))
        pygame.display.update()

    def walk(self):
        if self.direction == 'left':
            self.x -= 10
        if self.direction == 'right':
            self.x += 10
        if self.direction == 'up':
            self.y -= 10
        if self.direction == 'down':
            self.y += 10

        self.draw()


class Game:
    def __init__(self):
        pygame.init()
        self.surface = pygame.display.set_mode((500, 500))
        self.surface.fill((117, 17, 8))
        self.snake = Snake(self.surface)
        self.snake.draw()

    def run(self):
        running = True

        while running:
            for event in pygame.event.get():
                if event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        running = False
                    if event.key == K_UP:
                        self.snake.move_up()

                    if event.key == K_DOWN:
                        self.snake.move_down()

                    if event.key == K_LEFT:
                        self.snake.move_left()

                    if event.key == K_RIGHT:
                        self.snake.move_right()

                elif event.type == QUIT:
                    running = False

                self.snake.walk()
                time.sleep(0.2)


if __name__ == "__main__":
    game = Game()
    game.run()

Thanks in advance!

Advertisement

Answer

    while running:
        for event in pygame.event.get():
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    running = False
                if event.key == K_UP:
                    self.snake.move_up()

                if event.key == K_DOWN:
                    self.snake.move_down()

                if event.key == K_LEFT:
                    self.snake.move_left()

                if event.key == K_RIGHT:
                    self.snake.move_right()

            elif event.type == QUIT:
                running = False

        self.snake.walk()
        time.sleep(0.2)

Your original code indentation means that you are handling keypresses every pygame event, but also updating your snake every pygame event. Removing the indent on the last two lines which move the snake means they will execute in the outer while loop instead of the event loop. This means the snake will update its position each time the loop runs instead of only when an event occurs.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement