๐Ÿ  Beranda โ€บ Bahan Ajar โ€บ Cara Membuat Game Stickman Runner dengan...
Bahan Ajar

Cara Membuat Game Stickman Runner dengan HTML & JavaScript

Adi Irawan, M.Pd.Gr.
Adi Irawan, M.Pd.Gr.
๐Ÿ“… 14 September 2026 โฑ 16 mnt baca ๐Ÿ’ฌ 0 komentar
Cara Membuat Game Stickman Runner dengan HTML & JavaScript
Buat Game Stickman Runner dengan HTML & JavaScript โ€” Tutorial Ekskul Coding SMP
๐Ÿ“š Tutorial Ekskul Coding SMP

Bikin Game Stickman Runner dari Nol Pakai HTML & JavaScript!

Halo para coder muda! ๐Ÿ‘‹ Di sesi kali ini kita akan bikin game seru bareng โ€” Stickman Runner! Stickman lari, ada rintangan kaktus dan burung, dan kamu harus melompat menghindarinya. Semakin lama bertahan, skor kamu makin tinggi!

Yang paling keren: kita akan bikin semua ini dari nol โ€” baris demi baris โ€” pakai tiga teknologi yang sudah kalian pelajari: HTML, CSS, dan JavaScript. Yuk langsung gas! ๐Ÿš€

Iklan

Iklan

๐Ÿ› ๏ธ
Tools
VS Code / Notepad++
๐ŸŒ
Teknologi
HTML ยท CSS ยท JavaScript
๐ŸŽฏ
Level
Pemulaโ€“Menengah
โฑ๏ธ
Waktu
2 Sesi (4 ร— 40 mnt)

๐Ÿง  Konsep Coding yang Akan Kita Pelajari

Sebelum mulai, kita kenali dulu konsep apa saja yang akan dipakai dalam game ini. Jangan panik โ€” semua akan dijelaskan sambil kita coding!

Konsep Dipakai untuk Teknologi
Canvas Area menggambar game kita HTML
Variabel Menyimpan posisi, kecepatan, skor JS
Fungsi (Function) Memisahkan tugastiap bagian game JS
Perulangan (Loop) Game loop yang terus berjalan JS
Kondisi (if/else) Deteksi tabrakan, game over JS
Object Stickman, rintangan sebagai satu kesatuan JS
Array Menyimpan banyak rintangan sekaligus JS
Event Listener Mendeteksi tombol spasi / klik JS
๐Ÿ’ก
Target Akhir Kita

Setelah 2 pertemuan, game kalian bisa: stickman bergerak dengan gravitasi, lompat double-jump, ada rintangan kaktus dan burung yang makin cepat, sistem skor, dan high score!


Sesi 1 Fondasi โ€” Canvas, Stickman & Gravitasi

Step 1 Buat File dan Struktur HTML Dasar

Buka VS Code, buat file baru bernama stickman.html, lalu ketik kode berikut:

stickman.html
<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="UTF-8">
  <title>Stickman Runner</title>
  <style>
    body {
      background: #1a1a2e;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      min-height: 100vh;
      font-family: sans-serif;
      color: white;
    }
    canvas {
      border: 3px solid #e94560;
      border-radius: 8px;
      display: block;
    }
  </style>
</head>
<body>

  <h1>๐Ÿƒ Stickman Runner</h1>
  <canvas id="gameCanvas" width="600" height="250"></canvas>

  <script>
    // Kita ambil canvas dari HTML
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');

    // Gambar latar belakang untuk tes
    ctx.fillStyle = '#0f0f23';
    ctx.fillRect(0, 0, 600, 250);

    // Gambar tanah
    ctx.fillStyle = '#2c3e50';
    ctx.fillRect(0, 235, 600, 15);

    console.log('Canvas siap! ๐ŸŽฎ');
  </script>

</body>
</html>
๐Ÿ”ต
Coba dulu!

Simpan file (Ctrl+S), lalu buka di browser. Kalian akan lihat kotak hitam dengan garis tanah. Itu artinya canvas kita berhasil! Buka Console di F12 untuk cek pesan “Canvas siap!”

