Найти в Дзене

Урок 34-3 🐦 Обновлённая версия игры Berd 2.1

В предыдущем уроке мы уже создали первый вариант игры Berd на Python с использованием библиотеки Pygame. В ней птичка прыгает по пирамиде из кубиков, закрашивает клетки и получает очки.
В версии Berd 2.1 мы добавим несколько важных игровых механизмов: В этом уроке основной упор сделан на новые части программы, а уже знакомые блоки кода будут рассмотрены кратко. import pygame import sys import random pygame.init() WIDTH, HEIGHT = 900,700 screen = pygame.display.set_mode((WIDTH,HEIGHT)) pygame.display.set_caption("Berd 2.1") clock = pygame.time.Clock() ROWS = 7 TILE = 90 BG = (30,30,40) # загрузка изображений cube = pygame.image.load("cube_day.png").convert_alpha() cube_painted = pygame.image.load("cube_day_painted.png").convert_alpha() bird = pygame.image.load("bird.png").convert_alpha() bonus_img = pygame.image.load("bonus_ball.png").convert_alpha() cube = pygame.transform.scale(cube,(TILE,TILE)) cube_painted = pygame.transform.scale(cube_painted,(TILE,TILE)) bird = pygame.transform.s
Оглавление

В предыдущем уроке мы уже создали первый вариант игры Berd на Python с использованием библиотеки Pygame. В ней птичка прыгает по пирамиде из кубиков, закрашивает клетки и получает очки.

В версии
Berd 2.1 мы добавим несколько важных игровых механизмов:

  • появляющиеся и исчезающие бонусные яйца
  • систему проверки завершения уровня
  • сообщение о победе

В этом уроке основной упор сделан на новые части программы, а уже знакомые блоки кода будут рассмотрены кратко.

📝Текст программы

