
🎮 Перша гра на Pygame: пишемо на Python з нуля
Хочете написати свою першу гру, але не знаєте, з якого боку підступитися до геймдеву? Pygame знімає цей бар'єр. Ви пишете на чистому Python і одразу бачите результат на екрані: рухомий спрайт, реакцію на клавіші, оживлену механіку. Без важких рушіїв, без тисяч рядків шаблонного коду.
Проблема більшості туторіалів у тому, що вони або закопуються в теорію на 40 сторінок, або кидають вас із «допишіть самі». Тут ми підемо середнім шляхом: пояснимо рівно стільки, щоб ви розуміли кожен рядок, і одразу зберемо робочу гру, персонажа, який рухається екраном на WASD. Весь код уміщається в 60 рядків.
💡 Швидкий огляд:
- Встановіть Pygame через pip і створіть файл гри — це займе пару хвилин
- Розберіться з ігровим циклом: події, розрахунки, відмальовування, три фази, які живуть у нескінченному
while True - Напишіть клас гравця й оживіть його: клавіші WASD рухають спрайт, екран перемальовується 60 разів на секунду
- Зрозумійте систему координат і роботу з кольором, два наріжні камені, на яких тримається будь-яка 2D-графіка
Що таке Pygame і чому саме він
Pygame — це бібліотека для Python, яка обгортає мультимедійну SDL (Simple DirectMedia Layer) у зручне Python-API. SDL відповідає за низькорівневу роботу з графікою, звуком і пристроями введення, а Pygame дає до цього доступ через звичні класи та методи. Актуальна версія, 2.6.0, бібліотека активно підтримується і працює на Windows, macOS та Linux.
Для новачка Pygame має три незаперечні плюси. Перше, поріг входу: ви використовуєте звичайний Python-код, жодної нової мови чи візуального редактора. Друге, миттєвий зворотний зв'язок: написали pygame.draw.rect(...), і на екрані з'явився прямокутник, жодної магії. Третє, розуміння фундаменту: Pygame не ховає від вас ігровий цикл і чергу подій, ви бачите, як влаштована будь-яка гра зсередини. Після Pygame пересісти на Godot чи Unity буде легше, тому що ви вже знаєте, що таке delta time і event polling.
Бібліотека не намагається бути ігровим рушієм. У ній немає сцени, фізики чи вбудованого редактора рівнів, і це свідоме рішення. Ви контролюєте кожен піксель і кожен тік, а отже, вчитеся думати як розробник ігор, а не як оператор чужого інструмента.
Встановлення Pygame за дві хвилини
Python 3.9 або новіший уже стоїть? Тоді відкривайте термінал і виконуйте одну команду:
1 pip install pygame
Для ізоляції проєкту краще створити віртуальне оточення:
1 python -m venv game_env 2 game_env\Scripts\activate # Windows 3 source game_env/bin/activate # macOS / Linux 4 pip install pygame
Перевірте, що бібліотека підхопилася:
1 import pygame 2 print(pygame.version.ver)
Якщо у відповідь отримали 2.6.0 (або новішу, актуальну версію можна звірити на pygame.org), усе готово. Створіть папку проєкту, покладіть у неї будь-яке зображення-спрайт розміром 80×80 пікселів з іменем player.png і текстовий файл game.py, з нього й почнемо.
Як влаштована ігрова петля: події, розрахунки, відмальовування
Серце будь-якої гри, головний цикл, він же main loop. Поки гра запущена, всередині нескінченного while True змінюють одна одну три фази:
Обробка подій, що сталося з минулого кадру? Натиснута клавіша? Смикнулася миша? Вікно закрили? Pygame збирає всі події в чергу, і ми проходимо по ній циклом
for event in pygame.event.get().Розрахунок логіки, як змінився світ у відповідь на події? Гравець натиснув W, збільшуємо Y-координату. Куля зіткнулася з астероїдом, позначаємо обидва «до видалення».
Відмальовування, малюємо все, що має бути на екрані. Заливаємо фон, розміщуємо спрайти за новими координатами, викликаємо
pygame.display.update(), і гравець бачить кадр.
Ці три кроки повторюються 60 разів на секунду, саме стільки кадрів (FPS) ми задамо таймеру. Ілюзія руху будується на тому, що між кадрами спрайт зміщується на пару пікселів, а око сприймає це як безперервну анімацію.
Пишемо перший код: рухаємо спрайт екраном
Ось повний код гри. Збережіть його в game.py і покладіть player.png у ту саму папку:
1 #!/usr/bin/env python3 2 3 import pygame 4 import sys 5 6 WIDTH, HEIGHT = 360, 480 7 WHITE = (255, 255, 255) 8 9 class Player(pygame.sprite.Sprite): 10 11 def __init__(self, image_path): 12 super().__init__() 13 self.image = pygame.image.load(image_path) 14 self.x = WIDTH / 2 15 self.y = HEIGHT / 2 16 self.speed = 5 17 18 def move(self, dx, dy): 19 self.x += dx 20 self.y += dy 21 22 def main(): 23 pygame.init() 24 screen = pygame.display.set_mode((WIDTH, HEIGHT)) 25 pygame.display.set_caption("Первая игра на Pygame") 26 27 clock = pygame.time.Clock() 28 fps = 60 29 30 player = Player("player.png") 31 dx, dy = 0, 0 32 33 running = True 34 while running: 35 for event in pygame.event.get(): 36 if event.type == pygame.QUIT: 37 running = False 38 39 elif event.type == pygame.KEYDOWN: 40 if event.key == pygame.K_d: 41 dx = player.speed 42 elif event.key == pygame.K_a: 43 dx = -player.speed 44 elif event.key == pygame.K_w: 45 dy = -player.speed 46 elif event.key == pygame.K_s: 47 dy = player.speed 48 49 elif event.type == pygame.KEYUP: 50 if event.key in (pygame.K_d, pygame.K_a): 51 dx = 0 52 elif event.key in (pygame.K_w, pygame.K_s): 53 dy = 0 54 55 player.move(dx, dy) 56 screen.fill(WHITE) 57 screen.blit(player.image, (player.x, player.y)) 58 pygame.display.update() 59 clock.tick(fps) 60 61 pygame.quit() 62 sys.exit() 63 64 if __name__ == "__main__": 65 main()

