Snake Game With Python + Tkinter
Pengertian, kode, penjelasan baris demi baris, tabel penilaian, dan petunjuk menjalankan di Thonny.
Pendahuluan
Artikel ini menjelaskan secara menyeluruh bagaimana membuat Game Ular (Snake Game) menggunakan Python dan library tkinter. Semua contoh bisa dijalankan offline menggunakan Thonny IDE
Apa yang akan dipelajari
- Pengenalan
tkinterdanimport - Cara memberi komentar di Python
- Kode lengkap Game Ular dengan menu, pengaturan kecepatan, rintangan, skor, dan tombol restart
- Penjelasan setiap bagian kode (baris demi baris)
- Instruksi menjalankan di Thonny
Pengertian Dasar
1. Apa itu tkinter?
tkinter adalah library bawaan Python yang digunakan untuk membuat aplikasi berbasis GUI (Graphical User Interface). Dengan tkinter kita dapat membuat jendela, tombol, teks, menu, area gambar (Canvas), dan menangani input keyboard/mouse seperti pada aplikasi desktop.
2. Apa itu import?
import dipakai untuk memanggil modul atau library yang akan digunakan di program. Contoh: import random memanggil modul untuk menghasilkan angka acak.
3. Cara memberi komentar di Python
Gunakan # untuk komentar satu baris. Untuk komentar beberapa baris bisa pakai tiga kutip '''...''' atau """...""".
# Ini komentar satu baris
'''
Komentar
lebih dari satu baris
'''
Salin & Simpan sebagai snake_game.py
Berikut kode lengkap yang sudah dioptimalkan: menu, pengaturan kecepatan, rintangan, skor, dan restart.
import tkinter as tk
import random
# --- Pengaturan Awal ---
LEBAR = 400
TINGGI = 400
UKURAN_KOTAK = 20
WARNA_LATAR = "lightgreen"
# --- Jendela Utama ---
root = tk.Tk()
root.title("Game Ular Sekolah")
root.resizable(False, False)
# --- Kanvas Utama ---
canvas = tk.Canvas(root, width=LEBAR, height=TINGGI, bg=WARNA_LATAR)
canvas.pack()
# Variabel global
arah = "kanan"
ular = []
makanan = ()
rintangan = []
skor = 0
game_berjalan = False
kecepatan = 150 # default kecepatan (ms)
# --- Fungsi Menggambar ---
def gambar_ular():
canvas.delete("snake")
for (x, y) in ular:
canvas.create_rectangle(x, y, x + UKURAN_KOTAK, y + UKURAN_KOTAK,
fill="green", outline="darkgreen", tags="snake")
def gambar_makanan():
canvas.delete("food")
x, y = makanan
canvas.create_oval(x, y, x + UKURAN_KOTAK, y + UKURAN_KOTAK,
fill="red", tags="food")
def gambar_skor():
canvas.delete("score")
canvas.create_text(60, 10, text=f"Skor: {skor}",
font=("Arial", 12, "bold"), fill="black", tags="score")
def gambar_rintangan():
canvas.delete("wall")
for (x, y) in rintangan:
canvas.create_rectangle(x, y, x + UKURAN_KOTAK, y + UKURAN_KOTAK,
fill="gray", outline="black", tags="wall")
# --- Fungsi Membuat Objek ---
def buat_makanan():
x = random.randrange(0, LEBAR, UKURAN_KOTAK)
y = random.randrange(0, TINGGI, UKURAN_KOTAK)
return (x, y)
def buat_rintangan():
daftar_rintangan = []
for _ in range(8):
x = random.randrange(0, LEBAR, UKURAN_KOTAK)
y = random.randrange(0, TINGGI, UKURAN_KOTAK)
daftar_rintangan.append((x, y))
return daftar_rintangan
# --- Fungsi Gerak Ular ---
def gerak_ular():
global makanan, skor, game_berjalan
if not game_berjalan:
return
kepala_x, kepala_y = ular[0]
if arah == "kanan":
kepala_x += UKURAN_KOTAK
elif arah == "kiri":
kepala_x -= UKURAN_KOTAK
elif arah == "atas":
kepala_y -= UKURAN_KOTAK
elif arah == "bawah":
kepala_y += UKURAN_KOTAK
kepala_baru = (kepala_x, kepala_y)
# --- Cek Tabrakan ---
if (
kepala_x < 0 or kepala_x >= LEBAR or
kepala_y < 0 or kepala_y >= TINGGI or
kepala_baru in ular or kepala_baru in rintangan
):
game_over()
return
ular.insert(0, kepala_baru)
# --- Makan makanan ---
if kepala_baru == makanan:
skor += 10
makanan_baru = buat_makanan()
while makanan_baru in ular or makanan_baru in rintangan:
makanan_baru = buat_makanan()
makanan = makanan_baru
else:
ular.pop()
gambar_ular()
gambar_makanan()
gambar_rintangan()
gambar_skor()
root.after(kecepatan, gerak_ular)
# --- Fungsi Ubah Arah ---
def ubah_arah(event):
global arah
key = event.keysym
if key == "Up" and arah != "bawah":
arah = "atas"
elif key == "Down" and arah != "atas":
arah = "bawah"
elif key == "Left" and arah != "kanan":
arah = "kiri"
elif key == "Right" and arah != "kiri":
arah = "kanan"
elif key == "Return": # ENTER untuk pilih menu
pilih_menu()
elif key == "Up" or key == "Down": # navigasi menu
ubah_pilihan(key)
# --- Fungsi Game Over ---
def game_over():
global game_berjalan
game_berjalan = False
canvas.delete("all")
canvas.create_text(LEBAR / 2, TINGGI / 2 - 30,
text="GAME OVER", font=("Arial", 24, "bold"), fill="red")
canvas.create_text(LEBAR / 2, TINGGI / 2,
text=f"Skor Akhir: {skor}", font=("Arial", 14), fill="black")
# Tombol restart
canvas.create_rectangle(130, 250, 270, 290, fill="yellow", tags="restart_box")
canvas.create_text(200, 270, text="Main Lagi", font=("Arial", 12, "bold"),
fill="black", tags="restart_text")
canvas.tag_bind("restart_box", "", lambda e: mulai_game())
canvas.tag_bind("restart_text", "", lambda e: mulai_game())
# --- Fungsi Mulai Game ---
def mulai_game():
global ular, makanan, arah, skor, game_berjalan, rintangan
canvas.delete("all")
ular = [(100, 100), (80, 100), (60, 100)]
makanan = buat_makanan()
rintangan = buat_rintangan()
arah = "kanan"
skor = 0
game_berjalan = True
gambar_ular()
gambar_makanan()
gambar_rintangan()
gambar_skor()
gerak_ular()
# --- MENU UTAMA ---
pilihan_menu = ["Mulai Game", "Pengaturan", "Keluar"]
indeks_pilihan = 0
def tampilkan_menu():
canvas.delete("all")
canvas.create_text(LEBAR / 2, 100, text="🐍 SNAKE GAME 🐍",
font=("Arial", 22, "bold"), fill="black")
for i, teks in enumerate(pilihan_menu):
warna = "white" if i == indeks_pilihan else "lightgray"
canvas.create_rectangle(140, 180 + i * 60, 260, 220 + i * 60,
fill=warna, outline="black", tags=f"menu{i}")
canvas.create_text(200, 200 + i * 60, text=teks,
font=("Arial", 12, "bold"), fill="black", tags=f"menu{i}")
canvas.tag_bind("menu0", "", lambda e: mulai_game())
canvas.tag_bind("menu1", "", lambda e: tampilkan_pengaturan())
canvas.tag_bind("menu2", "", lambda e: root.destroy())
def ubah_pilihan(key):
global indeks_pilihan
if key == "Up":
indeks_pilihan = (indeks_pilihan - 1) % len(pilihan_menu)
elif key == "Down":
indeks_pilihan = (indeks_pilihan + 1) % len(pilihan_menu)
tampilkan_menu()
def pilih_menu():
if indeks_pilihan == 0:
mulai_game()
elif indeks_pilihan == 1:
tampilkan_pengaturan()
elif indeks_pilihan == 2:
root.destroy()
# --- MENU PENGATURAN ---
def tampilkan_pengaturan():
global kecepatan
canvas.delete("all")
canvas.create_text(LEBAR / 2, 100, text="⚙️ PENGATURAN KECEPATAN ⚙️",
font=("Arial", 18, "bold"), fill="black")
opsi = [("Pelan", 200), ("Sedang", 150), ("Cepat", 100)]
for i, (teks, nilai) in enumerate(opsi):
canvas.create_rectangle(140, 180 + i * 60, 260, 220 + i * 60,
fill="white", outline="black", tags=f"speed{i}")
canvas.create_text(200, 200 + i * 60, text=teks,
font=("Arial", 12, "bold"), fill="black", tags=f"speed{i}")
canvas.tag_bind(f"speed{i}", "", lambda e, v=nilai: atur_kecepatan(v))
# Tombol kembali
canvas.create_rectangle(140, 360, 260, 400, fill="lightgray", tags="back_box")
canvas.create_text(200, 380, text="Kembali", font=("Arial", 12, "bold"),
fill="black", tags="back_text")
canvas.tag_bind("back_box", "", lambda e: tampilkan_menu())
canvas.tag_bind("back_text", "", lambda e: tampilkan_menu())
def atur_kecepatan(nilai):
global kecepatan
kecepatan = nilai
tampilkan_menu()
# --- Jalankan Program ---
root.bind("", ubah_arah)
tampilkan_menu()
root.mainloop()
Catatan: saat mem-paste kode pastikan indentasi (spasi/tabs) tetap sama. Simpan file sebagai snake_game.py lalu jalankan di Thonny (F5).
Penjelasan Kode Dipisah Per Bagian
1) Baris awal: import dan pengaturan awal
import tkinter as tk
import random
# --- Pengaturan Awal ---
LEBAR = 400
TINGGI = 400
UKURAN_KOTAK = 20
WARNA_LATAR = "lightgreen"
Penjelasan:
import tkinter as tk— Memanggil library GUI. Kita beri singkatantkagar pemanggilan fungsi tkinter lebih ringkas (misalnyatk.Tk()).import random— Memanggil modul untuk membuat angka acak (dipakai untuk posisi makanan dan rintangan).- Variabel
LEBAR,TINGGI,UKURAN_KOTAK, danWARNA_LATARberfungsi sebagai pengaturan ukuran layar dan tampilan. Memudahkan jika ingin diubah nanti.
2) Membuat jendela utama (root) dan canvas
# --- Jendela Utama ---
root = tk.Tk()
root.title("Game Ular Sekolah")
root.resizable(False, False)
# --- Kanvas Utama ---
canvas = tk.Canvas(root, width=LEBAR, height=TINGGI, bg=WARNA_LATAR)
canvas.pack()
Penjelasan:
root = tk.Tk()— Membuat jendela utama. Semua komponen GUI akan diletakkan di dalamroot.root.title()— Menentukan judul jendela.root.resizable(False, False)— Mencegah pengguna mengubah ukuran jendela agar tata letak tetap konsisten.canvas = tk.Canvas(...)— Membuat area gambar (kanvas) untuk menggambar ular, makanan, dan rintangan.canvas.pack()— Memasukkan kanvas ke dalam jendela agar tampil.
3) Variabel global
# Variabel global
arah = "kanan"
ular = []
makanan = ()
rintangan = []
skor = 0
game_berjalan = False
kecepatan = 150 # default kecepatan (ms)
Penjelasan:
arahmenyimpan arah gerak ular saat ini.ularadalah list berisi posisi bagian tubuh ular (setiap elemen tuple x,y).makananmenyimpan posisi makanan (tuple x,y).rintanganlist posisi rintangan (obstacle).skormenyimpan nilai skor pemain.game_berjalanBoolean yang menandakan apakah game sedang berjalan.kecepatanmenentukan interval pergerakan ular dalam milidetik (ms).
4) Fungsi gambar (rendering)
def gambar_ular():
canvas.delete("snake")
for (x, y) in ular:
canvas.create_rectangle(x, y, x + UKURAN_KOTAK, y + UKURAN_KOTAK,
fill="green", outline="darkgreen", tags="snake")
Penjelasan:
canvas.delete("snake")menghapus semua objek dengan tagsnakeagar digambar ulang (menghindari jejak).- Perulangan menggambar setiap bagian tubuh ular sebagai kotak persegi.
- Tag
snakememudahkan untuk menghapus/menangani objek ular pada kanvas.
def gambar_makanan():
canvas.delete("food")
x, y = makanan
canvas.create_oval(x, y, x + UKURAN_KOTAK, y + UKURAN_KOTAK,
fill="red", tags="food")
Penjelasan: menggambar makanan sebagai lingkaran kecil (oval) berwarna merah.
def gambar_skor():
canvas.delete("score")
canvas.create_text(60, 10, text=f"Skor: {skor}",
font=("Arial", 12, "bold"), fill="black", tags="score")
Penjelasan: menampilkan teks skor di pojok atas.
def gambar_rintangan():
canvas.delete("wall")
for (x, y) in rintangan:
canvas.create_rectangle(x, y, x + UKURAN_KOTAK, y + UKURAN_KOTAK,
fill="gray", outline="black", tags="wall")
Penjelasan: menggambar rintangan sebagai kotak abu-abu dengan tag wall.
5) Fungsi membuat objek acak
def buat_makanan():
x = random.randrange(0, LEBAR, UKURAN_KOTAK)
y = random.randrange(0, TINGGI, UKURAN_KOTAK)
return (x, y)
Penjelasan: random.randrange(0, LEBAR, UKURAN_KOTAK) memilih posisi grid yang sesuai ukuran kotak.
def buat_rintangan():
daftar_rintangan = []
for _ in range(8):
x = random.randrange(0, LEBAR, UKURAN_KOTAK)
y = random.randrange(0, TINGGI, UKURAN_KOTAK)
daftar_rintangan.append((x, y))
return daftar_rintangan
Penjelasan: membuat beberapa rintangan acak pada grid.
6) Fungsi utama: gerak_ular()
def gerak_ular():
global makanan, skor, game_berjalan
if not game_berjalan:
return
kepala_x, kepala_y = ular[0]
if arah == "kanan":
kepala_x += UKURAN_KOTAK
elif arah == "kiri":
kepala_x -= UKURAN_KOTAK
elif arah == "atas":
kepala_y -= UKURAN_KOTAK
elif arah == "bawah":
kepala_y += UKURAN_KOTAK
kepala_baru = (kepala_x, kepala_y)
# --- Cek Tabrakan ---
if (
kepala_x < 0 or kepala_x >= LEBAR or
kepala_y < 0 or kepala_y >= TINGGI or
kepala_baru in ular or kepala_baru in rintangan
):
game_over()
return
ular.insert(0, kepala_baru)
# --- Makan makanan ---
if kepala_baru == makanan:
skor += 10
makanan_baru = buat_makanan()
while makanan_baru in ular or makanan_baru in rintangan:
makanan_baru = buat_makanan()
makanan = makanan_baru
else:
ular.pop()
gambar_ular()
gambar_makanan()
gambar_rintangan()
gambar_skor()
root.after(kecepatan, gerak_ular)
Penjelasan utama (ringkasan):
- Menghitung posisi kepala baru berdasarkan
arah. - Mengecek apakah kepala menabrak dinding, dirinya sendiri, atau rintangan — jika ya maka
game_over(). - Jika kepala berada di posisi makanan, skor bertambah dan tubuh ular tidak dihapus (sehingga panjang bertambah).
- Jika tidak makan, bagian ekor dihapus (
ular.pop()) sehingga efeknya ular terlihat bergerak tanpa bertambah panjang. root.after(kecepatan, gerak_ular)memanggil fungsi ini berulang sesuai intervalkecepatan.
7) Mengubah arah (input keyboard)
def ubah_arah(event):
global arah
key = event.keysym
if key == "Up" and arah != "bawah":
arah = "atas"
elif key == "Down" and arah != "atas":
arah = "bawah"
elif key == "Left" and arah != "kanan":
arah = "kiri"
elif key == "Right" and arah != "kiri":
arah = "kanan"
elif key == "Return": # ENTER untuk pilih menu
pilih_menu()
elif key == "Up" or key == "Down": # navigasi menu
ubah_pilihan(key)
Penjelasan: event event.keysym memberi nama tombol yang ditekan. Fungsi ini mencegah balik arah 180° langsung (misal dari kanan langsung ke kiri) agar tidak tabrakan sendiri tiba-tiba.
8) Game Over & Restart
def game_over():
global game_berjalan
game_berjalan = False
canvas.delete("all")
canvas.create_text(LEBAR / 2, TINGGI / 2 - 30,
text="GAME OVER", font=("Arial", 24, "bold"), fill="red")
canvas.create_text(LEBAR / 2, TINGGI / 2,
text=f"Skor Akhir: {skor}", font=("Arial", 14), fill="black")
# Tombol restart
canvas.create_rectangle(130, 250, 270, 290, fill="yellow", tags="restart_box")
canvas.create_text(200, 270, text="Main Lagi", font=("Arial", 12, "bold"),
fill="black", tags="restart_text")
canvas.tag_bind("restart_box", "", lambda e: mulai_game())
canvas.tag_bind("restart_text", "", lambda e: mulai_game())
Penjelasan: pada saat game over, semua objek dihapus, pesan muncul, dan dibuat tombol restart dengan fungsi klik mouse.
9) Memulai game
def mulai_game():
global ular, makanan, arah, skor, game_berjalan, rintangan
canvas.delete("all")
ular = [(100, 100), (80, 100), (60, 100)]
makanan = buat_makanan()
rintangan = buat_rintangan()
arah = "kanan"
skor = 0
game_berjalan = True
gambar_ular()
gambar_makanan()
gambar_rintangan()
gambar_skor()
gerak_ular()
Penjelasan: fungsi ini mengatur ulang kondisi awal game sebelum dimainkan.
10) Menu utama & pengaturan
# --- MENU UTAMA ---
pilihan_menu = ["Mulai Game", "Pengaturan", "Keluar"]
indeks_pilihan = 0
def tampilkan_menu():
canvas.delete("all")
canvas.create_text(LEBAR / 2, 100, text="🐍 SNAKE GAME 🐍",
font=("Arial", 22, "bold"), fill="black")
for i, teks in enumerate(pilihan_menu):
warna = "white" if i == indeks_pilihan else "lightgray"
canvas.create_rectangle(140, 180 + i * 60, 260, 220 + i * 60,
fill=warna, outline="black", tags=f"menu{i}")
canvas.create_text(200, 200 + i * 60, text=teks,
font=("Arial", 12, "bold"), fill="black", tags=f"menu{i}")
canvas.tag_bind("menu0", "", lambda e: mulai_game())
canvas.tag_bind("menu1", "", lambda e: tampilkan_pengaturan())
canvas.tag_bind("menu2", "", lambda e: root.destroy())
def ubah_pilihan(key):
global indeks_pilihan
if key == "Up":
indeks_pilihan = (indeks_pilihan - 1) % len(pilihan_menu)
elif key == "Down":
indeks_pilihan = (indeks_pilihan + 1) % len(pilihan_menu)
tampilkan_menu()
def pilih_menu():
if indeks_pilihan == 0:
mulai_game()
elif indeks_pilihan == 1:
tampilkan_pengaturan()
elif indeks_pilihan == 2:
root.destroy()
Penjelasan: membuat menu interaktif yang bisa dipilih dengan keyboard atau mouse.
def tampilkan_pengaturan():
global kecepatan
canvas.delete("all")
canvas.create_text(LEBAR / 2, 100, text="⚙️ PENGATURAN KECEPATAN ⚙️",
font=("Arial", 18, "bold"), fill="black")
opsi = [("Pelan", 200), ("Sedang", 150), ("Cepat", 100)]
for i, (teks, nilai) in enumerate(opsi):
canvas.create_rectangle(140, 180 + i * 60, 260, 220 + i * 60,
fill="white", outline="black", tags=f"speed{i}")
canvas.create_text(200, 200 + i * 60, text=teks,
font=("Arial", 12, "bold"), fill="black", tags=f"speed{i}")
canvas.tag_bind(f"speed{i}", "", lambda e, v=nilai: atur_kecepatan(v))
# Tombol kembali
canvas.create_rectangle(140, 360, 260, 400, fill="lightgray", tags="back_box")
canvas.create_text(200, 380, text="Kembali", font=("Arial", 12, "bold"),
fill="black", tags="back_text")
canvas.tag_bind("back_box", "", lambda e: tampilkan_menu())
canvas.tag_bind("back_text", "", lambda e: tampilkan_menu())
def atur_kecepatan(nilai):
global kecepatan
kecepatan = nilai
tampilkan_menu()
Penjelasan: menu pengaturan berisi opsi pelan/sedang/cepat. Saat pilih, fungsi atur_kecepatan mengubah nilai global kecepatan.
11) Menjalankan program
# --- Jalankan Program ---
root.bind("", ubah_arah)
tampilkan_menu()
root.mainloop()
Penjelasan: root.bind("<Key>", ubah_arah) menghubungkan fungsi keyboard. tampilkan_menu() menampilkan menu awal. root.mainloop() menjalankan aplikasi.
Tabel Penilaian & Tugas Siswa
| Aspek | Bobot | Kriteria |
|---|---|---|
| Fungsionalitas | 40% | Program berjalan, kontrol, skor, rintangan |
| Tampilan (UI) | 25% | Menu jelas, teks terbaca, warna sesuai |
| Kreativitas & Ekstensi | 20% | Penambahan fitur: level, suara, dsb. |
| Dokumentasi | 15% | Penjelasan kode & komentar dalam kode |
Tugas
- Jalankan dan pahami seluruh kode.
- Tambahkan komentar pada setiap fungsi yang kamu buat.
- Tambahkan fitur: skor tertinggi (high score) atau level.
- Ubah warna/tata letak lalu kumpulkan hasil dengan screenshot.

0 Comments