Logo SMK Muhammadiyah 2 Pekanbaru
Logo GameDev PKU
Workshop SMK Series

LOGIKA & ALGORITMA GAME

Dari instruksi sederhana hingga sistem yang kompleks. Pelajari cara berpikir layaknya seorang pengembang game profesional.

Pondasi 01

Apakah Algoritma Itu?

Algoritma adalah instruksi terurut yang diberikan kepada komputer untuk menyelesaikan suatu tugas. Apabila Anda ingin membuat karakter melompat, komputer memerlukan serangkaian perintah yang tepat dan berurutan. Tanpa urutan yang benar, program permainan tidak akan berjalan sebagaimana mestinya.

Contoh Algoritma "Musuh Mengejar Pemain":

  1. 1. Periksa jarak antara Musuh dan Pemain.
  2. 2. Jika jarak kurang dari 5 meter, jalankan animasi berlari.
  3. 3. Pindahkan koordinat Musuh ke arah koordinat Pemain.
  4. 4. Jika jarak kurang dari 1 meter, jalankan animasi menyerang.

Perbandingan Efisiensi Algoritma

Metrik Algoritma Efisien Tidak Terstruktur
Kecepatan Proses Tinggi Rendah
Efisiensi Memori Tinggi Rendah
Keterbacaan Kode Sangat Tinggi Rendah
Ketepatan Logika Tinggi Sedang
Fleksibilitas Tinggi Sedang

Dari Algoritma Menuju Kode

Bagaimana "resep" algoritma diterjemahkan menjadi kode program? Mari kita lihat transformasi langkah demi langkah dari logika konseptual menjadi bahasa pemrograman formal yang dapat dieksekusi oleh mesin.

1

Periksa jarak antara Musuh dan Pemain.

2

Jika jarak < 5 meter, jalankan animasi berlari.

3

Pindahkan koordinat Musuh ke arah Pemain.

4

Jika jarak < 1 meter, jalankan animasi menyerang.

musuh_ai.cs
// Fungsi pembaruan yang dipanggil setiap frame
void Update() {
    // 1. Kalkulasi jarak
    float jarak = Vector3.Distance(
        transform.posisi,
        pemain.posisi
    );
    // 2. Evaluasi kondisi kejar
    if (jarak < 5.0f) {
        animator.SetBool("Berlari", true);
        // 3. Pergerakan ke arah pemain
        GerakKeArah(pemain.posisi);
        // 4. Evaluasi kondisi serang
        if (jarak < 1.0f) {
            animator.SetTrigger("Serang");
        }
    }
}
DRY PATTERN

Skalabilitas: Upaya vs. Jumlah Fitur

Don't Repeat Yourself

Bayangkan apabila setiap karakter musuh memiliki kode "mati" yang berbeda-beda. Saat Anda ingin menambahkan efek suara, Anda harus mengubah ratusan baris kode secara terpisah.

+ Gunakan satu Pusat Logika yang dapat digunakan bersama oleh seluruh objek dalam permainan.

Penerapan pada Algoritma Musuh

Sebelum DRY — Kode Duplikat
// Musuh jenis Prajurit
class Prajurit : MonoBehaviour {
    void Update() {        float jarak = Vector3.Distance(
            transform.position, pemain.position);
        if (jarak < 5f) transform.LookAt(pemain);
        if (jarak < 5f) transform.position =
            Vector3.MoveTowards(transform.position,
                pemain.position, 3f * Time.deltaTime);    }
}// Musuh jenis Pemanah — logika SAMA, duplikat
class Pemanah : MonoBehaviour {
    void Update() {
        float jarak = Vector3.Distance(
            transform.position, pemain.position);
        if (jarak < 8f) transform.LookAt(pemain);
        if (jarak < 8f) transform.position =
            Vector3.MoveTowards(transform.position,
                pemain.position, 2f * Time.deltaTime);
    }
}
// Perubahan harus diulang di SETIAP kelas!
Sesudah DRY — Pusat Logika
// Satu kelas induk dengan logika bersamaabstract class MusuhBase : MonoBehaviour {
    protected Transform pemain;
    protected abstract float jarakDeteksi { get; }
    protected abstract float kecepatanGerak { get; }
    void Update() {        float jarak = Vector3.Distance(
            transform.position, pemain.position);
        if (jarak < jarakDeteksi) {
            transform.LookAt(pemain);
            transform.position = Vector3.MoveTowards(
                transform.position, pemain.position,
                kecepatanGerak * Time.deltaTime);        }
    }
}
// Setiap musuh hanya menentukan nilai uniknyaclass Prajurit : MusuhBase {
    protected override float jarakDeteksi => 5f;
    protected override float kecepatanGerak => 3f;
}
class Pemanah : MusuhBase {
    protected override float jarakDeteksi => 8f;
    protected override float kecepatanGerak => 2f;
}
// Ubah logika sekali → berlaku ke semua!
OBSERVER PATTERN

