Skip to content

Урок 18. Pygame: керування клавіатурою

Урок 18. Pygame: керування клавіатурою

Section titled “Урок 18. Pygame: керування клавіатурою”

Тривалість: 45–60 хв
XP: 250

Марко, минулого уроку об’єкти рухалися самі. Але справжньою грою керує гравець! Сьогодні ти даси Марку «пульт» — навчиш персонажа слухатися стрілок і WASD.

Дати гравцеві контроль над персонажем.

Після уроку Марко має вміти:

  • читати стан клавіатури через pygame.key.get_pressed();
  • рухати персонажа в 4 напрямках;
  • не випускати його за межі екрана;
  • розуміти, чому швидкість знову встановлюється кожен кадр.

⌨️ Крок 1. Читаємо клавіатуру

Section titled “⌨️ Крок 1. Читаємо клавіатуру”

Кожен кадр Pygame може «запитати», які клавіші зараз натиснуті:

keys = pygame.key.get_pressed()

keys — це «знімок» клавіатури. Щоб перевірити, чи натиснута клавіша, пишемо keys[pygame.K_LEFT]. Воно повертає True (натиснуто) або False (ні).

⚠️ Важливо: get_pressed() показує стан клавіш у цей момент, а не «натискання». Поки тримаєш клавішу — воно кожен кадр повертає True. Саме тому персонаж рухається безперервно, поки клавіша затиснута.

graph LR
    A["Клавіша затиснута"] -->|"get_pressed()<br/>кожен кадр"| B["keys[K_LEFT] = True"]
    B --> C["player_x -= 5"]
    C --> D["Герой їде вліво"]

🎮 Крок 2. Рух у 4 напрямках

Section titled “🎮 Крок 2. Рух у 4 напрямках”

Цей код ставимо всередину game loop:

keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_x -= 5
if keys[pygame.K_RIGHT]:
player_x += 5
if keys[pygame.K_UP]:
player_y -= 5
if keys[pygame.K_DOWN]:
player_y += 5

Зверни увагу на знаки:

  • LEFT → player_x -= 5 (вліво — зменшуємо x);
  • RIGHT → player_x += 5 (вправо — збільшуємо x);
  • UP → player_y -= 5 (вгору — зменшуємо y!);
  • DOWN → player_y += 5 (вниз — збільшуємо y).

💡 Аналогія: уяви, що x — це твій крок управо, а y — крок униз. Щоб піти вгору (зменшити y), треба зробити «мінусовий крок» вниз.

🎮 Крок 3. WASD — додаткові клавіші

Section titled “🎮 Крок 3. WASD — додаткові клавіші”

Не всі люблять стрілки. Додай підтримку WASD тим самим способом:

if keys[pygame.K_a]:
player_x -= 5
if keys[pygame.K_d]:
player_x += 5

🧱 Крок 4. Не випускаємо за екран

Section titled “🧱 Крок 4. Не випускаємо за екран”

Можна обмежити координати через if. Так робили в минулому уроці.

Але є коротший спосіб. min повертає менше з двох чисел, max — більше. Це дозволяє «затиснути» значення в межах:

player_x = max(0, min(player_x, 800 - player_size))
player_y = max(0, min(player_y, 600 - player_size))

Логіка рядка: player_x має бути не менше 0 і не більше 800 - player_size.

Debian-tip: не хвилюйся, якщо скорочений запис здається складним. Спершу реалізуй через if — це теж правильне рішення. Короткий варіант можна спробувати пізніше.

🧩 Повна програма (керований квадрат)

Section titled “🧩 Повна програма (керований квадрат)”
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
player_x = 400
player_y = 300
player_size = 50
player_speed = 5
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_x -= player_speed
if keys[pygame.K_RIGHT]:
player_x += player_speed
if keys[pygame.K_UP]:
player_y -= player_speed
if keys[pygame.K_DOWN]:
player_y += player_speed
player_x = max(0, min(player_x, 800 - player_size))
player_y = max(0, min(player_y, 600 - player_size))
screen.fill((30, 30, 30))
pygame.draw.rect(screen, (0, 200, 100), (player_x, player_y, player_size, player_size))
pygame.display.flip()
clock.tick(60)
pygame.quit()
  1. Рух стрілками.
  2. Додай WASD.
  3. Заборони виходити за межі.
  4. Винеси швидкість у змінну player_speed (як у прикладі вище).

✅ Зупинись і перевір: персонаж рухається плавно і не вилітає за межі? Якщо так — переходь далі.

Коли затиснуто SHIFT, персонаж рухається вдвічі швидше:

speed = 5
if keys[pygame.K_LSHIFT]:
speed = 10
if keys[pygame.K_LEFT]:
player_x -= speed
# ... і так для решти напрямків

Подумай і поясни: чому speed = 5 треба встановлювати кожен кадр, а не один раз перед циклом?

Підказка: що станеться зі швидкістю після того, як людина відпустить SHIFT, якщо speed = 10 запишеться назавжди?

Намалюй простий лабіринт із прямокутників-стін. Поки що collision зі стінами не потрібен: персонаж має просто дійти до фінішної зони. Це тренування керування і меж.

Марко може:

  • пояснити, що повертає pygame.key.get_pressed();
  • рухати персонажа в 4 напрямках;
  • пояснити, чому швидкість знову встановлюється кожен кадр;
  • не випускати персонажа за межі екрана.

Додай sprint (SHIFT) і кнопку повільного руху (наприклад CTRL).