Запустіть python game.py, відкриється вікно з білим фоном і вашим спрайтом по центру. Затисніть W, A, S або D, персонаж рухається. Відпустили, зупиняється. Це вже справжня гра, хоча й мінімальна.
Що поліпшено порівняно з класичними туторіалами: додано KEYUP, обробник відпускання клавіші. Без нього спрайт після першого натискання поїхав би за край екрана назавжди. А ще код обгорнуто в конструкцію if __name__ == "__main__", хороша практика, яка дозволяє імпортувати файл як модуль без запуску гри.
Система координат і робота з кольором
У Pygame координати відраховуються від лівого верхнього кута: (0, 0), самий верх ліворуч. Рух праворуч збільшує X, рух униз збільшує Y. Це відрізняється від шкільної системи координат, де Y росте вгору, просто запам'ятайте і перевірте себе на перших двох запусках: натиснули S, спрайт поїхав униз, натиснули W, угору.
Колір задається кортежем із трьох чисел (R, G, B), кожне від 0 до 255. Білому відповідає (255, 255, 255), чорному відповідає (0, 0, 0), червоному відповідає (255, 0, 0). Метод screen.fill(WHITE) заливає весь екран вибраним кольором перед відмальовуванням кожного кадру. Якщо цього не робити, спрайт залишатиме за собою шлейф із попередніх позицій.
Що відбувається під капотом: порядковий розбір
Клас Player успадковується від pygame.sprite.Sprite, це вбудований клас Pygame для ігрових об'єктів. У конструкторі ми завантажуємо зображення через pygame.image.load() і задаємо стартову позицію по центру екрана: WIDTH / 2 і HEIGHT / 2. Метод move(dx, dy) отримує зміщення і додає його до поточних координат, чиста арифметика, жодної магії.
Функція main() збирає все воєдино. pygame.init() запускає внутрішні підсистеми. pygame.display.set_mode() створює вікно, а screen — це поверхня (Surface), на якій ми малюємо. pygame.time.Clock() створює таймер: його метод tick(fps) у кінці циклу каже Pygame «чекай, поки не мине 1/60 секунди з минулого кадру», так ми фіксуємо частоту кадрів і не навантажуємо процесор марно.
Головний цикл while running крутиться, поки прапорець running не стане False. Всередині, три фази, про які говорили вище:

