32. Menggambar di layar — Solusi pekerjaan rumah
Setiap solusi adalah program pygame lengkap yang bisa dijalankan. Jalankan dengan:
python exercises/32/homework/solutions/01-flag.py
Soal 1 — Bendera
Soal. Gambar bendera tiga garis yang mengisi sebagian besar jendela.
Cara memikirkannya. Bagi tinggi jendela dengan 3. Setiap garis adalah persegi panjang yang membentang selebar penuh di posisi y yang berbeda.
Solusi.
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Flag")
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((255, 255, 255))
stripe_height = 600 // 3
pygame.draw.rect(screen, (0, 57, 166), (0, 0, 800, stripe_height))
pygame.draw.rect(screen, (255, 255, 255),(0, stripe_height, 800, stripe_height))
pygame.draw.rect(screen, (255, 0, 0), (0, stripe_height * 2, 800, stripe_height))
pygame.display.flip()
clock.tick(60)
pygame.quit()Tiga warna apa pun bisa diterima. Kuncinya adalah menghitung offset y
setiap garis sebagai stripe_height * stripe_index.
Kesalahan umum.
- Menulis posisi piksel secara langsung seperti
0, 200, 400alih-alih menghitungnya dari600 // 3. Jika ukuran jendela berubah, posisi yang ditulis langsung akan rusak; posisi yang dihitung akan menyesuaikan.
Soal 2 — Sasaran
Soal. Tiga lingkaran konsentris dengan warna bergantian.
Cara memikirkannya. Gambar lingkaran terbesar dulu, lalu yang sedang di atasnya, lalu yang terkecil. Ketiganya berbagi pusat yang sama. Menggunakan radius berbeda dengan pusat yang sama menghasilkan cincin-cincin konsentris.
Solusi.
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Target")
clock = pygame.time.Clock()
cx, cy = 400, 300 # centre
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((200, 200, 200))
pygame.draw.circle(screen, (220, 0, 0), (cx, cy), 150)
pygame.draw.circle(screen, (255, 255, 255), (cx, cy), 100)
pygame.draw.circle(screen, (220, 0, 0), (cx, cy), 50)
pygame.display.flip()
clock.tick(60)
pygame.quit()Kesalahan umum.
- Menggambar yang terkecil dulu. Lingkaran terbesar akan menimpa yang lebih kecil, menyisakan hanya satu lingkaran terisi. Selalu gambar dari belakang ke depan.
Soal 3 — Grid
Soal. Grid 4x4 kotak bertepi menggunakan nested loop.
Cara memikirkannya. Bagi jendela menjadi 4 kolom dan
4 baris yang sama. Sudut kiri atas setiap sel berada di
(col * cell_w, row * cell_h).
Solusi.
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Grid")
clock = pygame.time.Clock()
cols = 4
rows = 4
cell_w = 800 // cols
cell_h = 600 // rows
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((30, 30, 30))
for row in range(rows):
for col in range(cols):
x = col * cell_w
y = row * cell_h
pygame.draw.rect(screen, (180, 180, 180), (x, y, cell_w, cell_h), 2)
pygame.display.flip()
clock.tick(60)
pygame.quit()Argumen ketebalan 2 hanya menggambar batas. Mengaturnya
ke 0 akan mengisi setiap sel.
Kesalahan umum.
- Menggunakan
range(1, 5)alih-alihrange(4). Keduanya menghasilkan empat nilai tapirange(4)dimulai dari 0, yang dengan benar dipetakan ke posisi piksel melalui perkalian.
Tantangan — Papan catur
Soal. Papan catur 8x8 di mana
(row + col) % 2 == 0 adalah putih dan sisanya gelap.
Cara memikirkannya. Struktur yang sama seperti grid,
tapi warna isian tergantung pada (row + col) % 2. Gunakan
persegi panjang terisi (ketebalan 0).
Solusi.
import pygame
pygame.init()
SIZE = 600
screen = pygame.display.set_mode((SIZE, SIZE))
pygame.display.set_caption("Chessboard")
clock = pygame.time.Clock()
LIGHT = (240, 217, 181)
DARK = (181, 136, 99)
CELLS = 8
cell = SIZE // CELLS
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((0, 0, 0))
for row in range(CELLS):
for col in range(CELLS):
color = LIGHT if (row + col) % 2 == 0 else DARK
x = col * cell
y = row * cell
pygame.draw.rect(screen, color, (x, y, cell, cell))
pygame.display.flip()
clock.tick(60)
pygame.quit()Menggunakan jendela persegi (600x600) dan membaginya
dengan 8 menghasilkan sel yang sama tanpa error pembulatan
(600 / 8 = 75 persis).
Kesalahan umum.
- Menggunakan jendela non-persegi (misalnya 800x600).
800 / 8 = 100tapi600 / 8 = 75, sehingga sel akan berbentuk persegi panjang bukan persegi. Gunakan jendela persegi atau gunakancell_wdancell_hyang terpisah.
Selesai?
Bab 33 menambahkan input keyboard dan mouse sehingga program bisa merespons apa yang dilakukan pemain.