Step 2 Gambar Stickman dengan Canvas Drawing

Sekarang kita bikin fungsi untuk menggambar stickman. Ganti bagian <script> dengan kode berikut:

stickman.html โ€” bagian <script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

// ============================================
// VARIABEL STICKMAN
// ============================================
let stickmanX = 80;    // posisi horizontal
let stickmanY = 180;   // posisi vertikal

// ============================================
// FUNGSI GAMBAR STICKMAN
// ============================================
function gambarStickman(x, y) {
  const cx = x + 15;  // titik tengah horizontal

  ctx.strokeStyle = '#ffffff';
  ctx.lineWidth = 3;
  ctx.lineCap = 'round';

  // --- Kepala ---
  ctx.beginPath();
  ctx.arc(cx, y, 10, 0, Math.PI * 2);
  ctx.fillStyle = '#ffffff';
  ctx.fill();

  // --- Badan ---
  ctx.beginPath();
  ctx.moveTo(cx, y + 10);
  ctx.lineTo(cx, y + 35);
  ctx.stroke();

  // --- Tangan kiri ---
  ctx.beginPath();
  ctx.moveTo(cx, y + 17);
  ctx.lineTo(cx - 12, y + 30);
  ctx.stroke();

  // --- Tangan kanan ---
  ctx.beginPath();
  ctx.moveTo(cx, y + 17);
  ctx.lineTo(cx + 12, y + 30);
  ctx.stroke();

  // --- Kaki kiri ---
  ctx.beginPath();
  ctx.moveTo(cx, y + 35);
  ctx.lineTo(cx - 12, y + 55);
  ctx.stroke();

  // --- Kaki kanan ---
  ctx.beginPath();
  ctx.moveTo(cx, y + 35);
  ctx.lineTo(cx + 12, y + 55);
  ctx.stroke();
}

// Gambar dulu langit + tanah
ctx.fillStyle = '#0f0f23';
ctx.fillRect(0, 0, 600, 250);
ctx.fillStyle = '#2c3e50';
ctx.fillRect(0, 235, 600, 15);

// Panggil fungsi gambar stickman
gambarStickman(stickmanX, stickmanY);
๐ŸŽจ
Eksperimen!

Coba ganti angka-angka di moveTo dan lineTo โ€” misalnya badan lebih panjang, atau tangan lebih lebar. Kalian bisa bikin stickman dengan gaya sendiri!

Step 3 Tambah Gravitasi & Lompatan

Ini bagian paling seru! Kita akan bikin stickman bisa jatuh karena gravitasi, dan bisa melompat ketika spasi ditekan. Ganti isi <script> dengan kode berikut:

stickman.html โ€” bagian <script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

// ============================================
// DATA STICKMAN โ€” kita gabungkan jadi OBJECT
// ============================================
const stickman = {
  x: 80,
  y: 180,      // posisi saat ini
  vy: 0,       // kecepatan vertikal (- = naik, + = turun)
  groundY: 180, // posisi tanah
  jumpCount: 0 // hitungan lompatan (max 2 untuk double jump)
};

const GRAVITASI = 0.6;
const KEKUATAN_LOMPAT = -13;

// ============================================
// FUNGSI GAMBAR STICKMAN
// ============================================
function gambarStickman() {
  const cx = stickman.x + 15;
  const y = stickman.y;

  ctx.strokeStyle = '#ffffff';
  ctx.lineWidth = 3;
  ctx.lineCap = 'round';

  ctx.beginPath();
  ctx.arc(cx, y, 10, 0, Math.PI * 2);
  ctx.fillStyle = '#ffffff';
  ctx.fill();

  ctx.beginPath();
  ctx.moveTo(cx, y + 10);
  ctx.lineTo(cx, y + 35);
  ctx.stroke();

  ctx.beginPath();
  ctx.moveTo(cx, y + 17);
  ctx.lineTo(cx - 12, y + 30);
  ctx.stroke();

  ctx.beginPath();
  ctx.moveTo(cx, y + 17);
  ctx.lineTo(cx + 12, y + 30);
  ctx.stroke();

  ctx.beginPath();
  ctx.moveTo(cx, y + 35);
  ctx.lineTo(cx - 12, y + 55);
  ctx.stroke();

  ctx.beginPath();
  ctx.moveTo(cx, y + 35);
  ctx.lineTo(cx + 12, y + 55);
  ctx.stroke();
}

