Skip to main content
Tweeted twitter.com/StackCodeReview/status/1135970164296622080
Became Hot Network Question

I am a complete beginner when it comes to programming and writing games and this is my first ever game. I made it with python 3 using pygamepygame library. I would appreciate any feedback really.

from __future__ import annotations
from typing import Tuple, List
import pygame
import random
import sys


# screen width & height and block size
bg_width = 500
bg_height = 500
block_size = 10

# direction strings
left = "LEFT"
right = "RIGHT"
up = "UP"
down = "DOWN"

# colors (RGB)
bg_color = black = (0, 0, 0)
yellow = (255, 255, 0)
green = (0, 128, 0)
red = (255, 0, 0)
blue = (0, 0, 255)

# pygame & font initialization
pygame.init()
window = pygame.display.set_mode((bg_width, bg_height))
pygame.display.set_caption("Snake")
font = pygame.font.SysFont('Times New Roman', 20)
text_colour = pygame.Color('White')
fps = pygame.time.Clock()


class Snake:
    """This class represents a snake object. Every snake object consists of a head
        and its body.
        ===Attributes===
        head: snake head
        color: snake color
        body: snake body
        direction: direction of head
        size: size of snake (head and body)
        """
    head: List[int, int]
    color: Tuple[int, int, int]
    body: List[List[int, int]]
    direction: str
    size: int

    def __init__(self, color: Tuple[int, int, int]) -> None:
        self.head = [int(10*block_size), int(5*block_size)]
        self.color = color
        self.body = [self.head, [9*block_size, 5*block_size]]
        self.direction = right
        self.size = 2

    def change_dir(self, direc: str) -> None:
        if self.direction != left and direc == right:
            self.direction = right
        elif self.direction != right and direc == left:
            self.direction = left
        elif self.direction != down and direc == up:
            self.direction = up
        elif self.direction != up and direc == down:
            self.direction = down

    def move(self) -> None:
        if self.direction == right:
            self.head[0] += block_size
        elif self.direction == left:
            self.head[0] -= block_size
        elif self.direction == up:
            self.head[1] -= block_size
        elif self.direction == down:
            self.head[1] += block_size
        self.body.insert(0, list(self.head))
        self.body.pop()
        if self.body[0] != self.head:
            self.head = self.body[0]

    def add_to_tail(self) -> None:
        new_part = [self.body[-1][0], self.body[-1][1]]
        self.body.append(new_part)
        self.size += 1

    def get_body(self) -> List[List[int, int]]:
        return self.body


