Сегодня мы сделаем интересную программу на Pygame.
Она будет рисовать пирамиду из изометрических кубиков, а при клике мышкой кубики будут перекрашиваться.
Это небольшой, но очень важный шаг к созданию собственной игры на python pygame. 🎮
В этом уроке мы потренируем:
- работу с изображениями
- обработку мыши
- использование условий
- загрузку и масштабирование картинок
А ещё узнаем немного истории о знаменитой игровой пирамиде.
🎮 Откуда появилась пирамида
Если вы видели старые аркадные автоматы 80-х годов, то могли заметить игру Q*bert.
В этой игре герой прыгал по пирамиде из кубиков и перекрашивал их цвет.
Именно эта идея вдохновила множество игр:
Наша программа создаёт похожую пирамиду, но управлять мы будем мышкой. 🖱️
🧠 Что тренирует эта программа
Этот проект отлично развивает навыки:
🐍 python мышь — обработка кликов
🧩 python event — события программы
📍 python get pos — получение координат мыши
🧠 python if else — логические проверки
🖼 pygame image load — загрузка изображений
📏 pygame transform scale — изменение размера картинок
Это важные основы для любой игры на python pygame.
📁 Подготовим изображения
Подготовим папку и разместим в неё изображения.
Для программы нам нужны 4 картинки:
cube_day.png
cube_day_painted.png
cube_night.png
cube_night_painted.png
Это разные состояния кубиков:
☀ обычный дневной
🎨 закрашенный дневной
🌙 обычный ночной
✨ закрашенный ночной
🧩Код программы
Напишем код в Python и сохраним его в туже папку что и картинки.
🧱 Программа
import pygame
import sys
pygame.init()
WIDTH, HEIGHT = 900, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Пирамида кубиков")
clock = pygame.time.Clock()
ROWS = 7
TILE = 80
BG = (20,20,30)
# загрузка изображений
cube_day = pygame.image.load("cube_day.png").convert_alpha()
cube_day_painted = pygame.image.load("cube_day_painted.png").convert_alpha()
cube_night = pygame.image.load("cube_night.png").convert_alpha()
cube_night_painted = pygame.image.load("cube_night_painted.png").convert_alpha()
# масштабируем под размер тайла
cube_day = pygame.transform.scale(cube_day,(TILE,TILE))
cube_day_painted = pygame.transform.scale(cube_day_painted,(TILE,TILE))
cube_night = pygame.transform.scale(cube_night,(TILE,TILE))
cube_night_painted = pygame.transform.scale(cube_night_painted,(TILE,TILE))
# состояние кубиков
grid = []
for r in range(ROWS):
row = []
for c in range(r+1):
row.append(False)
grid.append(row)
# режим день/ночь
night_mode = True
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 night_mode:
if painted:
img = cube_night_painted
else:
img = cube_night
else:
if painted:
img = cube_day_painted
else:
img = cube_day
screen.blit(img,(x,y))
def check_click(mx, my):
for r in range(ROWS):
for c in range(r+1):
x, y = cube_position(r, c)
cx = x + TILE/2
cy = y + TILE/4
dx = mx - cx
dy = my - cy
# проверка ромба (верхней грани)
if abs(dx) + abs(dy)*2 < TILE/2:
grid[r][c] = not grid[r][c]
return
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
mx,my = pygame.mouse.get_pos()
check_click(mx,my)
if event.type == pygame.KEYDOWN:
# переключение день/ночь
if event.key == pygame.K_SPACE:
night_mode = not night_mode
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])
pygame.display.flip()
clock.tick(60)
🧱 Создание окна игры
Сначала создаём окно программы.
import pygame
import sys
pygame.init()
WIDTH, HEIGHT = 900, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Пирамида кубиков")
Здесь происходит:
- запуск библиотеки python pygame
- создание окна
- установка заголовка
🖼 Загружаем изображения
Теперь используем pygame image load.
cube_day = pygame.image.load("cube_day.png").convert_alpha()
cube_day_painted = pygame.image.load("cube_day_painted.png").convert_alpha()
Метод convert_alpha() позволяет сохранить прозрачность изображения.
📏 Масштабируем картинки
Иногда изображения слишком большие.
Поэтому используем pygame transform scale.
cube_day = pygame.transform.scale(cube_day,(TILE,TILE))
Теперь картинка будет идеально подходить к размеру кубика.
🧱 Создаём пирамиду
Пирамида хранится в виде списка списков.
grid = []
for r in range(ROWS):
row = []
for c in range(r+1):
row.append(False)
grid.append(row)
Каждый элемент хранит состояние кубика:
False — обычный
True — закрашенный
🔄 Главный цикл программы
while True:
Это бесконечный цикл.
Он означает:
пока программа запущена → выполнять код снова и снова
Игра работает примерно так:
обработать события
обновить данные
нарисовать кадр
повторить
Так происходит 60 раз в секунду.
📬 Получение событий
for event in pygame.event.get():
Эта строка получает все события, которые произошли в программе.
События — это действия пользователя:
🖱 клик мыши
⌨ нажатие клавиши
❌ закрытие окна
Каждое событие помещается в переменную event.
❌ Закрытие окна
if event.type == pygame.QUIT:
Это событие возникает, когда пользователь нажимает крестик окна.
Если это произошло:
pygame.quit()
sys.exit()
Что делают команды:
pygame.quit()
- корректно закрывает библиотеку
sys.exit()
- завершает программу Python
Без этого программа могла бы зависнуть в памяти.
🖱 Обработка клика мыши
if event.type == pygame.MOUSEBUTTONDOWN:
Это событие появляется, когда пользователь нажимает кнопку мыши.
Важно: это происходит только в момент нажатия, а не пока кнопка удерживается.
🖱 Проверка кнопки мыши
if event.button == 1:
У мыши несколько кнопок.
Номера кнопок:
1 — левая кнопка
2 — средняя (колёсико)
3 — правая кнопка
В игре используется левая кнопка.
📍 Получение координат мыши
mx,my = pygame.mouse.get_pos()
Функция возвращает положение курсора:
mx — координата X
my — координата Y
Пример:
mx = 450
my = 320
Это значит, что курсор находится в точке 450,320 окна.
🧱 Проверка попадания в кубик
check_click(mx,my)
Эта функция проверяет:
в какой кубик попал курсор
Алгоритм внутри функции:
1️⃣ перебираются все кубики
2️⃣ вычисляется положение каждого кубика
3️⃣ проверяется попадание в ромб
4️⃣ состояние кубика меняется
После этого кубик перекрашивается.
⌨ Обработка клавиатуры
if event.type == pygame.KEYDOWN:
Это событие появляется, когда пользователь нажимает клавишу.
Важно: событие возникает один раз, в момент нажатия.
🌙 Переключение день / ночь
if event.key == pygame.K_SPACE:
Проверяется конкретная клавиша.
Здесь используется пробел.
Если нажать пробел:
night_mode = not night_mode
Это переключатель.
Работает так:
False → True
True → False
То есть:
день → ночь
ночь → день
После этого функция draw_cube() начинает использовать другие изображения.
🧼 Очистка экрана
screen.fill(BG)
Эта команда очищает экран.
Если её убрать, появится эффект "шлейфа":
старые кадры будут оставаться
Поэтому каждый кадр начинается с очистки.
🧱 Рисование пирамиды
for r in range(ROWS):
for c in range(r+1):
Этот двойной цикл проходит по всей пирамиде.
Если ROWS = 7, получится:
1 кубик
2 кубика
3 кубика
4 кубика
5 кубиков
6 кубиков
7 кубиков
📍 Получение позиции кубика
x,y = cube_position(r,c)
Функция вычисляет:
где должен находиться кубик на экране
Это создаёт изометрическую пирамиду.
🎨 Рисование кубика
draw_cube(x,y,grid[r][c])
Функция:
1️⃣ выбирает нужное изображение
2️⃣ проверяет состояние кубика
3️⃣ выводит картинку на экран
grid[r][c] хранит состояние:
False — обычный
True — закрашенный
🖥 Обновление экрана
pygame.display.flip()
Эта команда показывает новый кадр.
До этой команды всё рисуется в скрытом буфере.
После flip() изображение появляется на экране.
⏱ Ограничение FPS
clock.tick(60)
Эта команда ограничивает скорость цикла.
60 кадров в секунду
Без ограничения игра могла бы работать:
300–1000 FPS
что:
- нагружает процессор
- делает управление нестабильным
⚙ Как работает весь цикл
Каждый кадр программа делает следующее:
1 получить события
2 обработать мышь
3 обработать клавиатуру
4 очистить экран
5 нарисовать пирамиду
6 показать кадр
7 подождать до 60 FPS
И затем цикл начинается снова.
🎮 Что получается в итоге
Программа умеет:
🖱 реагировать на клики мыши
🧱 определять какой кубик нажат
🎨 менять цвет кубика
🌙 переключать день и ночь
🖥 обновлять экран 60 раз в секунду
Это уже настоящая игровая механика, которая используется во многих играх на Python. 🚀
🖱 Функция проверки клика
Что делает функция
Эта функция определяет:
на какой кубик нажал пользователь мышкой.
В функцию передаются координаты мыши:
mx, my
- mx — позиция мыши по горизонтали
- my — позиция по вертикали
Эти координаты обычно получаются так:
mx, my = pygame.mouse.get_pos()
Перебор всех кубиков
for r in range(ROWS):
for c in range(r+1):
Здесь программа проходит по всей пирамиде.
Например если уровней 7:
r = 0 -> 1 кубик
r = 1 -> 2 кубика
r = 2 -> 3 кубика
...
r = 6 -> 7 кубиков
Поэтому используется:
range(r+1)
Получаем позицию кубика
x, y = cube_position(r, c)
Вызывается функция cube_position.
Она возвращает координаты кубика на экране.
Находим центр ромба
cx = x + TILE/2
cy = y + TILE/4
Кубик изометрический, поэтому его центр не совпадает с центром картинки.
Мы вычисляем центр верхней грани кубика.
Расстояние от мыши до центра
dx = mx - cx
dy = my - cy
Это расстояние:
dx — по горизонтали
dy — по вертикали
Проверка формы ромба
if abs(dx) + abs(dy)*2 < TILE/2:
Это главный трюк программы.
Он проверяет попадание мыши в ромб, а не в квадрат.
Почему это важно?
Изометрический кубик выглядит так:
Но картинка хранится в прямоугольнике:
Белые углы — пустые.
Если проверять обычный прямоугольник, будут срабатывать лишние клики.
Формула:
|dx| + |dy|*2
создаёт ромбовидную область.
Перекрашивание кубика
grid[r][c] = not grid[r][c]
Это очень удобная конструкция Python.
Она переключает состояние:
False → True
True → False
То есть:
обычный кубик → закрашенный
закрашенный → обычный
Прерывание функции
return
После того как найден нужный кубик — функция останавливается.
Это важно, иначе могли бы перекраситься несколько кубиков.
📍 Функция позиции кубика
Эта функция вычисляет:
где должен находиться кубик на экране.
Начало пирамиды
start_x = WIDTH//2
start_y = 120
Это верхняя точка пирамиды.
◼
Она располагается:
- по центру окна
- немного сверху
Смещение по горизонтали
x = start_x + (c - r/2) * TILE
Это формула изометрической сетки.
Она делает так, что каждый следующий ряд расширяется:
Здесь:
c — номер кубика в ряду
r — номер ряда
Выражение:
(c - r/2)
центрирует ряд относительно вершины.
Смещение по вертикали
y = start_y + r * TILE * 0.6
Каждый новый ряд опускается вниз.
Но не на полный размер кубика, потому что изометрические кубики частично перекрываются.
Поэтому используется коэффициент:
0.6
Он создаёт красивую плотную пирамиду.
🎨 Функция рисования кубика
def draw_cube(x,y,painted):
Функция отвечает за выбор изображения и вывод его на экран.
Проверка режима день / ночь
if night_mode:
Если включён ночной режим — используются ночные картинки.
Выбор изображения
if painted:
img = cube_night_painted
else:
img = cube_night
Логика очень простая:
Рисование кубика
screen.blit(img,(x,y))
Команда blit выводит изображение на экран.
Параметры:
img — картинка
(x,y) — координаты
После этого кубик появляется в окне игры.
🎮 Как работают функции вместе
Порядок работы программы такой:
1. программа строит пирамиду 7 уровней
2. рисует кубики
3. пользователь кликает мышкой
4. вызывается check_click()
5. определяется нужный кубик
6. состояние кубика меняется
7. кубик перерисовывается
Именно так создаётся интерактивная пирамида. 🎮
🚀 Почему это проект важен
Этот проект — отличный фундамент для будущих игр.
Он тренирует:
🖼 работу с изображениями
🖱 работу с мышкой
⌨ работу с клавиатурой
🎮 основы игровой логики
Это первый шаг к созданию собственной игры на Pygame.
⭐ Заключение
- Сегодня мы сделали интерактивную пирамиду и научились применять на практике функции python и pygame:
- python event
- python get pos
- pygame image load
- pygame transform scale
Теперь можно идти дальше и добавить:
🐦 персонажа
🐍 врагов
💎 бонусы
🏆 очки
И постепенно получится настоящая игра! 🎮
👍 Если урок был полезен — поставьте лайк.
📌 Подписывайтесь на канал, чтобы не пропустить новые уроки.
💬 В комментариях обязательно напишите:
- какие игры вы хотите сделать на Pygame
- какие идеи для этой игры у вас появились
Очень интересно посмотреть на ваши идеи! 🚀
🐦 Скоро на канале: создаём игру с птичкой на Python! 🎮
Представьте пирамиду из кубиков.
Маленькая птичка прыгает по клеткам — и каждый её прыжок меняет цвет кубика.
Но это ещё не всё…
✨ появляются бонусные шарики
🏆 начисляются очки за закрашенные клетки
🎯 можно собирать бонусы и увеличивать счёт
Игрок управляет птичкой стрелками клавиатуры и постепенно закрашивает всю пирамиду.
Это не просто игра — это отличный пример того, как с помощью Python и библиотеки Pygame можно создать свою первую изометрическую аркаду.
В новом уроке мы разберём:
🐦 как перемещать персонажа по клеткам
🎁 как сделать рандомное появление бонусов
🏆 как добавить систему очков
В итоге получится мини-игра в духе классической аркады Q*bert.
📢 Не пропустите урок!
Скоро покажу, как написать эту игру шаг за шагом.