// ============================================
// UPDATE โ€” logika fisika setiap frame
// ============================================
function update() {
  // Tambahkan gravitasi ke kecepatan vertikal
  stickman.vy += GRAVITASI;

  // Gerakkan stickman sesuai kecepatan
  stickman.y += stickman.vy;

  // Cek apakah sudah menyentuh tanah
  if (stickman.y >= stickman.groundY) {
    stickman.y = stickman.groundY;   // snap ke tanah
    stickman.vy = 0;                // stop jatuh
    stickman.jumpCount = 0;         // reset hitungan lompatan
  }
}

// ============================================
// GAME LOOP โ€” ini yang membuat game berjalan!
// ============================================
function gameLoop() {
  // 1. Bersihkan canvas
  ctx.clearRect(0, 0, 600, 250);

  // 2. Gambar latar belakang
  ctx.fillStyle = '#0f0f23';
  ctx.fillRect(0, 0, 600, 250);
  ctx.fillStyle = '#2c3e50';
  ctx.fillRect(0, 235, 600, 15);

  // 3. Update posisi stickman
  update();

  // 4. Gambar stickman
  gambarStickman();

  // 5. Ulangi terus menerus (60x per detik)
  requestAnimationFrame(gameLoop);
}

// ============================================
// KONTROL โ€” deteksi tombol spasi
// ============================================
document.addEventListener('keydown', function(e) {
  if (e.code === 'Space') {
    e.preventDefault();

    if (stickman.jumpCount < 2) {   // Double jump!
      stickman.vy = KEKUATAN_LOMPAT;
      stickman.jumpCount++;
    }
  }
});

// Mulai game loop!
gameLoop();
โš ๏ธ
Paham dulu konsepnya!

Gravitasi = setiap frame, kecepatan turun bertambah 0.6. Seperti bola yang dilempar ke atas โ€” makin lama makin melambat, lalu jatuh. requestAnimationFrame membuat gameLoop dipanggil ~60 kali per detik!


Sesi 2 Rintangan, Skor & Game Over

Step 4 Tambah Rintangan Kaktus

Stickman sudah bisa lompat. Sekarang kita tambahkan kaktus yang bergerak dari kanan ke kiri! Tambahkan kode ini setelah bagian stickman (sebelum gameLoop):

stickman.html โ€” tambahkan bagian rintangan
// ============================================
// RINTANGAN
// ============================================
let rintangan = [];       // array untuk menyimpan semua kaktus
let timerRintangan = 0;   // penghitung waktu kemunculan
const KECEPATAN = 4;      // seberapa cepat rintangan bergerak

// Fungsi membuat kaktus baru
function buatKaktus() {
  const tinggi = 30 + Math.random() * 25; // tinggi acak 30-55

  rintangan.push({
    x: 620,               // mulai dari kanan canvas
    y: 235 - tinggi,      // posisi atas kaktus
    lebar: 20,
    tinggi: tinggi
  });
}

// Fungsi gambar kaktus
function gambarKaktus(k) {
  ctx.fillStyle = '#2ecc71';

  // Batang utama
  ctx.fillRect(k.x + 5, k.y, 10, k.tinggi);

  // Cabang kiri
  ctx.fillRect(k.x, k.y + 8, 5, 12);

  // Cabang kanan
  ctx.fillRect(k.x + 15, k.y + 5, 5, 12);
}

// ============================================
// Tambahkan ke dalam gameLoop():
// ============================================
// Tulis ini DI DALAM fungsi gameLoop, setelah update()

