Snake version 2

A different user evet type of management in this snake game version.

import pygame
from pygame import gfxdraw
import random


# Define Constants

BOARD_SIZE = 20  # Size of the board, in block
BLOCK_SIZE = 20  # Size of 1 block, in pixel
GAME_SPEED = 8  # Game speed (Normal = 10), The bigger, the faster
SIZE = (BOARD_SIZE * BLOCK_SIZE, BOARD_SIZE * BLOCK_SIZE)
window = pygame.display.set_mode(SIZE)
pygame.display.set_caption("window")
score = 0


# ============================ THE SNAKE POSITION AND BEHAVIOUR ======

class Snake():
    def __init__(self):
        self.starting_position()

    def starting_position(self):
        "The coordinates of the start and direction are here"

        self.head = [
            # self.head[0] = x = 5
            int(BOARD_SIZE / 4),
            # self.head[1] = x = 5
            int(BOARD_SIZE / 4)]
        self.body = [[self.head[0], self.head[1]],
                     [self.head[0] - 1, self.head[1]],
                     [self.head[0] - 2, self.head[1]]
                     ]
        #   [ ][ ][ ] => right
        self.direction = "RIGHT"

    def change_direction_to(self, dir):
        "When you hit a key in the while loop; avoid going backwards"
        if dir == "RIGHT" and not self.direction == "LEFT":
            self.direction = "RIGHT"
        if dir == "LEFT" and not self.direction == "RIGHT":
            self.direction = "LEFT"
        if dir == "UP" and not self.direction == "DOWN":
            self.direction = "UP"
        if dir == "DOWN" and not self.direction == "UP":
            self.direction = "DOWN"

    def move(self, food_pos):
        "Continue to move in the dir, place one square forward, delete last"
        # if do not eat, return 1 if you eat
        # so that in the while loop... score += 1 GAME_SPEED +=1 food_spawn
        if self.direction == "RIGHT":
            self.head[0] += 1
        if self.direction == "LEFT":
            self.head[0] -= 1
        if self.direction == "UP":
            self.head[1] -= 1
        if self.direction == "DOWN":
            self.head[1] += 1
        # [][][]
        self.body.insert(0, list(self.head))
        # [][][][]
        if self.head == food_pos:
            # [][][][]  it grows after he ate
            return 1
        else:
            "If do not eat... same size"
            self.body.pop()
            # pop([])   [][][]  it stays of the same size, but moves
            return 0

    def check_collision(self):
        # Checks collision with border or himself

        conditions = (
            # x axis limits  <0 ..... >20
            self.head[0] >= 20 or self.head[0] < 0,
            # y axis
            self.head[1] > 19 or self.head[1] < 0,
            # checks if you hit yourself
            # comprehension list - a for loop with a python syntax
            [x for x in self.body[1:] if self.head == x]
        )
        if any(conditions):
            return 1
        else:
            return 0

# ============================= SPAWN FOOD =======================

class FoodSpawner():
    def __init__(self):
        self.food_pos = [random.randrange(1, BOARD_SIZE), random.randrange(1, BOARD_SIZE)]
        self.is_food_on_screen = True

    def spawn_food(self):
        if self.is_food_on_screen == False:
            self.food_pos = [random.randrange(1, BOARD_SIZE), random.randrange(1, BOARD_SIZE)]
            self.is_food_on_screen = True
        return self.food_pos

    def set_food_on_screen(self, bool_value):
        self.is_food_on_screen = bool_value


# ===================== DRAW HEAD, BODY and FOOD ================


def draw_head(pos):
    pygame.draw.rect(
        window,
        (0, 255, 0),
        pygame.Rect(
            pos[0] * BLOCK_SIZE,
            pos[1] * BLOCK_SIZE,
            BLOCK_SIZE,
            BLOCK_SIZE))

def draw_body(pos):
    pygame.draw.rect(window, (0, 128, 0), pygame.Rect(pos[0] * BLOCK_SIZE, pos[1] * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))

def delete_tail(pos):
    pygame.draw.rect(window, (0, 0, 0), pygame.Rect(snake.body[-1][0] * BLOCK_SIZE, snake.body[-1][1] * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))

def delete_fruit(pos, food_pos):
    x = food_pos[0] * BLOCK_SIZE + 10
    y = food_pos[1] * BLOCK_SIZE + 10
    r = 9
    gfxdraw.filled_circle(window, x, y, r, (0, 0, 0))

def draw_fruit(food_pos):
    gfxdraw.filled_circle(window, food_pos[0] * BLOCK_SIZE + 10, food_pos[1] * BLOCK_SIZE + 10, 9, (255, 0, 0))


# =========== To write on the window surface on the screen ========

def write(text_to_show, x=0, y=0, middle="both"):
    "It write in the middle by default, if not middle='both' middle='x'"
    text = font.render(text_to_show, 1, pygame.Color("Coral"))
    if middle == "x":
        text_rect = text.get_rect(center=((size // 2, y)))
        window.blit(text, text_rect)      
    elif middle == "both":
        text_rect = text.get_rect(center=((size // 2, size // 2)))
        window.blit(text, text_rect)
    else:
        window.blit(text, (x, y))
    pygame.display.update()


# ================================= MANAGE GAME PART =================

def restart():
    global GAME_SPEED

    GAME_SPEED = 8
    window.fill((0, 0, 0))
    snake.starting_position()
    start()


def press_to_start():
    "Initial menu"
    global loop, snake, food_spawner
    global font, size

    pygame.init()
    font = pygame.font.SysFont("Arial", 24)
    size = BOARD_SIZE * BLOCK_SIZE # 400 20x20
    snake = Snake()
    food_spawner = FoodSpawner()
    write("Python vs Snake", y=30, middle="x")
    write("Press s to start")
    while True:
        event = pygame.event.wait()
        if event.type == pygame.QUIT:
            loop = 0
            break
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                loop = 0
                break
            if event.key == pygame.K_s:
                restart()
                break
    pygame.quit()


def start():
    "Starts the game"
    global GAME_SPEED, score, loop

    clock = pygame.time.Clock()
    food_pos = food_spawner.spawn_food()
    loop = 1
    while loop:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                loop = 0
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    loop = 0
                elif event.key == pygame.K_RIGHT:
                    snake.change_direction_to("RIGHT")
                elif event.key == pygame.K_UP:
                    snake.change_direction_to("UP")
                elif event.key == pygame.K_DOWN:
                    snake.change_direction_to("DOWN")
                elif event.key == pygame.K_LEFT:
                    snake.change_direction_to("LEFT")
        if snake.move(food_pos) == 1:
            # delete_fruit(pos, food_pos)
            score += 1
            food_spawner.set_food_on_screen(False)
            GAME_SPEED += 1
            food_pos = food_spawner.spawn_food()

        head = 1
        for pos in snake.body:
            if head == 1:
                draw_head(pos)
                head = 0
            else:
                draw_body(pos)
        delete_tail(pos)
        draw_fruit(food_pos)

        if snake.check_collision() == 1:
            loop = 0
            press_to_start()
        pygame.display.update()
        clock.tick(GAME_SPEED)

    pygame.quit()

press_to_start()

 


Subscribe to the newsletter for updates
Tkinter templates
My youtube channel

Twitter: @pythonprogrammi - python_pygame

Videos

Speech recognition game

Pygame's Platform Game

Other Pygame's posts