-2
-3
-4
-5
-6
-7
import pygame
import sys
import random
pygame.init()
WIDTH, HEIGHT = 900,700
screen = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption("Berd 2.1")
clock = pygame.time.Clock()
ROWS = 7
TILE = 90
BG = (30,30,40)
# загрузка изображений
cube = pygame.image.load("cube_day.png").convert_alpha()
cube_painted = pygame.image.load("cube_day_painted.png").convert_alpha()
bird = pygame.image.load("bird.png").convert_alpha()
bonus_img = pygame.image.load("bonus_ball.png").convert_alpha()
cube = pygame.transform.scale(cube,(TILE,TILE))
cube_painted = pygame.transform.scale(cube_painted,(TILE,TILE))
bird = pygame.transform.scale(bird,(60,60))
bonus_img = pygame.transform.scale(bonus_img,(40,40))
font = pygame.font.SysFont(None,40)
# состояние кубиков
grid = []
for r in range(ROWS):
row = []
for c in range(r+1):
row.append(False)
grid.append(row)
# бонусы (r,c,time)
bonuses = []
# время жизни бонуса
BONUS_LIFE = 180 # 3 секунды при 60 FPS
# очки
score = 0
# позиция птички
bird_r = 0
bird_c = 0
grid[0][0] = True
game_over = False
def cube_position(r,c):
start_x = WIDTH//2
start_y = 120
x = start_x + (c - r/2) * TILE
y = start_y + r * TILE * 0.6
return x,y
def draw_cube(x,y,painted):
if painted:
img = cube_painted
else:
img = cube
screen.blit(img,(x,y))
def draw_bird():
x,y = cube_position(bird_r,bird_c)
bx = x + TILE/2 - 30
by = y - 20
screen.blit(bird,(bx,by))
def draw_bonuses():
for bonus in bonuses:
r,c,timer = bonus
x,y = cube_position(r,c)
bx = x + TILE/2 - 20
by = y + 10
screen.blit(bonus_img,(bx,by))
def spawn_bonus():
if random.randint(0,200) == 1:
r = random.randint(0,ROWS-1)
c = random.randint(0,r)
bonuses.append([r,c,BONUS_LIFE])
def update_bonuses():
for bonus in bonuses[:]:
bonus[2] -= 1
if bonus[2] <= 0:
bonuses.remove(bonus)
def check_win():
for row in grid:
for cell in row:
if not cell:
return False
return True
def move_bird(dr,dc):
global bird_r,bird_c,score,game_over
nr = bird_r + dr
nc = bird_c + dc
if nr < 0 or nr >= ROWS:
return
if nc < 0 or nc > nr:
return
bird_r = nr
bird_c = nc
# закрашивание кубика
if not grid[bird_r][bird_c]:
grid[bird_r][bird_c] = True
score += 10
# проверка бонуса
for bonus in bonuses[:]:
r,c,t = bonus
if r == bird_r and c == bird_c:
bonuses.remove(bonus)
score += 30
# проверка победы
if check_win():
game_over = True
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN and not game_over:
# управление цифровым блоком
if event.key == pygame.K_KP1:
move_bird(1,0)
if event.key == pygame.K_KP3:
move_bird(1,1)
if event.key == pygame.K_KP7:
move_bird(-1,-1)
if event.key == pygame.K_KP9:
move_bird(-1,0)
if not game_over:
spawn_bonus()
update_bonuses()
screen.fill(BG)
for r in range(ROWS):
for c in range(r+1):
x,y = cube_position(r,c)
draw_cube(x,y,grid[r][c])
draw_bonuses()
draw_bird()
score_text = font.render("Score: " + str(score),True,(255,255,255))
screen.blit(score_text,(20,20))
if game_over:
text = font.render("LEVEL COMPLETE!",True,(255,220,0))
screen.blit(text,(WIDTH//2-140,50))
pygame.display.flip()
clock.tick(60)

🧱 Основная структура программы (кратко)

В начале программы подключаются модули и запускается игровой движок.

import pygame
import sys
import random

pygame.init()

Создаётся окно игры:

WIDTH, HEIGHT = 900,700
screen = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption("Berd 2.1")

Задаётся частота обновления кадров:

clock = pygame.time.Clock()

🧱 Игровое поле

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

Количество рядов:

ROWS = 7

Состояние кубиков хранится в двумерном списке grid.

False — кубик не закрашен
True — кубик закрашен

После прыжка птички клетка становится закрашенной.

🖼 Загрузка графики

Игра использует несколько изображений:

  • обычный кубик
-8
  • закрашенный кубик
-9
  • птичка
-10
  • бонусное яйцо
-11
cube = pygame.image.load("cube_day.png").convert_alpha()
cube_painted = pygame.image.load("cube_day_painted.png").convert_alpha()
bird = pygame.image.load("bird.png").convert_alpha()
bonus_img = pygame.image.load("bonus_ball.png").convert_alpha()

После загрузки изображения масштабируются под нужный размер.

🐦 Движение птички

Функция move_bird() отвечает за перемещение персонажа.

Она:

  1. проверяет границы пирамиды
  2. перемещает птичку
  3. закрашивает клетку
  4. добавляет очки

За каждую новую клетку игрок получает:

+10 очков

🥚 Новая система бонусов

Одно из главных нововведений версии Berd 2.1 — бонусные яйца.

Они появляются случайно на пирамиде.

Для хранения бонусов используется список:

bonuses = []

Каждый бонус хранит три значения:

ряд
колонку
таймер жизни

Пример бонуса:

[3, 1, 180]

где:

3 — ряд
1 — колонка
180 — время жизни

🥚 Появление бонуса

Функция spawn_bonus() отвечает за случайное появление яйца.

def spawn_bonus():

if random.randint(0,200) == 1:

r = random.randint(0,ROWS-1)
c = random.randint(0,r)

bonuses.append([r,c,BONUS_LIFE])

Что происходит в этой функции:

1️⃣ Генерируется случайное число

2️⃣ Иногда создаётся новый бонус

3️⃣ Бонус добавляется в список

Это создаёт эффект непредсказуемого появления награды.

⏳ Таймер жизни бонуса

Новое поведение бонусов — они не остаются на поле бесконечно.

Каждое яйцо имеет таймер жизни:

BONUS_LIFE = 180

Это примерно 3 секунды при 60 FPS.

Функция update_bonuses() уменьшает таймер.

def update_bonuses():

for bonus in bonuses[:]:

bonus[2] -= 1

if bonus[2] <= 0:
bonuses.remove(bonus)

Что делает эта функция:

1️⃣ каждый кадр уменьшает таймер

2️⃣ проверяет, не закончился ли он

3️⃣ удаляет бонус, если время истекло

Таким образом игроку нужно успеть поймать яйцо, иначе оно исчезнет.

⭐ Получение бонуса

Когда птичка попадает на клетку с яйцом:

игрок получает +30 очков

Бонус удаляется из списка:

bonuses.remove(bonus)

Это добавляет игре элемент реакции и скорости.

🏁 Проверка завершения уровня

Вторая важная функция — check_win().

Она проверяет, закрашены ли все клетки пирамиды.

def check_win():

for row in grid:
for cell in row:
if not cell:
return False
return True

Логика работы:

1️⃣ перебираются все ряды

2️⃣ проверяются все клетки

3️⃣ если найдена незакрашенная — игра продолжается

Если все клетки закрашены — игрок победил.

🎉 Завершение игры

Когда функция check_win() возвращает True, игра устанавливает флаг:

game_over = True

После этого:

  • управление отключается
  • появляется сообщение о завершении уровня

На экране выводится текст:

LEVEL COMPLETE!

Это сигнал игроку, что пирамида полностью закрашена.

🔄 Главный игровой цикл (кратко)

Игровой цикл выполняет несколько действий:

обработка событий
движение птички
появление бонусов
обновление бонусов
рисование поля
рисование персонажа
вывод очков
обновление экрана

Этот цикл повторяется 60 раз в секунду, создавая плавную анимацию игры.

🎮 Что получилось

В версии Berd 2.1 игра стала заметно интереснее:

🐦 управление персонажем

🧱 закрашивание пирамиды

🥚 случайные бонусы

⏳ исчезающие яйца

⭐ система очков

🏁 завершение уровня

Это отличный пример того, как сделать простую игру на python, изучая Pygame.

📚 Итог

В этом уроке мы расширили игру и добавили новые механики:

  • систему бонусов
  • таймер исчезновения предметов
  • проверку завершения уровня

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