У циклі for event in pygame.event.get() ми опитуємо чергу подій. pygame.QUIT — це сигнал «користувач натиснув на хрестик вікна»: виставляємо running = False, і на наступній ітерації цикл завершиться. pygame.KEYDOWN спрацьовує при натисканні клавіші, а KEYUP при відпусканні. Для D і A міняємо dx, для W і S міняємо dy. Коли клавішу відпускають, обнуляємо відповідну компоненту швидкості, спрайт зупиняється.
screen.blit(player.image, (player.x, player.y)), метод, який «накладає» одне зображення на інше. У нашому випадку, спрайт гравця на головну поверхню екрана за поточними координатами. pygame.display.update() оновлює вікно, і гравець бачить готовий кадр.
Зверніть увагу: player.move() викликається до screen.fill(). Якщо поміняти їх місцями, спрайт стиратиметься в ту саму мілісекунду, коли з'являється, ви просто не побачите його на екрані. Порядок операцій в ігровому циклі критичний.
Клацаєте по хрестику, pygame.quit() коректно вивантажує підсистеми Pygame, а sys.exit() завершує процес Python. Без pygame.quit() вікно може зависнути при закритті, дрібниця, але код має бути акуратним.
Коротке відео за темою
Якщо текстова інструкція заходить не до кінця, ось відмінний відеокурс англійською, де покроково збирають Space Invaders на Pygame. Усі концепції зі статті показані наживо:
⁉️🤔 Часті питання
Чи потрібно знати ООП для Pygame?
Так, на базовому рівні. Класи, методи, успадкування і
selfвам знадобляться з першого дня: гравець, вороги, кулі та бонуси природно лягають в об'єктну модель. Якщо ви пройшли будь-який introductory-курс з Python, де пояснювалиclassі__init__, цього достатньо. Решту доберете по ходу: Pygame не вимагає патернів проєктування, звичайного успадкування відSpriteвистачає для десятків прототипів. Ігровий об'єкт у Pygame — це клас, успадкований відpygame.sprite.Sprite. У конструкторі ви завантажуєте спрайт черезpygame.image.load(), задаєте початкові координати та швидкість. Методupdate()(або свій, на кшталтmove()) змінює позицію на кожному кадрі. Головний цикл смикаєupdate()у всіх об'єктів, потім відмальовує їх черезscreen.blit(). Жодної магії, просто виклик методів у правильному порядку 60 разів на секунду.
Чи гальмує Pygame на складній 2D-графіці?
При розумній кількості спрайтів ні. Поверхні (Surface) у Pygame живуть в оперативній пам'яті, і
blit— це швидке копіювання пікселів, а не програмний рендеринг. На тисячі одночасно рухомих об'єктів ви можете впертися в продуктивність Python, але для платформера, top-down шутера чи tower defence запас міцності є. Якщо потрібно витиснути максимум, використовуйтеpygame.sprite.Groupз автоматичним відмальовуванням і dirty-rectangles для часткового оновлення екрана.
Чи можна в Pygame додати звук і музику?
Так, з коробки. Модуль
pygame.mixerвміє програвати WAV і MP3. Звук пострілу запускається черезpygame.mixer.Sound("shoot.wav").play(), а фонова музика завантажується черезpygame.mixer.music.load("theme.mp3")іpygame.mixer.music.play(-1)(прапорець-1зациклює). Єдиний нюанс:pygame.mixer.init()потрібно викликати до завантаження звуків, і для MP3 на Linux може знадобитися бібліотекаlibmpg123.
Чи є сенс вчити Pygame у 2026 році, коли є Godot і Unity?
Абсолютно. Pygame не конкурент Godot — це навчальний інструмент і легкий прошарок для 2D-прототипів. Ви не вчите C# заради того, щоб посувати квадратик, і не розбираєтеся в нодовій системі заради Pong-а. Pygame дає розуміння того, як ігри працюють на нижньому рівні: ігровий цикл, буферизація кадрів, колізії. Програмісти, які стартували з Pygame, легше освоюють Unity і Godot, тому що бачать за абстракціями рушія живу механіку. На Pygame пишуть реальні інді-проєкти, включно з комерційними, невеликий платформер чи пазл можна випустити в Steam, не торкаючись C++.
Що робити, якщо спрайт виходить за край екрана?
Додайте перевірку меж у метод
move(): якщоself.x < 0, прирівняйте до 0; якщоself.x + ширина_спрайта > WIDTH, прирівняйте доWIDTH - ширина_спрайта. Те саме для Y. Це називається clamping, і без нього персонаж рано чи пізно поїде в невидиму область. У більш просунутих іграх межами слугують стіни рівня, визначені через тайлову сітку або масив колізій.
Готові запустити свою першу гру?
Скопіюйте код із розділу «Пишемо перший код», збережіть у game.py, покладіть поруч будь-яку картинку-спрайт, і через кілька секунд ви побачите вікно з рухомим персонажем. Це і є точка входу в геймдев: не читати, а запустити і почати крутити параметри.
Поміняйте WIDTH і HEIGHT, вікно стане більшим. Задайте player.speed = 10, персонаж прискориться. Замініть WHITE на (35, 35, 35), отримаєте темний фон. Поекспериментуйте, і ви зрозумієте, що ігрова програма, не магія, а послідовність кроків, які ви контролюєте.
Коли освоїте рух, беріться за зіткнення (pygame.sprite.collide_rect()), анімацію (зміна кадрів спрайт-листа) і процедурну генерацію рівнів. Для старту вистачить одного файлу game.py і бажання розібратися, як воно влаштовано.