Menghentikan Pemeriksaan Berulang (Polling)

Dalam sebuah game engine, melakukan pemeriksaan status pada setiap siklus pembaruan membutuhkan sumber daya yang besar. Pendekatan yang lebih efisien adalah menggunakan sistem Siaran (Broadcast), di mana suatu objek mengirimkan notifikasi hanya ketika terjadi perubahan.

Kejadian (Event)

Pemain membuka peti harta karun.

Pemberitahuan (Broadcast)

Sistem mengirimkan notifikasi: "Peti harta telah terbuka."

Respons Otomatis

Antarmuka skor dan efek suara merespons secara langsung.

Dampak terhadap Beban Prosesor

Penerapan pada Algoritma Musuh

Sebelum Observer — Polling Tiap Frame
// UI, suara & minimap cek posisi musuh masing-masing
class UIManager : MonoBehaviour {    void Update() {
        // Dijalankan SETIAP FRAME — sangat boros!
        float j = Vector3.Distance(
            musuh.position, pemain.position);
        if (j < 5f) healthBar.TampilkanPeringatan();
    }}
class AudioManager : MonoBehaviour {    void Update() {
        // Pemeriksaan DUPLIKAT — hal yang sama!
        float j = Vector3.Distance(
            musuh.position, pemain.position);
        if (j < 5f) audio.PutarSuaraWaspada();
    }}
class Minimap : MonoBehaviour {    void Update() {
        // Pemeriksaan KETIGA — hal yang sama!
        float j = Vector3.Distance(
            musuh.position, pemain.position);
        if (j < 5f) minimap.SorotMusuh(musuh);
    }}
// 3× cek jarak per frame — sangat boros!
Sesudah Observer — Siaran Satu Kejadian
// Musuh cek jarak SEKALI, lalu menyiarkan kejadian
class MusuhBase : MonoBehaviour {    public static event Action OnMusuhMendekat;
    void Update() {
        float jarak = Vector3.Distance(
            transform.position, pemain.position);
        if (jarak < jarakDeteksi)            OnMusuhMendekat?.Invoke(); // Siaran 1×!    }
}
// Setiap sistem mendaftarkan diri sebagai pendengarclass UIManager : MonoBehaviour {
    void OnEnable()  =>
        MusuhBase.OnMusuhMendekat += TampilkanPeringatan;
    void OnDisable() =>
        MusuhBase.OnMusuhMendekat -= TampilkanPeringatan;
}
class AudioManager : MonoBehaviour {
    void OnEnable()  =>
        MusuhBase.OnMusuhMendekat += PutarSuaraWaspada;
    void OnDisable() =>
        MusuhBase.OnMusuhMendekat -= PutarSuaraWaspada;
}
class Minimap : MonoBehaviour {
    void OnEnable()  =>
        MusuhBase.OnMusuhMendekat += SorotMusuh;
    void OnDisable() =>
        MusuhBase.OnMusuhMendekat -= SorotMusuh;
}
// 1× cek jarak — semua sistem merespons!
STATE PATTERN

Finite State Machine (FSM)

Setiap karakter memiliki state — kondisi aktif yang mendefinisikan aksi apa saja yang secara teknis valid untuk dieksekusi. State Pattern menegakkan aturan ini secara programatik, mencegah transisi ilegal seperti double-jump di udara.

Diagram Transisi State

DIAM Siaga BERLARI Horizontal aktif MELOMPAT Melayang berlari() berhenti() lompat() mendarat()

Setiap panah merepresentasikan satu transisi yang terdefinisi dan legal dalam FSM.

Simulator Interaktif

State Aktif

DIAM

Karakter siaga — menunggu input pemain.

Kirim Aksi ke Karakter

Log Transisi

Belum ada transisi...

Sesi Berikutnya

Ayo Kita
Bedah Game

Saatnya melihat bagaimana sebuah game
benar-benar bekerja dari dalam.

Dipandu oleh

Bang Habi

GBStudio