Создание Flappy Bird с помощью pygame. Часть — 0


Введение

Я создаю знаменитую игру Flappy bird, используя python и его библиотеку под названием «pygame». Она очень проста в создании и очень увлекательна в игре. Она требует всего 200 строк кода. Существует веб-версия этой игры, которую вы можете найти на сайте flappybird.io.

О Flappy

Flappy Bird — мобильная игра, разработанная вьетнамским художником и программистом Донг Нгуеном (вьетнамский: Nguyễn Hà Đông) под руководством его компании по разработке игр Gears. Игра представляет собой сайд-скроллер, в котором игрок управляет птицей, пытающейся пролететь между колоннами зеленых труб, не задев их. Нгуен создавал игру в течение нескольких дней, используя птицу-протагониста, которую он разработал для отмененной игры в 2012 году.

Pygame

pygame — это обертка Python для библиотеки SDL, которая расшифровывается как Simple DirectMedia Layer. SDL обеспечивает кроссплатформенный доступ к базовым мультимедийным аппаратным компонентам вашей системы, таким как звук, видео, мышь, клавиатура и джойстик. pygame начал свою жизнь как замена заглохшему проекту PySDL. Кроссплатформенность SDL и pygame означает, что вы можете писать игры и насыщенные мультимедийные Python-программы для любой платформы, которая их поддерживает!

Установите pygame с помощью pip, если у вас уже установлен python.

pip install pygame
Вход в полноэкранный режим Выйдите из полноэкранного режима

Импортируйте его в вашу программу на python и инициализируйте.

import pygame
pygame.init()
Войти в полноэкранный режим Выход из полноэкранного режима

Проект

Создайте папку проекта с именем flappy и создайте в ней python файл с именем flappy.py.

Активы

Для создания этой игры нам понадобятся некоторые спрайты. Три спрайта птиц с анимированными крыльями, зеленые трубы, земля, фон и кнопка перезапуска. Вы можете найти активы здесь
Скачайте активы и сохраните их в папке с именем img.
Структура файла будет выглядеть следующим образом.

flappy
|
| -- img
      |
      -- bg.png
      -- bird1.png
      -- bird2.png
      -- bird3.png
      -- ground.png
      -- pipe.png
      -- restart.png
|
| -- flappy.py
Вход в полноэкранный режим Выход из полноэкранного режима

Базовая настройка

начните работу над кодом, импортировав необходимые модули.

import pygame
from pygame.locals import *
import random
Вход в полноэкранный режим Выход из полноэкранного режима

Модуль pygame.locals содержит различные константы, используемые pygame. Мы используем random для генерации случайных труб в сайдскроллере.

Инициализация pygame

pygame.init()
Войти в полноэкранный режим Выйти из полноэкранного режима

Определите высоту и ширину экрана, чтобы мы могли создать окно.

screen_width = 460
screen_height = 500

screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Flappy Bird')
Войти в полноэкранный режим Выход из полноэкранного режима

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

run = True
while run:
   pass
Вход в полноэкранный режим Выход из полноэкранного режима

Не забудьте выйти из pygame в конце кода

pygame.quit()
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь запустите программу python из терминала.

python3 flappy.py
Войти в полноэкранный режим Выйти из полноэкранного режима

Это откроет новое пустое окно с высотой и шириной, которые мы определили ранее. Но теперь мы не сможем закрыть окно, кроме как прервав терминал. Это происходит потому, что мы не указали циклу прерваться, когда пользователь закроет окно, и это вызовет pygame.quit() в конце кода.

Мы должны перебрать все события pygame и проверить, является ли это событием закрытия. Затем придать run значение false, что прервет цикл.

for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь мы сможем закрыть окно после запуска программы.

Фон

Сначала нарисуем фон. Для этого импортируйте спрайт bg из папки img и отмасштабируйте его в соответствии с размером экрана.

bg = pygame.image.load('img/bg.png')
bg = pygame.transform.scale(bg, (460, 420))
Вход в полноэкранный режим Выйдите из полноэкранного режима

