Senin, 31 Agustus 2020

Algorithma Path Finding #6: Jalan yang lebih halus

In adalah pembahasan ke 6 dari seri Algorithma Path Finding. Pembahasan pertama bisa Anda baca pada tautan ini.

Pada tulisan sebelumnya, kita telah membahas bagaimana membuat karakter yang berjalan mengikuti jalur path-finding. Karakter berjalan dengan cara 'melompat-lompat' dari satu grid ke grid berikutnya.

Pada pembahasan kali ini, kita akan melakukan penyempurnaan cara berjalan. Karakter tidak lagi berjalan secara melompat-lompat, tapi berjalan perlahan-lahan dari satu grid ke grid berikutnya.

Kode sumber nya bisa diunduh di tautan ini:
https://drive.google.com/file/d/1-uGzY1QBcaCyZbUr4SgJSHZyXSQZMMw_/view?usp=sharing

Demo daring bisa dilihat di tautan ini:
https://hagarden.netlify.app/moon/400_jalan/

Video Youtube juga tersedia sbb:



Perubahan kode dari pembahasan sebelumnya.

Perubahan pertama adalah pada struktur data karakter.

let karakter = {
    jalur: [],
    jalurn: 0,
    pindahJml: 4,
    pindahn: 0,
    pos: {
        x: 32,
        y: 32
    },
    status: st_idle
};

Kita tambahkan dua property baru, yaitu pindahJml dan pindahn.
pindahJml berisi informasi jumlah langkah yang dibutuhkan untuk berpindah dari satu grid ke grid berikutnya. pindahn berisi informasi langkah yang ke-berapa.

Posisi karakter sekarang dirubah dari posisi di grid menjadi posisi di layar. Pada tulisan sebelumnya, posisi karakter berada pada posisi 1,1. Posisi ini merujuk pada posisi grid. Sekarang posisi karakter adalah 32, 32 yang merujuk pada posisi di layar. Satu grid adalah 32 x 32 pixel.

Perubahan berikutnya adalah penambahan fungsi-fungsi baru, antara lain:

function krkPosisiGrid(karakter) {
    return {
        x: Math.floor(karakter.pos.x / 32),
        y: Math.floor(karakter.pos.y / 32)
    };
}

Fungsi ini akan menghasilkan informasi posisi grid dimana karakter sekarang berdiri.

Fungsi baru berikutnya adalah fungsi krkCheckPosisiDiGrid().

function krkCheckPosisiDiGrid(karakter) {
    if (karakter.pos.x % 32)
        return false;
    if (karakter.pos.y % 32)
        return false;
    return true;
}

Fungsi ini mengecek apakah karakter sekarang sedang berada di grid atau berada diantara grid. Saat karakter berpindah dari grid satu ke grid berikutnya, maka posisi karakter sedang berada di antara grid sampai karakter tersebut sampai di grid berikutnya.

Fungsi berikutnya adalah fungsi krkPindahGrid()

function krkPindahGrid(karakter) {
    let posAwalX;
    let posAwalY;
    let posSelanjutnyaX;
    let posSelanjutnyaY;
    let jarakX;
    let jarakY;
    let posBaruX;
    let posBaruY;

    karakter.pindahn++;

    //posisi grid sekarang
    posAwalX = karakter.jalur[karakter.jalurn][0] * 32;
    posAwalY = karakter.jalur[karakter.jalurn][1] * 32;

    //posisi grid target
    posSelanjutnyaX = karakter.jalur[karakter.jalurn + 1][0] * 32;
    posSelanjutnyaY = karakter.jalur[karakter.jalurn + 1][1] * 32;

    //jarak dari grid sekarang ke target
    jarakX = posSelanjutnyaX - posAwalX;
    jarakY = posSelanjutnyaY - posAwalY;

    //posisi karakter baru
    posBaruX = posAwalX + (karakter.pindahn / karakter.pindahJml) * jarakX;
    posBaruY = posAwalY + (karakter.pindahn / karakter.pindahJml) * jarakY;

    karakter.pos.x = posBaruX;
    karakter.pos.y = posBaruY;

}

Fungsi ini adalah fungsi yang menangani perpindahan karakter dari grid satu ke grid berikutnya. Proses penghitungannya adalah sebagai berikut.

Pertama kita tambah nilai dari pindahn. Variable ini berisi informasi kita sedang di langkah ke berapa

    karakter.pindahn++;

Selanjutnya kita dapatkan posisi grid awal sebelum karakter berpindah.

    //posisi grid sekarang
    posAwalX = karakter.jalur[karakter.jalurn][0] * 32;
    posAwalY = karakter.jalur[karakter.jalurn][1] * 32;

Nilainya kita kali 32 untuk merubah dari posisi grid ke posisi di layar.

Setelah itu kita dapatkan posisi grid berikutnya, yang merupakan grid tujuan.

    //posisi grid target
    posSelanjutnyaX = karakter.jalur[karakter.jalurn + 1][0] * 32;
    posSelanjutnyaY = karakter.jalur[karakter.jalurn + 1][1] * 32;

Kemudian kita hitung jarak perpindahan dari grid sekarang ke grid berikutnya.

    //jarak dari grid sekarang ke target
    jarakX = posSelanjutnyaX - posAwalX;
    jarakY = posSelanjutnyaY - posAwalY;

Posisi karakter yang baru dihitung dari posisi awal + posisi perpindahan

//posisi karakter baru
    posBaruX = posAwalX + (karakter.pindahn / karakter.pindahJml) * jarakX;
    posBaruY = posAwalY + (karakter.pindahn / karakter.pindahJml) * jarakY;

Hasil dari posisi baru ini disimpan di karakter.

    karakter.pos.x = posBaruX;
    karakter.pos.y = posBaruY;

Berikutnya Kita akan membahas perubahan pada fungsi berikutnya, yaitu fungsi update():

function update() {
    if (karakter.status == st_idle) {
    }
    else if (karakter.status == st_jalan) {
        if (krkCheckPosisiDiGrid(karakter)) {
            karakter.jalurn++;
            if (karakter.jalurn >= karakter.jalur.length - 1) {
                karakter.status = st_idle;
            }
            else {
                karakter.status = st_jalan;
                karakter.pindahn = 0;
                krkPindahGrid(karakter);
            }
        }
        else {
            krkPindahGrid(karakter);
        }
    }
}

Kita merubah cara karakter berjalan. Tiap kali posisi karakter berada tepat di grid, maka kita tambahkan nilai dari jalurn.

if (krkCheckPosisiDiGrid(karakter)) {
  karakter.jalurn++;

Kemudian kita check apakah jalurn sudah mencapai maksimal, artinya karakter sudah sampai pada index terakhir. Bila ya, maka kita ubah status karakter menjadi idle.

if (karakter.jalurn >= karakter.jalur.length - 1) {
  karakter.status = st_idle;
}

Bila tidak, maka kita ubah statusnya jadi jalan lagi.


karakter.status = st_jalan;
karakter.pindahn = 0;

krkPindahGrid(karakter);

Untuk selanjutnya, maka kode sumbernya sama dengan sebelumnya,

Terima kasih telah mampir dan membaca.














Tidak ada komentar:

Posting Komentar