Sabtu, 07 November 2020
Rabu, 30 September 2020
Agorithma Path Finding #9: Config [DRAFT]
Ini adalah pembahasan ke 9 dari seri Algorithma Path Finding. Pembahasan pertama bisa Anda baca pada tautan ini.
Pada pembahasan sebelumnya kita membahas tentang refaktoring kode sumber kita untuk persiapan pembahasan selanjutnya yang akan banyak membahas tentang variasi dalam path finding. Kita akan membuat algorithma kita lebih fleksibel dengan konfigurasi yang bisa diubah-ubah sesuai kebutuhan.
Kode sumber bisa di download disini
Perubahan pada file PathFinder.js
Senin, 28 September 2020
HAGL - Library WebGL Sederhana
Awalnya Saya hanya ingin mencari library WebGL yang fokus ke rendering, dan sudah nemu juga, namanya PIXI.js. PIXI.js sangat bagus sekali, sangat recomended. Tapi PIXI punya masalah yang Saya kurang sreg, yaitu ukurannya yang terlalu besar, yaitu hampir 1/2 MB. Terlau besar, menurut Saya untuk sebuah library. Padahal target saya, ukurannya gak lebih besar dari 100 kb.
Setelah mempertimbangkan masak-masak, akhirnya Saya memutuskan untuk membuat library WebGL sendiri. Library ini Saya beri nama HAGL.
HAGL adalah sebuah library sederhana untuk menggambar menggunakan WebGL di browser.
HAGL bukan game enggine, tapi bisa digunakan untuk merender game, khususnya game 2D.
HAGL bisa untuk menggambar image, tileset, ataupun spritesheet.
HAGL bukan 3d enggine. HAGL hanya memfokuskan pada fungsi utama dari WebGL sebagai rasterising engine. Cocok untuk game 2D di browser yang butuh performa tambahan untuk menggambar.
Cara penggunaannya sangat sederhana:
var gl = new Hagl(canvas);
gl.drawImage(image, x, y);
Atau bisa juga pakai pilihan
var gl = new Hagl(canvas);
gl.drawImage(image, x, y, {pilihan})
pilihan yang tersedia antara lain:
skala, rotasi, alpha, offset, dan textureUV.
Contoh penggunaan tersedia dalam demo yang bisa dicoba disini:
https://hagarden.blogspot.com/p/blog-page.html
Saat ini fitur dan demonya masih sedikit. Saya akan menambahkan sedikit demi sedikit pada update-update selanjutnya.
Jumat, 25 September 2020
Algorithma Path Finding #8: Refaktor
Ini adalah pembahasan ke 8 dari seri Algorithma Path Finding. Pembahasan pertama bisa Anda baca pada tautan ini.
Pada pembahasan sebelumnya kita membahas tentang A * (Star). A Star path finding menghasilkan jalur yang lebih optimal dari sebelumnya.
Pada pembahasan kali ini, Saya tidak membahas hal yang baru. Saya hanya melakukan bersih-bersih rumah. Pembahasan kita sampai saat ini sudah semakin kompleks dan sudah mencapai titik dimana kita perlu mengadakan perapihan sebelum membahas pembahasan yang lebih mendalam lagi.
Kode sumber yang sudah dirapikan bisa di unduh disini.
Apa saja yang berubah?
Perubahan pada file index.html
Saya merapikan css nya, dan menambahkan style baru pada elemen kanvas. Saya suka dengan style piksel dan senang bekerja pada resolusi rendah. Selama ini tampilannya cenderung nge-blur karena hal ini. Untuk itulah Saya menambahkan style pada canvas agar lebih ber-piksel
canvas {
position: absolute;
image-rendering: -moz-crisp-edges;
image-rendering: -webkit-crisp-edges;
image-rendering: pixelated;
image-rendering: crisp-edges;
}
Kemudian saya menyederhanakan struktur html dengan menghapus semua atribut pada elemen kanvas.
<canvas></canvas>
Semua atribut pada kanvas akan diatur dari pemrograman.
Penambahan file Data.js
Saya menambahkan file Data.js yang akan menampung semua variabel. Awalnya variabel dismpan jadi satu dengan file Game.js. Kita sekarang memisahkan antara data dengan logika dan alur dari program.
Pada file ini, Saya juga menambahkan variabel baru yaitu gp dan gl. Masing-masing berisi informasi mengenai resolusi game. Sekarang kita akan mengontrol resolusi dari sini.
Dan beberapa perubahan kecil lainnya yang tidak bisa dibahas satu persatu.
Sekarang struktur kita sudah siap, dan kita siap untuk membahas algorithma ini ke arah yang lebih kompleks lagi.
Terima kasih sudah mampir dan membaca.
.
Jumat, 11 September 2020
Algorithma Path Finding #7: A Star
In adalah pembahasan ke 7 dari seri Algorithma Path Finding. Pembahasan pertama bisa Anda baca pada tautan ini.
Pada pembahasan sebelumnya kita membahas tentang bagaimana membuat karakter berjalan lebih halus dalam penerapan algorithma path-finding.
Pada tulisan kali ini kita akan membahas tentang A * (A Star) Path finding. A * Pathfinding adalah penyempurnaan dari algorithma path finding sebelumnya yang biasa dikenal dengan istilah fast-path-finding.
A * Path finding akan menghasilkan jalur yang lebih optimal.
Perhatikan perbedaan keduanya dalam kedua gambar berikut.
Jalur yang dibuat dari algorithma sebelumnya hasilnya tidak optimal. Karakter menempuh jalur yang lebih panjang.
Demonya bisa dicoba online di tautan ini:
Kode sumber bisa di unduh di tautan ini:
Video Youtube:
Apa yang berubah?
Dalam pembahasan kali ini kita mengenalkan konsep G. G adalah 'jarak' dari posisi awal ke posisi sekarang. G dihitung dengan cara berbeda dengan jarak sebelumnya (H) yang dihitung dari posisi sekarang ke posisi tujuan.
G tidak dihutung secara kira-kira/heuristic seperti H. G adalah jarak sebenarnya. Kita mendapatkan G dengan cara menambahkan nilai G dari cell parent. Cell parent mendapatkan nilai G dari parent sebelumnya, hingga ke cell yang pertama. Dengan cara ini, maka nilai G tidak dikira-kira.
Sebenarnya istilah 'jarak' kurang cocok untuk G, namun untuk menyamakan dengan H, maka saya pakai istilah jarak. G sebenarnya lebih cocok disebut biaya perjalanan dari titik awal ke titik sekarang.
Pada pembahasan sebelumnya kita menghitung jarak dengan cara mengira-ira dari posisi sekarang keposisi target.
Jarak(F) = H ...1)
Dengan adanya G maka perhitungannya jadi:.
Jarak(F) = G + H ...2)
G biasanya tidak berdiri sendiri tapi diberi pemberat.
Jarak (F) = G * P + H ...3)
P adalah pemberat. Bila nilainya satu maka G * P = G, (persamaan 2).
P bernilai lebih dari atau sama dengan satu. Semakin besar P, maka G akan semakin berat, dan hal ini akan mempengaruhi penghitungan jarak. Semakin besar pengaruh G, maka jarak yang dihasilkan akan semakin optimal, namun waktu yang dibutuhkan untuk menyelesaikan algorithma juga semakin lama.
Perubahan kode sumber
Kita melakukan perubahan pada kode sumber untuk mengenalkan G.
Perubahan pertama ada pada fungsi cellBuat().
function cellBuat(parent, x, y, tx, ty) {
...
let cell = {
x: x,
y: y,
buka: 1,
jarak: -1,
induk: parent,
g: parent ? parent.g + 1 : 0
};
cell.jarak = Math.abs(tx - x) + Math.abs(ty - y);
cell.jarak += (cell.g * 1.1);
return cell;
}
Terima kasih sudah mampir dan membaca
Senin, 07 September 2020
Membuat kanvas bersifat responsif #2: Layar Penuh
Kode sumber bisa diunduh di tautan ini:
Demo bisa dilihat di tautan ini. Silahkan ubah-ubah ukuran browser untuk melihat hasilnya.
Contoh hasilnya adalah seperti gambar di bawah ini:
Tampilan landskape
Tampilan portrait
Dari kedua tampilan di atas terlihat bagaimana kanvas akan selalu terlihat memenuhi layar.
Penjelasan Kode:
Bisa dibilan 99% kode pada pembahasan sekarang sama persih dengan kode pada pembahasan sebelumnya. Yang membedakan hanyalah satu baris saja. Perhatikan fungsi resize berikut:
function resize() {
let cp = 360;
let cl = 218;
let wp = window.innerWidth;
let wl = window.innerHeight;
let ratio = Math.max((wp / cp), (wl / cl));
let cp2 = Math.floor(cp * ratio);
let cl2 = Math.floor(cl * ratio);
canvas.style.width = cp2 + 'px';
canvas.style.height = cl2 + 'px';
canvas.style.top = ((wl - cl2) / 2) + 'px';
canvas.style.left = ((wp - cp2) / 2) + 'px';
gambarCanvas(canvasCtx);
}
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.
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 berikutnya adalah fungsi krkPindahGrid()
//posisi grid target
//jarak dari grid sekarang ke target
//posisi karakter baru
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.
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
Kemudian kita hitung jarak perpindahan dari grid sekarang ke grid berikutnya.
Posisi karakter yang baru dihitung dari posisi awal + posisi perpindahan
Hasil dari posisi baru ini disimpan di karakter.
Berikutnya Kita akan membahas perubahan pada fungsi berikutnya, yaitu fungsi update():
Kemudian kita check apakah jalurn sudah mencapai maksimal, artinya karakter sudah sampai pada index terakhir. Bila ya, maka kita ubah status karakter menjadi idle.
Bila tidak, maka kita ubah statusnya jadi jalan lagi.
Untuk selanjutnya, maka kode sumbernya sama dengan sebelumnya,
Terima kasih telah mampir dan membaca.
Minggu, 23 Agustus 2020
Algorithma Path Finding #5: Membuat karakter berjalan mengikuti jalur yang dibuat oleh algorithma path-finding
In adalah pembahasan ke 5 dari seri Algorithma Path Finding. Pembahasan pertama bisa Anda baca pada tautan ini.
Dalam tulisan kali ini, Kita akan membahas bagaimana membuat karakter berjalan mengikuti jalur yang telah dibuat oleh algoritma path-finding tersebut, tentu saja pada kanvas yang responsif karena kita akan mencobanya bukan hanya di PC tapi juga di telepon gengam.
Demonya bisa dilihat disini:
Kode sumbernya bisa di unduh disini:
Videonya juga tersedia di youtube:
Penjelasan kode sumber:
Pembahasan sekarang lebih kompleks dari sebelumnya sehingga sekarang file javascript-nya Kita pisah menjadi beberapa bagian antara lain:
- Pathfinder.js: menangani algorithma path finding
- Game.js: file utama
- Peta.js: menangani peta
- Window.js: menangani segala yang berhubungan dengan window seperti saat window di- resize.
Dalam pembahasan kali ini kita akan memiliki sebuah karakter yang berjalan mengikuti jalur path finding. Untuk itu kita perlu menyusun struktur untuk karakter ini.
Struktur karakter ini adalah struktur minimal untuk karakter yang bisa berjalan.
jalur: berisi informasi jalur hasil path-finding. Jalur disimpan dalam bentuk Array.
jalurn: informasi index ke berapa dari jalur di atas.
pos: berisi informasi posisi x dan y
status: status karakter saat ini
Karakter memiliki status yang didefinisikan dalam konstanta sbb:
const st_idle = 1;
const st_jalan = 2;
window.onload()
Saat saat event window.onload() Kita membuat interval untuk proses perulangan. Dalam perulangan ini kita memanggil fungsi update() dan render(). Fungsi update() akan memperbaharui informasi karakter sedangkan fungsi render() akan melakukan proses penggambaran.
setInterval(() => {
update();
render();
}, 100);
canvas.onclick()
Pada saat kanvas diklik, kita melakukan pengecekan terdahulu apakah saat ini status karakter sedang berjalan atau tidak. Bila karakter sedang berjalan maka kita langsung mengakhiri fungsi ini. Kita harus menunggu karakter selesai berjalan sebelum memberi perintah baru.
if (karakter.status != st_idle)
return;
Bila ternyata karakter sedang diam, maka kita lanjutkan prosesnya. Kita mencari posisi klik di layar. Metodenya sama dengan tulisan sebelumnya.
let rect = canvas.getBoundingClientRect();
let poslx = (e.clientX - rect.x) * canvasScaleX;
let posly = ((e.clientY - rect.y) * canvasScaleY);
let posx = Math.floor(poslx / 32);
let posy = Math.floor(posly / 32);
Kemudian kita mencari jalur ke posisi tersebut dari posisi karakter yang terakhir.
let hasil = pfCariJalan(karakter.pos.x, karakter.pos.y, posx, posy);
karakter.status = st_jalan;
karakter.jalur = hasil;
karakter.jalurn = -1;
Kita mengubah status karakter yang awalnya diam ke berjalan. Kita juga memasukkan jalur hasil algoritma path-finding.
Saat karakter belum berjalan, isi dari variable jalurn adalah -1. Saat karakter berjalan, maka jalurn akan mulai berjalan dari angka 0 dst. Hal ini karena Array dimulai dari angka 0.
fungsi Update():
Fungsi update berisi proses untuk memperbaharui informasi karakter.
function update() {
if (karakter.status == st_idle) {}
else if (karakter.status == st_jalan) {
if (karakter.jalurn >= (karakter.jalur.length - 1)) {
karakter.status = st_idle;
}
else {
karakter.jalurn++;
karakter.pos.x = karakter.jalur[karakter.jalurn][0];
karakter.pos.y = karakter.jalur[karakter.jalurn][1];
}
}
}
Kita mengecek status dari karakter.
Bila statusnya st_idle, maka tidak ada yang dilakukan.
Bila statusnya st_jalan maka kita memperbaharui proses jalan.
Saat berjalan, kita mengecek apakah proses jalan sudah selesai. Hal ini ditandai dengan jalurn yang sudah melebihi panjang dari jalur path-finding.
Bila karakter sudah selesai berjalan, maka statusnya kita rubah ke st_idle.
if (karakter.jalurn >= (karakter.jalur.length - 1)) {
karakter.status = st_idle;
}
Bila proses jalan belum selesai, maka kita menambah isi dari jalurn. Kemudian kita mengubah posisi karakter sesuai dengan informasi dari jalur path finding.
karakter.jalurn++;
karakter.pos.x = karakter.jalur[karakter.jalurn][0];
karakter.pos.y = karakter.jalur[karakter.jalurn][1];
Fungsi Render():
Fungsi ini berisi proses pengambaran. Kita menggambar peta, jalan dan jalur sesuai informasi yang ada. Kita tidak membahas terlalu dalam mengenai fungsi ini karena isinya Saya rasa sudah cukup jelas dan sudah sering dibahas di tulisan-tulisan sebelumnya.
Terima kasih sudah mampir dan membaca. Bila ada pertanyaan, jangan sungkan untuk bertanya.
Rabu, 19 Agustus 2020
Algorithma Path Finding #4 Mencari posisi klik pada kanvas yang di skala
In adalah pembahasan ke 4 dari seri Algorithma Path Finding. Pembahasan pertama bisa Anda baca pada tautan ini.
Sekarang kita akan melanjutkan dengan menggabungkan keduanya. Kita akan mencari jalur pada posisi yang diklik pada kanvas yang bersifat responsif.
Hasil nya bisa Anda dicoba di sini.
Silahkan buka linknya, dan ubah ukuran browsernya kemudian klik pada kanvas. Anda bisa lihat bagaimana algorithma path-finding ini bekerja pada ukuran kanvas yang berbeda-beda.
Kode sumber bisa diunduh di sini
Atau Anda bisa mencoba mengedit kodenya secara langsung disini:
Mendeteksi posisi yang di klik pada kanvas yang bersifat responsif memiliki tantangan tersendiri. Hal ini karena kanvas tidak hanya memiliki ukuran yang berbeda-beda namun juga memiliki posisi yang berbeda-beda pula.
Kode sumber dari pembahasan kali diambil dari dua tulisan sebelumnya dengan sedikit perubahan. Disini saya akan membahas perubahannya saja. Sisanya sama saja dan bisa dilihat pada artikel sebelumnya, atau anda bisa mengunduh kode sumbernya.
canvas.onclick = (e) => {
let rect = canvas.getBoundingClientRect();
let poslx = (e.clientX - rect.x) * canvasScaleX;
let posly = ((e.clientY - rect.y) * canvasScaleY);
let posx = Math.floor(poslx / 32);
let posy = Math.floor(posly / 32);
bersihkanLayar();
hasil = pfCariJalan(1, 1, posx, posy);
gambarPeta();
gambarJalan(hasil);
};
Perubahan yang paling mendasar adalah pada saat canvas.onclick(). Pada tulisan sebelumnya kita mencari posisi klik di kanvas dengan menggunakan e.clientX dan e.clientY saja. Hal ini tidak berlaku untuk kanvas yang responsif.
Proses penghitungannya sbb:
Pertama kita mencari dulu posisi kanvas dilayar. Posisi kanvas sekarang selalu berada di tengah menyesuaikan dengan dimensi layar.
let rect = canvas.getBoundingClientRect();
let posly = (e.clientY - rect.y) * canvasScaleY;
let posy = Math.floor(posly / 32);
Pada tulisan berikutnya, Saya akan membahas bagaimana membuat karakter berjalan mengikuti jalur yang telah dibuat oleh algorithma path-finding.
Minggu, 09 Agustus 2020
Macam kanvas responsif
Secara umum ada empat macam pendekatan untuk responsif yang pernah Saya temui. Tiga pertama sering dipakai di applikasi umum sedangkan yang terakhir hanya saya temukan di aplikasi Animate. Saya tidak membahas yang terakhir karena penggunaannya kurang umum dan Saya kurang paham juga.
Yang pertama disebut letterbox, pan atau kotak. Memiliki ciri-ciri sebagai berikut:
Rasio kanvas tetap
Kanvas diskala hingga memenuhi layar, tapi tidak sampai membuat gambar melebihi layar.
Ada jeda kosong di pinggir samping atau atas, karena rasio kanvas dan layar kadang tidak sama.
Yang kedua disebut strecth atau melar.
Rasio kanvas tidak dijaga, membuat gambar tampak melar tidak merata.
Kanvas diskala hingga memenuhi layar.
Tidak ada jeda kosong.
Yang ketiga disebut background atau cover, atau layar-penuh
Rasio kanvas tetap
Kanvas diskala memenuhi layar hingga melebihi layar dan gambar terpotong.
Tidak ada jeda kosong.
Senin, 27 Juli 2020
Algorithma Path Finding #3: Mencari jalur pada posisi yang di klik di layar.
In adalah pembahasan ke 3 dari seri Algorithma Path Finding. Pembahasan pertama bisa Anda baca pada tautan ini.
Hasilnya bisa dilihat secara daring di sini.
Setiap kali kita klik di layar, maka algorithma path finding ini akan mencari jalur ke posisi tersebut.
Berikut adalah penjelasan tentang kodenya:
window.onload = () => {
canvas = document.body.querySelector('canvas');
canvasCtx = canvas.getContext("2d");
gbrBola = document.body.querySelector("img#img-bola");
gbrBox = document.body.querySelector("img#img-box");
gambarPeta();
canvas.onclick = (e) => {
let posx = Math.floor((e.clientX) / 32);
let posy = Math.floor((e.clientY) / 32);
bersihkanLayar();
let hasil = pfCariJalan(1, 1, posx, posy);
gambarPeta();
gambarJalan(hasil);
};
};
Kodenya tidak jauh berbeda dengan kode pada tulisan sebelumnya. Kita cuman menambahkan fungsi onclick() pada canvas yang akan mendeteksi event mouse diklik.
Posisi diklik di layar ditentukan oleh e.clientX dan e.clientY. Setiap kali layar diklik, maka algorithma path finding akan mencari jalur ke posisi tersebut, kemudian hasilnya digambar di layar.
Sisanya adalah sama dengan kode pada tulisan sebelumnya.
Pada tulisan ini, kita menggunakan kanvas yang statis yang ukurannya tidak berubah mengikuti ukuran browser. Pada tulisan berikutnya, Saya akan membahas bagaimana mengaplikasikan algorithma ini pada kanvas yang berubah-ubah. Namun sebelumnya Saya akan membahas dulu bagaimana membuat kanvas bersifat responsif.
Sabtu, 04 Juli 2020
Algorithma Path Finding #2: Penerapan kode algorithma path finding
"XXXXXXXXXX",
"X X",
"X X X",
"X X X",
"X X X",
"X X",
"XXXXXXXXXX"
];
let canvasCtx;
let gbrBox;
let gbrBola;
//persiapan canvas
canvas = document.body.querySelector('canvas') as HTMLCanvasElement;
canvasCtx = canvas.getContext("2d");
gbrBola = document.body.querySelector("img#img-bola") as HTMLImageElement;
gbrBox = document.body.querySelector("img#img-box") as HTMLImageElement;
let hasil: number[][] = pfCariJalan(2, 2, 8, 3);
gambarTembok();
gambarJalan(hasil);
console.log(JSON.stringify(hasil));
}
- Menyiapkan canvas,
- Mengambil referensi untuk gambar bola dan tembok.
- Mencari jalur dari posisi 2,2 ke posisi 8,3 hasilnya kita simpan di variable hasil.
- Memanggil fungsi untuk menggambar tembok dan menggambar jalan.
- Berikut adalah fungsi untuk menggambar tembok.
function gambarTembok() {
for (let jx = 0; jx < peta.length; jx++) {
for (let ix = 0; ix < peta[jx].length; ix++) {
if (petaKosong(ix, jx)) {
}
else {
canvasCtx.drawImage(gbrBox, ix * 32, jx * 32);
}
}
}
}
hasil.forEach((item) => {
canvasCtx.drawImage(gbrBola, item[0] * 32, item[1] * 32);
});
}
let cellCr;
let res = [];
cellAr = [];
//bila posisi tujuan sama dengan awal
//kembalikan array kosong
if ((sx == tx) && (sy == ty)) {
return [];
}
cellAr.push(cellBuat(null, sx, sy, tx, ty));
while (true) {
//bila jumlah cell yang dihasilkan melebihi maksimum
//kembalikan array kosong
if ((cellAr.length >= cellMax)) {
return [];
}
//cari cell yang masih terbuka (Langkah 2)
cellCr = cellCariYangTerbuka();
//bila ada cell yang masih terbuka
if (cellCr) {
//ubah status jadi tutup (Langkah 2)
cellCr.buka = -1;
//check jika sudah sampai tujuan (Langkah 12)
if (pfCheckSampaiTujuan(cellCr.x, cellCr.y, tx, ty)) {
res = pfTelusurBalik(cellCr);
return pfRes2Array(res);
}
//(Langkah 1)
pfBukaCellBaru(cellCr, tx, ty);
}
else {
//Tidak ada cell yang terbuka
//Jalur tidak ketemu
//Kembalikan array kosong
return [];
}
}
}
return [];
}
}
return [];
}
if ((x == tx) && (y == ty))
return true;
return false;
}
Fungsi cellbuat();
let cell = {
x: x,
y: y,
buka: 1,
jarak: -1,
induk: parent,
};
cell.jarak = Math.abs(tx - x) + Math.abs(ty - y);
return cell;
}
Fungsi cellCariYangTerbuka():
let i = 0;
let cell = null;
let maxLen;
let cellTemp;
let len = 0;
maxLen = 10000;
len = cellAr.length - 1;
for (i = len; i >= 0; i--) {
cell = cellAr[i];
if (1 == cell.buka) {
if (cell.jarak < maxLen) {
cellTemp = cell;
maxLen = cell.jarak;
}
}
}
return cellTemp;
}
Fungsi pfCheckSampaiTujuan():
if ((x == tx) && (y == ty))
return true;
return false;
}
let res = false;
cellAr.forEach(cell => {
if (cell.x == x && cell.y == y) {
res = true;
}
});
return res;
}
Fungsi pfPosBisa():
//check cell
if (cellCheckDouble(x, y)) {
return false;
}
//check block peta
if (!petaPosValid(x, y)) {
return false;
}
return true;
}
Fungsi pfRes2Array():
let ar = [];
res.forEach(cell => {
ar.push([cell.x, cell.y]);
});
return ar;
}
Fungsi pfTelusurBalik():
let res = [];
let i = 0;
let cellTemp = null;
let cellParent = null;
res.unshift(cell);
while (true) {
//cari parent dari cell yang sedang di check
cellParent = null;
for (i = 0; i < cellAr.length; i++) {
cellTemp = cellAr[i];
if (cell.induk == cellTemp) {
cellParent = cellTemp;
break;
}
}
//parent gak ada, berarti cell sekarang adalah cell awal, penelusuran selesai;
if (cellParent == null) {
return res;
}
else {
//hasilnya di masukkan ke let res
//update cell dengan cellParent
res.unshift(cellParent);
cell = cellParent;
}
}
}
Fungsi petaKosong():
return (peta[y].charAt(x) == " ");
}
or reload the browser
or reload the browser