Игра «Змейка» на Python c использованием модуля Pygame

Змейка — одна из самых популярных аркадных игр всех времен. В этой игре основная цель игрока – поймать максимальное количество фруктов, не ударившись о стену или себя. Создание игры может стать проблемой при изучении Python или Pygame. Это один из лучших проектов для начинающих, который каждый начинающий программист должен принять как вызов. Научиться создавать видеоигры довольно интересно и весело.

Мы будем использовать Pygame для создания этой игры . Pygame — это библиотека с открытым исходным кодом, предназначенная для создания видеоигр. Она имеет встроенные графические и звуковые библиотеки.

Установка
Чтобы установить Pygame, вам нужно открыть терминал или командную строку и ввести следующую команду:

pip install pygame

Шаг 1: Сначала мы импортируем необходимые библиотеки.

После этого мы определяем ширину и высоту окна, в котором будет проходить игра.
И определим цвет в формате RGB, который мы будем использовать в нашей игре для отображения текста.

# importing libraries
import pygame
import time
import random
 
snake_speed = 15
 
# Window size
window_x = 720
window_y = 480
 
# defining colors
black = pygame.Color(0, 0, 0)
white = pygame.Color(255, 255, 255)
red = pygame.Color(255, 0, 0)
green = pygame.Color(0, 255, 0)
blue = pygame.Color(0, 0, 255)

Шаг 2: После импорта библиотек нам нужно инициализировать Pygame с помощью метода pygame.init().

Создадим игровое окно, используя ширину и высоту, определенные на предыдущем шаге.
Здесь pygame.time.Clock() будет использоваться дальше в основной логике игры для изменения скорости змейки.

# Initialising pygame
pygame.init()
 
# Initialise game window
pygame.display.set_caption('GeeksforGeeks Snakes')
game_window = pygame.display.set_mode((window_x, window_y))
 
# FPS (frames per second) controller
fps = pygame.time.Clock()

Шаг 3: Инициализируем положение змейки и ее размер.

После инициализации положения змейки инициализируем положение фруктов случайным образом в любом месте заданной высоты и ширины.
Установив направление ВПРАВО, мы гарантируем, что всякий раз, когда пользователь запускает программу/игру, змейка должна двигаться вправо к экрану.

# defining snake default position
snake_position = [100, 50]
 
# defining first 4 blocks of snake
# body
snake_body = [  [100, 50],
                [90, 50],
                [80, 50],
                [70, 50]
            ]