И внутри цикла перерисуйте bg с помощью функции blit.

# draw background
screen.blit(bg, (0,0))
Войти в полноэкранный режим Выйти из полноэкранного режима

также добавьте функцию обновления в конце цикла

pygame.display.update()
Вход в полноэкранный режим Выход из полноэкранного режима

Запустите программу, и вы увидите фон.

Земля

Импортируйте изображение земли так же, как мы импортировали фон.

ground_img = pygame.image.load('img/ground.png')
ground_img = pygame.transform.scale(ground_img, (480, 80))
Войти в полноэкранный режим Выйдите из полноэкранного режима

Также объявите некоторые переменные, чтобы сделать землю прокручиваемой.

# game variables
ground_scroll = 0
scroll_speed = 2
Вход в полноэкранный режим Выход из полноэкранного режима

Внутри цикла, сразу после рисования земли, нарисуйте землю с ground_scroll в качестве значения x. Также обновите ground_scroll с помощью scroll_speed.

# draw ground
screen.blit(ground_img, (ground_scroll, 420))
ground_scroll -= scroll_speed
Вход в полноэкранный режим Выход из полноэкранного режима

Также нам нужно сбросить значение ground_scroll на 0 после того, как оно пройдет 20, чтобы получить непрерывную прокрутку.

if abs(ground_scroll) > 20:
        ground_scroll = 0
Вход в полноэкранный режим Выход из полноэкранного режима

FPS

Теперь земля прокручивается очень быстро, и мы должны контролировать fps. Иначе fps может отличаться на разных компьютерах. Поэтому в верхней части объявите fps и pygame clock.

# fps control
clock = pygame.time.Clock()
fps = 60
Вход в полноэкранный режим Выход из полноэкранного режима

Внутри цикла, в верхней части вызовите функцию tick, используя переменную fps.

clock.tick(fps)
Вход в полноэкранный режим Выйдите из полноэкранного режима

Попробуйте игру и увидите, что земля прокручивается медленно.

Класс птицы

Теперь давайте создадим класс птицы. В классе птицы у нас есть конструктор, в котором мы получаем значения x, y и метод обновления.