// Spawn kaktus setiap 80 frame
timerRintangan++;
if (timerRintangan >= 80) {
  buatKaktus();
  timerRintangan = 0;
}

// Gerakkan dan gambar semua kaktus
rintangan.forEach(function(k) {
  k.x -= KECEPATAN;      // gerakkan ke kiri
  gambarKaktus(k);       // gambar
});

// Hapus kaktus yang sudah keluar layar (kiri)
rintangan = rintangan.filter(function(k) {
  return k.x > -50;
});

Step 5 Deteksi Tabrakan (Collision Detection)

Game butuh tahu kalau stickman menabrak kaktus. Ini disebut collision detection. Kita pakai teknik “AABB” โ€” membandingkan kotak pembatas dua objek:

stickman.html โ€” fungsi deteksi tabrakan
// ============================================
// DETEKSI TABRAKAN
// ============================================
let gameOver = false;

function cekTabrakan(k) {
  // Kita kasih sedikit "ruang" agar tidak terlalu ketat
  const margin = 6;

  // Kotak stickman
  const sx = stickman.x + margin;
  const sy = stickman.y + margin;
  const sw = 30 - margin * 2;  // lebar stickman
  const sh = 55 - margin * 2;  // tinggi stickman

  // Cek apakah dua kotak bersentuhan
  const tabrakan =
    sx < k.x + k.lebar &&
    sx + sw > k.x &&
    sy < k.y + k.tinggi &&
    sy + sh > k.y;

  if (tabrakan) {
    gameOver = true;
    console.log('Game Over! ๐Ÿ’ฅ');
  }
}

// Panggil cekTabrakan untuk setiap kaktus di dalam gameLoop
rintangan.forEach(function(k) {
  cekTabrakan(k);
});

Step 6 Sistem Skor & Layar Game Over

Terakhir, kita tambahkan skor yang naik otomatis dan tampilan game over. Ini kode lengkap final kalian โ€” salin semua dan ganti file lama:

โœ…
Kode Final Lengkap

Kode di bawah adalah versi final yang sudah punya skor, high score, layar start, layar game over, dan kecepatan yang makin cepat. Ini hasil kerja keras 2 sesi!