# fruit position
fruit_position = [random.randrange(1, (window_x//10)) * 10,
                  random.randrange(1, (window_y//10)) * 10]
fruit_spawn = True
 
# setting default snake direction
# towards right
direction = 'RIGHT'
change_to = direction

Шаг 4: Создадим функцию для отображения счета игрока.

В этой функции, во-первых, мы создаем объект шрифта.
Затем мы используем рендеринг для создания фоновой поверхности, которую мы будем менять при каждом обновлении нашей игры.
Создадим прямоугольный объект для объекта текстовой поверхности (где текст будет обновляться)
Затем мы отобразим счет, используя blit. blit , который принимает два аргумента screen.blit(background,(x,y))

# initial score
score = 0
 
# displaying Score function
def show_score(choice, color, font, size):
   
    # creating font object score_font
    score_font = pygame.font.SysFont(font, size)
     
    # create the display surface object
    # score_surface
    score_surface = score_font.render('Score : ' + str(score), True, color)
     
    # create a rectangular object for the
    # text surface object
    score_rect = score_surface.get_rect()
     
    # displaying text
    game_window.blit(score_surface, score_rect)

Шаг 5: Теперь создадим функцию завершения игры, которая будет отображать счет после того, как змейка ударится о стену или о саму себя.

В первой строке мы создаем объект шрифта для отображения результатов.
Затем мы создадим текстовые поверхности для рендеринга партитуры.
После этого мы устанавим положение текста в середине игровой области.
Отобразим результаты с помощью blit и обновите счет, обновив поверхность с помощью flip().
Мы используем sleep(2), чтобы подождать 2 секунды, прежде чем закрыть окно с помощью quit().

# game over function
def game_over():
   
    # creating font object my_font
    my_font = pygame.font.SysFont('times new roman', 50)
     
    # creating a text surface on which text
    # will be drawn
    game_over_surface = my_font.render('Your Score is : ' + str(score), True, red)
     
    # create a rectangular object for the text
    # surface object
    game_over_rect = game_over_surface.get_rect()
     
    # setting position of the text
    game_over_rect.midtop = (window_x/2, window_y/4)
     
    # blit will draw the text on screen
    game_window.blit(game_over_surface, game_over_rect)
    pygame.display.flip()
     
    # after 2 seconds we will quit the
    # program
    time.sleep(2)
     
    # deactivating pygame library
    pygame.quit()
     
    # quit the program
    quit()

Шаг 6: Теперь мы создадим нашу основную функцию, которая будет делать следующие вещи:

Мы будем проверять ключи, которые будут отвечать за движение змейки, а затем создадим специальное условие, при котором змея не должна двигаться в противоположном направлении мгновенно.
После этого, если змейка и фрукт столкнутся, мы увеличим счет на 10, и новый фрукт будет инициализоравн.
После этого проверяем, ударилась змейка о стену или нет. Если змейка ударится о стену, мы вызовем функцию Game Over.
Если змейка ударит себя так же будет вызвана функция окончания Game Over.
И, наконец, мы будем отображать результаты с помощью созданной ранее функции show_score.

# Main Function
while True:
   
    # handling key events
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                change_to = 'UP'
            if event.key == pygame.K_DOWN:
                change_to = 'DOWN'
            if event.key == pygame.K_LEFT:
                change_to = 'LEFT'
            if event.key == pygame.K_RIGHT:
                change_to = 'RIGHT'
 
    # If two keys pressed simultaneously
    # we don't want snake to move into two directions
    # simultaneously
    if change_to == 'UP' and direction != 'DOWN':
        direction = 'UP'
    if change_to == 'DOWN' and direction != 'UP':
        direction = 'DOWN'
    if change_to == 'LEFT' and direction != 'RIGHT':
        direction = 'LEFT'
    if change_to == 'RIGHT' and direction != 'LEFT':
        direction = 'RIGHT'
 
    # Moving the snake
    if direction == 'UP':
        snake_position[1] -= 10
    if direction == 'DOWN':
        snake_position[1] += 10
    if direction == 'LEFT':
        snake_position[0] -= 10
    if direction == 'RIGHT':
        snake_position[0] += 10
 
    # Snake body growing mechanism
    # if fruits and snakes collide then scores will be
    # incremented by 10
    snake_body.insert(0, list(snake_position))
    if snake_position[0] == fruit_position[0] and snake_position[1] == fruit_position[1]:
        score += 10
        fruit_spawn = False
    else:
        snake_body.pop()
         
    if not fruit_spawn:
        fruit_position = [random.randrange(1, (window_x//10)) * 10,
                          random.randrange(1, (window_y//10)) * 10]
         
    fruit_spawn = True
    game_window.fill(black)
     
    for pos in snake_body:
        pygame.draw.rect(game_window, green, pygame.Rect(
          pos[0], pos[1], 10, 10))
         
    pygame.draw.rect(game_window, white, pygame.Rect(
      fruit_position[0], fruit_position[1], 10, 10))
 
    # Game Over conditions
    if snake_position[0] < 0 or snake_position[0] > window_x-10:
        game_over()
    if snake_position[1] < 0 or snake_position[1] > window_y-10:
        game_over()
     
    # Touching the snake body
    for block in snake_body[1:]:
        if snake_position[0] == block[0] and snake_position[1] == block[1]:
            game_over()
     
    # displaying score countinuously
    show_score(1, white, 'times new roman', 20)
     
    # Refresh game screen
    pygame.display.update()
 
    # Frame Per Second /Refresh Rate
    fps.tick(snake_speed)

Ответить