class Bird(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pass

    def update(self):
        pass

Вход в полноэкранный режим Выход из полноэкранного режима

Видите, мы вывели класс из pygame.sprite.Sprite. Это простой базовый класс для видимых игровых объектов.
Давайте напишем метод __init__.

def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.images = []
        self.index = 0
        self.counter = 0
        for num in range(1, 4):
            img = pygame.image.load(f'img/bird{num}.png')
            img = pygame.transform.scale(img, (35, 25))
            self.images.append(img)
        self.image = self.images[self.index]
        self.rect = self.image.get_rect()
        self.rect.center = [x, y]
        self.vel = 0
        self.clicked = False
Вход в полноэкранный режим Выход из полноэкранного режима

Здесь мы сначала вызвали конструктор pygame.sprite.Sprite. У нас есть 3 спрайта с изображениями птиц, которые нужно анимировать. Поэтому мы выполняем цикл 3 раза и сохраняем каждое изображение в images[]. Переменная index используется для получения n-го изображения в каждом кадре. counter используется для контроля частоты кадров анимации. Также мы центрируем изображение по x, y, используя rect спрайта. vel задает скорость птицы, когда clicked = true.

Теперь нам нужно написать метод update.

def update(self):

        # gravity
        if flying == True:
            self.vel += 0.2
            if self.vel > 30:
                self.vel = 0
            if self.rect.bottom < 420:
                self.rect.y += int(self.vel)
Вход в полноэкранный режим Выход из полноэкранного режима

Сначала мы закодировали функцию гравитации для птицы. Убедитесь, что мы объявили переменную flying в верхней части кода.

flying = False
Вход в полноэкранный режим Выход из полноэкранного режима

Мы добавим скорость на 0.2, пока птица летит, и зажмем значение до 30, потому что птице не нужно опускаться ниже земли. Переменная vel будет добавлена к rect.y, что приведет к перемещению птицы вниз, как будто она падает.

Затем объявите переменную game_over вверху и добавьте этот код в метод update.

if game_over == False:
            # jump
            if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
                self.clicked = True
                self.vel = -5
            if pygame.mouse.get_pressed()[0] == 0:
                self.clicked = False
Вход в полноэкранный режим Выход из полноэкранного режима

Проверьте, не закончилась ли игра и не должна ли птица прыгнуть при нажатии кнопки мыши. Нам не нужны постоянные нажатия, поэтому мы должны проверить, что self.clicked равно false. Пришло время прыгать, мы устанавливаем clicked в true и vel в -5, что ведет птицу вверх. Мы установим clicked в false, когда мышь будет отпущена.

Теперь нам нужно анимировать птицу.

            # handle animation
            self.counter += 1
            flap_cooldown = 5

            if self.counter > flap_cooldown:
                self.counter = 0
                self.index += 1
                if self.index >= len(self.images):
                    self.index = 0

            self.image = self.images[self.index]
Войдите в полноэкранный режим Выйти из полноэкранного режима

Мы установим переменную flap_cooldown равной 5 и проверим, идет ли counter за ней. Затем изменим переменную index и обновим изображение спрайта в соответствии с index. Убедитесь, что index не больше длины изображений. Если это так, установите значение 0.

Наконец, мы повернем птицу в соответствии со скоростью.

# rotate the bird
            self.image = pygame.transform.rotate(self.images[self.index], self.vel * -2)
Вход в полноэкранный режим Выйдите из полноэкранного режима

Убедитесь, что все вышеперечисленные коды отступают внутрь условия game_over == False. А когда game_over == true, мы должны направить птицу вниз, как будто она быстро падает. Итак, сразу после вышеупомянутого условия введите следующий код.

else:
     self.image = pygame.transform.rotate(self.images[self.index], -90)
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь наш класс птицы завершен. Давайте нарисуем птицу внутри цикла. Но перед этим нам нужно создать группу класса птицы прямо над циклом.

bird_group = pygame.sprite.Group()
Вход в полноэкранный режим Выйти из полноэкранного режима

И добавьте в группу новый объект Bird.

flappy = Bird(100, int(screen_height/2))
bird_group.add(flappy)
Войти в полноэкранный режим Выйдите из полноэкранного режима

Мы делаем это потому, что класс sprite.Group класса pygame легко рисовать, так как он сам имеет метод по умолчанию draw.

Перейдите в цикл и вызовите метод draw и update группы птиц.

# draw bird
bird_group.draw(screen)
bird_group.update()
Вход в полноэкранный режим Выход из полноэкранного режима

Убедитесь, что мы поместили этот код после отрисовки bg и ground, потому что нам нужна птица в верхней их части.

Также добавьте этот код в цикл for event in pygame.event.get(), чтобы flying = true.

if event.type == pygame.MOUSEBUTTONDOWN and flying == False and game_over == False:
            flying = True
Вход в полноэкранный режим Выйти из полноэкранного режима

Это заставит птицу взлететь, когда мы впервые нажмем на кнопку мыши. Но не запустит игру при ее открытии.
Еще одно обновление. Мы должны закрыть обновление ground_scroll, которое мы написали ранее, внутри условия, потому что нам не нужно прокручивать землю, если игра еще не запущена.

if game_over == False and flying == True:
        # scroll ground
        ground_scroll -= scroll_speed
        if abs(ground_scroll) > 20:
            ground_scroll = 0
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь все начнет двигаться после первого нажатия на кнопку мыши. Попробуйте поиграть сейчас.

Заключение

Надеюсь, вам понравился этот пост и вы получили удовольствие от совместного создания flappy. Я вернусь к вам в ближайшее время с другим постом, в котором мы добавим больше функциональных возможностей в игру. Комментируйте свои мнения и сомнения.

Вторая часть: Часть-1

Оцените статью
devanswers.ru
Добавить комментарий