stickman.html โ€” VERSI FINAL
<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="UTF-8">
  <title>Stickman Runner</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      background: #1a1a2e; display: flex; flex-direction: column;
      align-items: center; justify-content: center;
      min-height: 100vh; font-family: sans-serif; color: white;
    }
    h1 { color: #e94560; margin-bottom: 10px; font-size: 1.8rem; }
    #ui { display: flex; justify-content: space-between; width: 600px; padding: 8px 4px; }
    #score { color: #f5a623; font-weight: bold; }
    #rekor { color: #7ed6a7; font-weight: bold; }
    canvas { border: 3px solid #e94560; border-radius: 8px; display: block; }
    #petunjuk { margin-top: 8px; color: #aaa; font-size: 0.85rem; }
  </style>
</head>
<body>
  <h1>๐Ÿƒ Stickman Runner</h1>
  <div id="ui">
    <span id="score">Score: 0</span>
    <span id="rekor">Rekor: 0</span>
  </div>
  <canvas id="gameCanvas" width="600" height="250"></canvas>
  <p id="petunjuk">โฌ† Tekan SPASI atau klik layar untuk lompat</p>

<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreEl = document.getElementById('score');
const rekorEl = document.getElementById('rekor');

// === VARIABEL GAME ===
let gameJalan = false;
let gameOver = false;
let score = 0;
let rekor = 0;
let frame = 0;
let kecepatan = 4;

// === STICKMAN ===
const sm = {
  x: 80, y: 180, vy: 0,
  groundY: 180, jumpCount: 0
};

function lompat() {
  if (sm.jumpCount < 2) {
    sm.vy = -13;
    sm.jumpCount++;
  }
}

function updateStickman() {
  sm.vy += 0.6;
  sm.y += sm.vy;
  if (sm.y >= sm.groundY) {
    sm.y = sm.groundY; sm.vy = 0; sm.jumpCount = 0;
  }
}

function gambarStickman() {
  const cx = sm.x + 15, y = sm.y;
  ctx.strokeStyle = '#fff'; ctx.lineWidth = 3; ctx.lineCap = 'round';
  ctx.beginPath(); ctx.arc(cx, y, 10, 0, Math.PI*2);
  ctx.fillStyle = '#fff'; ctx.fill();
  [[cx, y+10, cx, y+35],[cx, y+17, cx-12, y+30],
   [cx, y+17, cx+12, y+30],[cx, y+35, cx-12, y+55],
   [cx, y+35, cx+12, y+55]].forEach(function(l) {
    ctx.beginPath(); ctx.moveTo(l[0],l[1]); ctx.lineTo(l[2],l[3]); ctx.stroke();
  });
}

// === RINTANGAN ===
let rintangan = [], timerR = 0;

function buatKaktus() {
  const t = 30 + Math.random() * 25;
  rintangan.push({ x: 620, y: 235-t, lebar: 20, tinggi: t });
}

function gambarKaktus(k) {
  ctx.fillStyle = '#2ecc71';
  ctx.fillRect(k.x+5, k.y, 10, k.tinggi);
  ctx.fillRect(k.x, k.y+8, 5, 12);
  ctx.fillRect(k.x+15, k.y+5, 5, 12);
}

function cekTabrakan(k) {
  const m=6, sx=sm.x+m, sy=sm.y+m, sw=30-m*2, sh=55-m*2;
  if (sx < k.x+k.lebar && sx+sw > k.x && sy < k.y+k.tinggi && sy+sh > k.y) {
    gameOver = true; gameJalan = false;
    if (score > rekor) { rekor = score; rekorEl.textContent = `Rekor: ${rekor}`; }
  }
}

// === LAYAR TEKS ===
function tulisLayar(judul, sub, warna) {
  ctx.fillStyle = 'rgba(0,0,0,0.6)'; ctx.fillRect(0,0,600,250);
  ctx.fillStyle = warna; ctx.font = 'bold 36px sans-serif';
  ctx.textAlign = 'center'; ctx.fillText(judul, 300, 90);
  ctx.fillStyle = '#fff'; ctx.font = '18px sans-serif'; ctx.fillText(sub, 300, 130);
  ctx.fillStyle = '#f5a623'; ctx.font = 'bold 20px sans-serif';
  ctx.fillText('Tekan SPASI / Klik untuk mulai', 300, 200);
  ctx.textAlign = 'left';
}

// === GAME LOOP ===
function gameLoop() {
  ctx.clearRect(0,0,600,250);
  ctx.fillStyle='#0f0f23'; ctx.fillRect(0,0,600,250);
  ctx.fillStyle='#2c3e50'; ctx.fillRect(0,235,600,15);

  if (!gameJalan && !gameOver) {
    gambarStickman();
    tulisLayar('STICKMAN RUNNER', 'Hindari kaktus! Double jump tersedia ๐Ÿฆ…', '#e94560');
    requestAnimationFrame(gameLoop); return;
  }

  if (gameOver) {
    gambarStickman();
    rintangan.forEach(gambarKaktus);
    tulisLayar('GAME OVER!', `Score kamu: ${score}`, '#e94560');
    requestAnimationFrame(gameLoop); return;
  }

  frame++;
  score = Math.floor(frame/6);
  kecepatan = 4 + Math.floor(score/200) * 0.8;
  scoreEl.textContent = `Score: ${score}`;

  timerR++;
  if (timerR >= Math.max(80 - Math.floor(score/100)*3, 35)) {
    buatKaktus(); timerR=0;
  }

  rintangan.forEach(function(k) { k.x-=kecepatan; gambarKaktus(k); cekTabrakan(k); });
  rintangan = rintangan.filter(function(k){ return k.x > -50; });

  updateStickman();
  gambarStickman();

  requestAnimationFrame(gameLoop);
}

// === INPUT ===
function aksi() {
  if (!gameJalan && !gameOver) {
    gameJalan=true; score=0; frame=0; kecepatan=4;
    rintangan=[]; timerR=0;
    sm.y=sm.groundY; sm.vy=0; sm.jumpCount=0;
    lompat();
  } else if (gameOver) {
    gameOver=false; gameJalan=true; score=0; frame=0; kecepatan=4;
    rintangan=[]; timerR=0;
    sm.y=sm.groundY; sm.vy=0; sm.jumpCount=0;
  } else {
    lompat();
  }
}

document.addEventListener('keydown', function(e) {
  if (e.code==='Space') { e.preventDefault(); aksi(); }
});
canvas.addEventListener('click', aksi);

gameLoop();
</script>
</body>
</html>

๐Ÿš€ Tantangan Kreatif untuk Siswa

Sudah selesai game dasarnya? Jangan berhenti di sini! Coba tantangan berikut untuk membuat game kalian makin seru dan unik:

โญ Level 1 โ€” Modifikasi Dasar

  • Ganti warna stickman menjadi warna favorit kamu
  • Buat kaktus lebih besar atau lebih kecil
  • Tambahkan efek suara saat melompat menggunakan AudioContext
  • Ubah background menjadi siang hari (langit biru)

โญโญ Level 2 โ€” Fitur Baru

  • Tambahkan rintangan burung yang terbang di ketinggian berbeda
  • Buat koin yang bisa dikumpulkan untuk bonus skor
  • Tambahkan level system (tiap 500 poin naik level)
  • Buat stickman bisa jongkok (tekan bawah/S) untuk hindari burung

โญโญโญ Level 3 โ€” Eksplorasi Mandiri

  • Simpan high score ke localStorage agar tidak hilang saat refresh
  • Tambahkan karakter berbeda yang bisa dipilih
  • Buat animasi kaki stickman saat berlari
  • Tambahkan mode multiplayer (2 pemain di keyboard yang sama)

๐Ÿ“ Kesimpulan & Refleksi

โœ“
Struktur HTML Canvas
โœ“
Gambar dengan Drawing API
โœ“
Gravitasi & Fisika
โœ“
Game Loop
โœ“
Rintangan & Array
โœ“
Collision Detection
โœ“
Sistem Skor
โœ“
Event Listener

Selamat! Kalian sudah membuat game lengkap dari nol. Ini bukan hal kecil โ€” banyak developer profesional memulai perjalanan mereka persis seperti ini: membuat game sederhana di browser.

Konsep yang kalian pelajari hari ini โ€” loop, kondisi, object, array, event โ€” adalah fondasi dari semua program komputer. Sama persis yang dipakai di aplikasi besar seperti Gojek, Shopee, sampai game PC!

๐Ÿ†
Langkah Selanjutnya

Di sesi berikutnya kita akan belajar menghubungkan game dengan AI menggunakan Kimi AI API โ€” bayangkan stickman yang bisa bicara dan bercerita! Sampai jumpa! ๐Ÿ‘‹

๐Ÿ“š Materi Ekskul Coding SMP IT Bustanul Ulum ยท Terbanggi Besar, Lampung Tengah

Dibuat oleh Adi Irawan, S.Pd., Gr., M.Pd. ยท IT Coordinator IGI Lampung Tengah

Silakan dibagikan dan dimodifikasi untuk keperluan pendidikan ๐ŸŽ“

Adi Irawan
Adi Irawan, M.Pd.Gr.
Guru Matematika ยท CEO CV HNF GRAFIS ยท Mahasiswa S2 UM Metro
Pendidik dan pengembang perangkat lunak dari Lampung Tengah. Sekretaris MGMP Matematika dan Pengurus IGI Lampung Tengah. Membangun MahaGuru untuk menghadirkan pendidikan berkualitas bagi semua guru Indonesia.
๐Ÿ’ฌ Komentar 0
โœ๏ธ Tinggalkan Komentar
Email tidak akan ditampilkan publik. Komentar akan muncul setelah dimoderasi.
โšก
Generate Modul Ajar
Buat modul ajar Kurikulum Merdeka dalam hitungan menit.
Coba Sekarang โ†’