class Food:
    """This class represents a food object. Each food object has an x
       and a y value, a color and a state.
       ===Attributes===
       x: x-coordinate of food object
       y: y-coordinate of food object
       color: color of food object
       state: whether food object is on screen or not
       position: x,y-coordinates pair of food object
       """
    x: int
    y: int
    color: Tuple[int, int, int]
    state: bool
    position: Tuple[int, int]

    def __init__(self, color: Tuple[int, int, int]) -> None:
        self.x = random.randint(0, bg_width//block_size - 1)*block_size
        self.y = random.randint(0, bg_height//block_size - 1)*block_size
        self.color = color
        self.state = True
        self.position = self.x, self.y

    def spawn(self) -> Tuple[int, int]:
        if self.state:
            return self.x, self.y
        else:
            self.state = True
            self.x = random.randint(0, bg_width // block_size-1) * block_size
            self.y = random.randint(0, bg_height // block_size-1) * block_size
            return self.x, self.y

    def update(self, state) -> None:
        self.state = state


def collision(snake_: Snake, food_target_x: int, food_target_y: int) -> int:
    snake_rect = pygame.Rect(*snake_.head, block_size, block_size)
    food_rect = pygame.Rect(food_target_x, food_target_y, block_size,
                            block_size)
    if snake_rect == food_rect:
        snake_.add_to_tail()
        return 1
    return 0


def wall_collision(s: Snake) -> bool:
    if (s.head[0] < 0) or (s.head[0] > bg_width-block_size) or (s.head[1] < 0)\
            or (s.head[1] > bg_height-block_size):
        return True
    return False


def game():

    # initialize food and snake
    food = Food(blue)
    snake = Snake(green)

    # initialize loop logic
    running = True
    is_over = False

    # initialize score
    score = 0

    # game loop
    while running:

        # Game over Screen
        while is_over:
            text_on_screen = font.render("You scored: " + str(score) +
                                         ", Press R to play again or Q to quit",
                                         True, text_colour)
            window.blit(text_on_screen, [55, 225])
            for event in pygame.event.get():
                pressed_key = pygame.key.get_pressed()
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if pressed_key[pygame.K_q]:
                    pygame.quit()
                    sys.exit()
                if pressed_key[pygame.K_r]:
                    game()
            pygame.display.update()

        # check events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            pressed = pygame.key.get_pressed()
            if pressed[pygame.K_RIGHT] or pressed[pygame.K_d]:
                snake.change_dir(right)
            elif pressed[pygame.K_LEFT] or pressed[pygame.K_a]:
                snake.change_dir(left)
            elif pressed[pygame.K_UP] or pressed[pygame.K_w]:
                snake.change_dir(up)
            elif pressed[pygame.K_DOWN] or pressed[pygame.K_s]:
                snake.change_dir(down)

        # fill window and draw snake
        window.fill(black)
        for item in snake.get_body():
            pygame.draw.rect(window, snake.color, [item[0], item[1], block_size,
                                                   block_size])

        # move snake
        snake.move()

        # check for collision with wall:
        collision_with_wall = wall_collision(snake)
        if collision_with_wall:
            is_over = True

        # check if food is still on screen and draw it
        food_pos = food.spawn()
        collision_ = collision(snake, *food_pos)
        if collision_ == 1:
            score += 1
            food.update(False)
        pygame.draw.rect(window, food.color, [food_pos[0], food_pos[1],
                                              block_size, block_size])

        # renders display
        pygame.display.flip()

        # time delay
        pygame.time.delay(60)
        fps.tick(30)

    pygame.quit()
    quit()

 
game()
```

I am a complete beginner when it comes to programming and writing games and this is my first ever game. I made it with python 3 using pygame library. I would appreciate any feedback really.

from __future__ import annotations
from typing import Tuple, List
import pygame
import random
import sys


# screen width & height and block size
bg_width = 500
bg_height = 500
block_size = 10

# direction strings
left = "LEFT"
right = "RIGHT"
up = "UP"
down = "DOWN"

# colors (RGB)
bg_color = black = (0, 0, 0)
yellow = (255, 255, 0)
green = (0, 128, 0)
red = (255, 0, 0)
blue = (0, 0, 255)

# pygame & font initialization
pygame.init()
window = pygame.display.set_mode((bg_width, bg_height))
pygame.display.set_caption("Snake")
font = pygame.font.SysFont('Times New Roman', 20)
text_colour = pygame.Color('White')
fps = pygame.time.Clock()


class Snake:
    """This class represents a snake object. Every snake object consists of a head
        and its body.
        ===Attributes===
        head: snake head
        color: snake color
        body: snake body
        direction: direction of head
        size: size of snake (head and body)
        """
    head: List[int, int]
    color: Tuple[int, int, int]
    body: List[List[int, int]]
    direction: str
    size: int

    def __init__(self, color: Tuple[int, int, int]) -> None:
        self.head = [int(10*block_size), int(5*block_size)]
        self.color = color
        self.body = [self.head, [9*block_size, 5*block_size]]
        self.direction = right
        self.size = 2

    def change_dir(self, direc: str) -> None:
        if self.direction != left and direc == right:
            self.direction = right
        elif self.direction != right and direc == left:
            self.direction = left
        elif self.direction != down and direc == up:
            self.direction = up
        elif self.direction != up and direc == down:
            self.direction = down

    def move(self) -> None:
        if self.direction == right:
            self.head[0] += block_size
        elif self.direction == left:
            self.head[0] -= block_size
        elif self.direction == up:
            self.head[1] -= block_size
        elif self.direction == down:
            self.head[1] += block_size
        self.body.insert(0, list(self.head))
        self.body.pop()
        if self.body[0] != self.head:
            self.head = self.body[0]

    def add_to_tail(self) -> None:
        new_part = [self.body[-1][0], self.body[-1][1]]
        self.body.append(new_part)
        self.size += 1

    def get_body(self) -> List[List[int, int]]:
        return self.body


class Food:
    """This class represents a food object. Each food object has an x
       and a y value, a color and a state.
       ===Attributes===
       x: x-coordinate of food object
       y: y-coordinate of food object
       color: color of food object
       state: whether food object is on screen or not
       position: x,y-coordinates pair of food object
       """
    x: int
    y: int
    color: Tuple[int, int, int]
    state: bool
    position: Tuple[int, int]

    def __init__(self, color: Tuple[int, int, int]) -> None:
        self.x = random.randint(0, bg_width//block_size - 1)*block_size
        self.y = random.randint(0, bg_height//block_size - 1)*block_size
        self.color = color
        self.state = True
        self.position = self.x, self.y

    def spawn(self) -> Tuple[int, int]:
        if self.state:
            return self.x, self.y
        else:
            self.state = True
            self.x = random.randint(0, bg_width // block_size-1) * block_size
            self.y = random.randint(0, bg_height // block_size-1) * block_size
            return self.x, self.y

    def update(self, state) -> None:
        self.state = state


def collision(snake_: Snake, food_target_x: int, food_target_y: int) -> int:
    snake_rect = pygame.Rect(*snake_.head, block_size, block_size)
    food_rect = pygame.Rect(food_target_x, food_target_y, block_size,
                            block_size)
    if snake_rect == food_rect:
        snake_.add_to_tail()
        return 1
    return 0


def wall_collision(s: Snake) -> bool:
    if (s.head[0] < 0) or (s.head[0] > bg_width-block_size) or (s.head[1] < 0)\
            or (s.head[1] > bg_height-block_size):
        return True
    return False


def game():

    # initialize food and snake
    food = Food(blue)
    snake = Snake(green)

    # initialize loop logic
    running = True
    is_over = False

    # initialize score
    score = 0

    # game loop
    while running:

        # Game over Screen
        while is_over:
            text_on_screen = font.render("You scored: " + str(score) +
                                         ", Press R to play again or Q to quit",
                                         True, text_colour)
            window.blit(text_on_screen, [55, 225])
            for event in pygame.event.get():
                pressed_key = pygame.key.get_pressed()
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if pressed_key[pygame.K_q]:
                    pygame.quit()
                    sys.exit()
                if pressed_key[pygame.K_r]:
                    game()
            pygame.display.update()

        # check events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            pressed = pygame.key.get_pressed()
            if pressed[pygame.K_RIGHT] or pressed[pygame.K_d]:
                snake.change_dir(right)
            elif pressed[pygame.K_LEFT] or pressed[pygame.K_a]:
                snake.change_dir(left)
            elif pressed[pygame.K_UP] or pressed[pygame.K_w]:
                snake.change_dir(up)
            elif pressed[pygame.K_DOWN] or pressed[pygame.K_s]:
                snake.change_dir(down)

        # fill window and draw snake
        window.fill(black)
        for item in snake.get_body():
            pygame.draw.rect(window, snake.color, [item[0], item[1], block_size,
                                                   block_size])

        # move snake
        snake.move()

        # check for collision with wall:
        collision_with_wall = wall_collision(snake)
        if collision_with_wall:
            is_over = True

        # check if food is still on screen and draw it
        food_pos = food.spawn()
        collision_ = collision(snake, *food_pos)
        if collision_ == 1:
            score += 1
            food.update(False)
        pygame.draw.rect(window, food.color, [food_pos[0], food_pos[1],
                                              block_size, block_size])

        # renders display
        pygame.display.flip()

        # time delay
        pygame.time.delay(60)
        fps.tick(30)

    pygame.quit()
    quit()

 
game()
```

I am a complete beginner when it comes to programming and writing games and this is my first ever game. I made it with python 3 using pygame library. I would appreciate any feedback really.

from __future__ import annotations
from typing import Tuple, List
import pygame
import random
import sys


# screen width & height and block size
bg_width = 500
bg_height = 500
block_size = 10

# direction strings
left = "LEFT"
right = "RIGHT"
up = "UP"
down = "DOWN"

# colors (RGB)
bg_color = black = (0, 0, 0)
yellow = (255, 255, 0)
green = (0, 128, 0)
red = (255, 0, 0)
blue = (0, 0, 255)

# pygame & font initialization
pygame.init()
window = pygame.display.set_mode((bg_width, bg_height))
pygame.display.set_caption("Snake")
font = pygame.font.SysFont('Times New Roman', 20)
text_colour = pygame.Color('White')
fps = pygame.time.Clock()


class Snake:
    """This class represents a snake object. Every snake object consists of a head
        and its body.
        ===Attributes===
        head: snake head
        color: snake color
        body: snake body
        direction: direction of head
        size: size of snake (head and body)
        """
    head: List[int, int]
    color: Tuple[int, int, int]
    body: List[List[int, int]]
    direction: str
    size: int

    def __init__(self, color: Tuple[int, int, int]) -> None:
        self.head = [int(10*block_size), int(5*block_size)]
        self.color = color
        self.body = [self.head, [9*block_size, 5*block_size]]
        self.direction = right
        self.size = 2

    def change_dir(self, direc: str) -> None:
        if self.direction != left and direc == right:
            self.direction = right
        elif self.direction != right and direc == left:
            self.direction = left
        elif self.direction != down and direc == up:
            self.direction = up
        elif self.direction != up and direc == down:
            self.direction = down

    def move(self) -> None:
        if self.direction == right:
            self.head[0] += block_size
        elif self.direction == left:
            self.head[0] -= block_size
        elif self.direction == up:
            self.head[1] -= block_size
        elif self.direction == down:
            self.head[1] += block_size
        self.body.insert(0, list(self.head))
        self.body.pop()
        if self.body[0] != self.head:
            self.head = self.body[0]

    def add_to_tail(self) -> None:
        new_part = [self.body[-1][0], self.body[-1][1]]
        self.body.append(new_part)
        self.size += 1

    def get_body(self) -> List[List[int, int]]:
        return self.body


class Food:
    """This class represents a food object. Each food object has an x
       and a y value, a color and a state.
       ===Attributes===
       x: x-coordinate of food object
       y: y-coordinate of food object
       color: color of food object
       state: whether food object is on screen or not
       position: x,y-coordinates pair of food object
       """
    x: int
    y: int
    color: Tuple[int, int, int]
    state: bool
    position: Tuple[int, int]

    def __init__(self, color: Tuple[int, int, int]) -> None:
        self.x = random.randint(0, bg_width//block_size - 1)*block_size
        self.y = random.randint(0, bg_height//block_size - 1)*block_size
        self.color = color
        self.state = True
        self.position = self.x, self.y

    def spawn(self) -> Tuple[int, int]:
        if self.state:
            return self.x, self.y
        else:
            self.state = True
            self.x = random.randint(0, bg_width // block_size-1) * block_size
            self.y = random.randint(0, bg_height // block_size-1) * block_size
            return self.x, self.y

    def update(self, state) -> None:
        self.state = state


def collision(snake_: Snake, food_target_x: int, food_target_y: int) -> int:
    snake_rect = pygame.Rect(*snake_.head, block_size, block_size)
    food_rect = pygame.Rect(food_target_x, food_target_y, block_size,
                            block_size)
    if snake_rect == food_rect:
        snake_.add_to_tail()
        return 1
    return 0


def wall_collision(s: Snake) -> bool:
    if (s.head[0] < 0) or (s.head[0] > bg_width-block_size) or (s.head[1] < 0)\
            or (s.head[1] > bg_height-block_size):
        return True
    return False


def game():

    # initialize food and snake
    food = Food(blue)
    snake = Snake(green)

    # initialize loop logic
    running = True
    is_over = False

    # initialize score
    score = 0

    # game loop
    while running:

        # Game over Screen
        while is_over:
            text_on_screen = font.render("You scored: " + str(score) +
                                         ", Press R to play again or Q to quit",
                                         True, text_colour)
            window.blit(text_on_screen, [55, 225])
            for event in pygame.event.get():
                pressed_key = pygame.key.get_pressed()
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if pressed_key[pygame.K_q]:
                    pygame.quit()
                    sys.exit()
                if pressed_key[pygame.K_r]:
                    game()
            pygame.display.update()

        # check events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            pressed = pygame.key.get_pressed()
            if pressed[pygame.K_RIGHT] or pressed[pygame.K_d]:
                snake.change_dir(right)
            elif pressed[pygame.K_LEFT] or pressed[pygame.K_a]:
                snake.change_dir(left)
            elif pressed[pygame.K_UP] or pressed[pygame.K_w]:
                snake.change_dir(up)
            elif pressed[pygame.K_DOWN] or pressed[pygame.K_s]:
                snake.change_dir(down)

        # fill window and draw snake
        window.fill(black)
        for item in snake.get_body():
            pygame.draw.rect(window, snake.color, [item[0], item[1], block_size,
                                                   block_size])

        # move snake
        snake.move()

        # check for collision with wall:
        collision_with_wall = wall_collision(snake)
        if collision_with_wall:
            is_over = True

        # check if food is still on screen and draw it
        food_pos = food.spawn()
        collision_ = collision(snake, *food_pos)
        if collision_ == 1:
            score += 1
            food.update(False)
        pygame.draw.rect(window, food.color, [food_pos[0], food_pos[1],
                                              block_size, block_size])

        # renders display
        pygame.display.flip()

        # time delay
        pygame.time.delay(60)
        fps.tick(30)

    pygame.quit()
    quit()

game()
edited tags; edited title
Link
200_success
  • 145.6k
  • 22
  • 191
  • 481

Python Beginner's snake game - beginnerusing PyGame

Source Link

Python snake game - beginner

I am a complete beginner when it comes to programming and writing games and this is my first ever game. I made it with python 3 using pygame library. I would appreciate any feedback really.

from __future__ import annotations
from typing import Tuple, List
import pygame
import random
import sys


# screen width & height and block size
bg_width = 500
bg_height = 500
block_size = 10

# direction strings
left = "LEFT"
right = "RIGHT"
up = "UP"
down = "DOWN"

# colors (RGB)
bg_color = black = (0, 0, 0)
yellow = (255, 255, 0)
green = (0, 128, 0)
red = (255, 0, 0)
blue = (0, 0, 255)

# pygame & font initialization
pygame.init()
window = pygame.display.set_mode((bg_width, bg_height))
pygame.display.set_caption("Snake")
font = pygame.font.SysFont('Times New Roman', 20)
text_colour = pygame.Color('White')
fps = pygame.time.Clock()


class Snake:
    """This class represents a snake object. Every snake object consists of a head
        and its body.
        ===Attributes===
        head: snake head
        color: snake color
        body: snake body
        direction: direction of head
        size: size of snake (head and body)
        """
    head: List[int, int]
    color: Tuple[int, int, int]
    body: List[List[int, int]]
    direction: str
    size: int

    def __init__(self, color: Tuple[int, int, int]) -> None:
        self.head = [int(10*block_size), int(5*block_size)]
        self.color = color
        self.body = [self.head, [9*block_size, 5*block_size]]
        self.direction = right
        self.size = 2

    def change_dir(self, direc: str) -> None:
        if self.direction != left and direc == right:
            self.direction = right
        elif self.direction != right and direc == left:
            self.direction = left
        elif self.direction != down and direc == up:
            self.direction = up
        elif self.direction != up and direc == down:
            self.direction = down

    def move(self) -> None:
        if self.direction == right:
            self.head[0] += block_size
        elif self.direction == left:
            self.head[0] -= block_size
        elif self.direction == up:
            self.head[1] -= block_size
        elif self.direction == down:
            self.head[1] += block_size
        self.body.insert(0, list(self.head))
        self.body.pop()
        if self.body[0] != self.head:
            self.head = self.body[0]

    def add_to_tail(self) -> None:
        new_part = [self.body[-1][0], self.body[-1][1]]
        self.body.append(new_part)
        self.size += 1

    def get_body(self) -> List[List[int, int]]:
        return self.body


class Food:
    """This class represents a food object. Each food object has an x
       and a y value, a color and a state.
       ===Attributes===
       x: x-coordinate of food object
       y: y-coordinate of food object
       color: color of food object
       state: whether food object is on screen or not
       position: x,y-coordinates pair of food object
       """
    x: int
    y: int
    color: Tuple[int, int, int]
    state: bool
    position: Tuple[int, int]

    def __init__(self, color: Tuple[int, int, int]) -> None:
        self.x = random.randint(0, bg_width//block_size - 1)*block_size
        self.y = random.randint(0, bg_height//block_size - 1)*block_size
        self.color = color
        self.state = True
        self.position = self.x, self.y

    def spawn(self) -> Tuple[int, int]:
        if self.state:
            return self.x, self.y
        else:
            self.state = True
            self.x = random.randint(0, bg_width // block_size-1) * block_size
            self.y = random.randint(0, bg_height // block_size-1) * block_size
            return self.x, self.y

    def update(self, state) -> None:
        self.state = state


def collision(snake_: Snake, food_target_x: int, food_target_y: int) -> int:
    snake_rect = pygame.Rect(*snake_.head, block_size, block_size)
    food_rect = pygame.Rect(food_target_x, food_target_y, block_size,
                            block_size)
    if snake_rect == food_rect:
        snake_.add_to_tail()
        return 1
    return 0


def wall_collision(s: Snake) -> bool:
    if (s.head[0] < 0) or (s.head[0] > bg_width-block_size) or (s.head[1] < 0)\
            or (s.head[1] > bg_height-block_size):
        return True
    return False


def game():

    # initialize food and snake
    food = Food(blue)
    snake = Snake(green)

    # initialize loop logic
    running = True
    is_over = False

    # initialize score
    score = 0

    # game loop
    while running:

        # Game over Screen
        while is_over:
            text_on_screen = font.render("You scored: " + str(score) +
                                         ", Press R to play again or Q to quit",
                                         True, text_colour)
            window.blit(text_on_screen, [55, 225])
            for event in pygame.event.get():
                pressed_key = pygame.key.get_pressed()
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if pressed_key[pygame.K_q]:
                    pygame.quit()
                    sys.exit()
                if pressed_key[pygame.K_r]:
                    game()
            pygame.display.update()

        # check events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            pressed = pygame.key.get_pressed()
            if pressed[pygame.K_RIGHT] or pressed[pygame.K_d]:
                snake.change_dir(right)
            elif pressed[pygame.K_LEFT] or pressed[pygame.K_a]:
                snake.change_dir(left)
            elif pressed[pygame.K_UP] or pressed[pygame.K_w]:
                snake.change_dir(up)
            elif pressed[pygame.K_DOWN] or pressed[pygame.K_s]:
                snake.change_dir(down)

        # fill window and draw snake
        window.fill(black)
        for item in snake.get_body():
            pygame.draw.rect(window, snake.color, [item[0], item[1], block_size,
                                                   block_size])

        # move snake
        snake.move()

        # check for collision with wall:
        collision_with_wall = wall_collision(snake)
        if collision_with_wall:
            is_over = True

        # check if food is still on screen and draw it
        food_pos = food.spawn()
        collision_ = collision(snake, *food_pos)
        if collision_ == 1:
            score += 1
            food.update(False)
        pygame.draw.rect(window, food.color, [food_pos[0], food_pos[1],
                                              block_size, block_size])

        # renders display
        pygame.display.flip()

        # time delay
        pygame.time.delay(60)
        fps.tick(30)

    pygame.quit()
    quit()


game()
```