33. Event dan input

Game yang mengabaikan keyboard dan mouse hanyalah screensaver. Bab ini membahas cara pygame mengumpulkan input dan cara meresponsnya.

Antrian event

Setiap kali sesuatu terjadi — penekanan tombol, klik mouse, pengguna menutup jendela — pygame menyimpannya di antrian event internal. Di awal setiap frame, pygame.event.get() menguras antrian tersebut dan mengembalikan list objek Event. Kamu me-loop melalui list dan memeriksa atribut .type setiap event:

for event in pygame.event.get():
    if event.type == pygame.QUIT:
        running = False

Jika kamu tidak pernah memanggil pygame.event.get(), antrian akan penuh dan jendela berhenti merespons tombol X.

Event keyboard: KEYDOWN dan KEYUP

pygame.KEYDOWN terpicu sekali saat tombol ditekan. pygame.KEYUP terpicu sekali saat tombol dilepas.

for event in pygame.event.get():
    if event.type == pygame.QUIT:
        running = False
    if event.type == pygame.KEYDOWN:
        print(f"key pressed: {event.key}")
    if event.type == pygame.KEYUP:
        print(f"key released: {event.key}")

event.key adalah konstanta integer. pygame menyediakan konstanta bernama untuk setiap tombol:

Konstanta Tombol
pygame.K_LEFT Panah kiri
pygame.K_RIGHT Panah kanan
pygame.K_UP Panah atas
pygame.K_DOWN Panah bawah
pygame.K_SPACE Spasi
pygame.K_RETURN Enter
pygame.K_ESCAPE Escape
pygame.K_a Tombol A
pygame.K_z Tombol Z
pygame.K_0 Angka 0
pygame.K_9 Angka 9

Konstanta huruf adalah huruf kecil: pygame.K_a sampai pygame.K_z.

KEYDOWN terpicu sekali per penekanan. Tidak berulang saat tombol ditahan. Ini membuatnya cocok untuk aksi satu kali seperti melompat atau mengalihkan menu:

if event.type == pygame.KEYDOWN:
    if event.key == pygame.K_SPACE:
        jump()         # called once, not 60 times per second
    if event.key == pygame.K_ESCAPE:
        running = False

Buka exercises/33/01-print-key.py. Di event loop, tambahkan handler KEYDOWN yang mencetak f"pressed: {pygame.key.name(event.key)}". pygame.key.name(key) mengonversi konstanta tombol menjadi string yang bisa dibaca manusia seperti "left" atau "space". Jalankan program dan tekan beberapa tombol.

Input terus-menerus: pygame.key.get_pressed()

KEYDOWN tidak praktis untuk gerakan karena hanya terpicu sekali. Jika kamu ingin karakter terus bergerak selama pemain menahan tombol, gunakan pygame.key.get_pressed():

keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
    x -= 5
if keys[pygame.K_RIGHT]:
    x += 5

pygame.key.get_pressed() mengembalikan sebuah sequence di mana setiap posisi adalah True jika tombol itu sedang ditahan dan False jika tidak. Panggil sekali per frame di bagian perbarui state dari loop (bukan di dalam event loop). Karena diperiksa setiap frame, gerakan menjadi mulus.

KEYDOWN vs get_pressed — kapan menggunakan masing-masing.

  • KEYDOWN: aksi satu kali yang seharusnya terjadi tepat sekali per penekanan (lompat, tembak, alihkan).
  • get_pressed: aksi terus-menerus yang seharusnya berulang setiap frame tombol ditahan (jalan kiri, percepat, gulir).

Event mouse

pygame.MOUSEBUTTONDOWN terpicu saat tombol mouse ditekan.

if event.type == pygame.MOUSEBUTTONDOWN:
    print(f"click at {event.pos}, button {event.button}")
  • event.pos — tuple (x, y) posisi kursor saat klik terjadi.
  • event.button — tombol mana: 1 = kiri, 2 = roda gulir tengah, 3 = kanan.

pygame.MOUSEBUTTONUP terpicu saat tombol dilepas (atribut yang sama).

Untuk mendapatkan posisi mouse saat ini kapan saja (bukan hanya saat klik):

mx, my = pygame.mouse.get_pos()

Ini berguna untuk menggambar sesuatu yang mengikuti kursor:

# In the draw section:
mx, my = pygame.mouse.get_pos()
pygame.draw.circle(screen, (255, 255, 0), (mx, my), 10)

Menggabungkan input

Ini adalah program yang menggerakkan kotak dengan tombol panah, mengubah warnanya dengan spasi, dan mencetak posisi mouse saat klik kiri:

import pygame

pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Input demo")
clock = pygame.time.Clock()

x, y = 370, 270
size = 60
color = (255, 50, 50)

running = True
while running:
    # 1. Events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                color = (50, 50, 255)   # turn blue on spacebar
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_SPACE:
                color = (255, 50, 50)   # back to red when released
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                print(f"clicked at {event.pos}")

    # 2. Update
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        x -= 4
    if keys[pygame.K_RIGHT]:
        x += 4
    if keys[pygame.K_UP]:
        y -= 4
    if keys[pygame.K_DOWN]:
        y += 4

    # 3. Draw
    screen.fill((30, 30, 30))
    pygame.draw.rect(screen, color, (x, y, size, size))

    # 4. Flip
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Pekerjaan Rumah

Soal 1 — Pelapor tombol

Buka exercises/33/homework/01-key-reporter.py. Tampilkan tombol mana yang sedang ditahan di layar. Gunakan pygame.key.get_pressed() untuk mendeteksi tombol yang ditahan. Saat tidak ada tombol yang ditahan, tampilkan "no key". Tampilkan teks sebagai pesan yang dicetak ke terminal setiap frame (rendering teks ada di bab 35).

Soal 2 — Penghitung klik

Buka exercises/33/homework/02-click-counter.py. Hitung berapa kali pengguna mengklik kiri di jendela. Cetak hitungannya ke terminal setiap kali bertambah.

Soal 3 — Penggerak panah

Buka exercises/33/homework/03-arrow-mover.py. Sebuah lingkaran dimulai di tengah. Tombol panah menggerakkannya secara terus-menerus (get_pressed). Menekan Escape mengakhiri program. Cetak "moved" ke terminal setiap frame lingkaran sedang bergerak.

Tantangan — Pengikut mouse

Buka exercises/33/homework/04-mouse-follower.py. Gambar lingkaran kecil di posisi mouse saat ini setiap frame sehingga mengikuti kursor. Saat tombol mouse kiri ditahan (periksa pygame.MOUSEBUTTONDOWN dan MOUSEBUTTONUP untuk melacak kondisi ditahan), ubah warna lingkaran.

Macet atau sudah selesai? Buka halaman solusi pekerjaan rumah.