Membuat game penebang pohon dengan phaser part4

Halo,

Lanjut lagi untuk menyelesaikan game penebang pohon, untuk kali ini kita akan membuat ranting secara acak baik kanan atau kiri, dan memeriksa apakah karakter bertumbukan dengan ranting pohon. Kalian bisa download part yang sebelumnya di link ini

catatan

ini adalah tutorial dengan text untuk tutorial pembuatan game lumberjack / penebang pohon dengan menggunakan phaser framework. Jika mau liat videonya kalian bisa ke link youtube ini

Oh iya sebagai informasi, antara versi tulisan dan video mungkin tidak serupa, tapi memiliki tujuan sama, dan hasil akhir yang sama.

koding

Periksa code yang membuat batang pohon ranting untuk pertama kalinya. Dikode itu kita hanya akan menampilkan 1 posisi ranting atau tidak sama sekali.

Menampilkan jeda ranting

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for (var i = 1; i < 10; i++) {
var batangPohon = this.tambahkanBatangPohon();

//tambahkan code ini
if(i%2 === 0 || i === 1){
var rantingKanan = batangPohon.getAt(1);
rantingKanan.visible = false;
var rantingKiri = batangPohon.getAt(2);
rantingKiri.visible = false;
} else{
var random = Phaser.Math.Between(1, 2);
var ranting = batangPohon.getAt(random);
ranting.visible = false;
}

batangPohon.setPosition(240, config.height - 70 * i);
arrayBatangPohon.push(batangPohon);
}

Di line 5 hingga line 14 diatas, saya mengecek apakah i adalah bilang genap, atau i adalah 1, maka kita akan menghilangkan seluruh ranting. Jika tidak maka akan di random menggunakan Phaser.Math.Between(1, 2) untuk memilih ranting yang akan di hilangkan.

Setelah itu kita akan ubah fungsi mengisiBatangPohon dengan memberikan variable saat batang pohon diisi.

Menampilkan jeda ranting saat batang pohon diperbaharui

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
*
* @param {number} posisiRanting 0 tidak ada ranting,1 kanan, 2 kiri, default adalah 2
* @returns Phaser Container batang pohon
*/
this.mengisiBatangPohon = function (posisiRanting) {
if (posisiRanting === undefined) posisiRanting = 2;
var batangPohonBaru = null;
if (poolArrayBatangPohonTidakTerpakai.length > 0) {
batangPohonBaru = poolArrayBatangPohonTidakTerpakai[0];
poolArrayBatangPohonTidakTerpakai.shift();
//kode dibawah ini code baru
batangPohonBaru.iterate(function(child){
child.visible = true;
});
} else {
batangPohonBaru = this.tambahkanBatangPohon();
}

//tambahkancode ini
if (posisiRanting == 0) {
var rantingKanan = batangPohonBaru.getAt(1);
rantingKanan.visible = false;
var rantingKiri = batangPohonBaru.getAt(2);
rantingKiri.visible = false;
} else if (posisiRanting == 2) {
var rantingKiri = batangPohonBaru.getAt(2);
rantingKiri.visible = false;
} else if (posisiRanting == 1) {
var rantingKanan = batangPohonBaru.getAt(1);
rantingKanan.visible = false;
}

return batangPohonBaru;
}

Di line 6 saya menambahkan posisiRanting dan dilanjutkan di line7 dengan memberikan default atau standartnya adalah 2. Lalu pada line 13 panggil fungsi iterate yang akan mengubah keseluran child object pada container untuk ditampilkan seluruhnya baik kanan ataupun kiri, atau saya lebih menyebutnya sebagai reset dari batang pohon tersebut.

Dilajutkan pada line 21 kebawah, kita cek posisiRanting mana yang akan di hapuskan. Jika 0 hapus kanan dan kiri, 1 untuk hapus kanan, dan 2 untuk hapus kiri.

Setelah itu jangan lupa juga untuk panggil kembali Phaser.Math.Between(1, 2) di dalam fungsi turunkanBatangPohon().

1
2
3
4
5
6
7
8
9
this.turunkanBatangPohon = function () {
for (var i = 0; i < arrayBatangPohon.length; i++) {
batangPohon = arrayBatangPohon[i];
batangPohon.y = config.height - 70 * (i + 1);
}
//kode barunya
var pilihRanting = Phaser.Math.Between(1, 2);
var batangPohonBaru = this.mengisiBatangPohon(pilihRanting);
}

Nanti tampilan gamenya akan menjadi seperiti ini.

tampilan tiang pohon dan ranting, yang random setelah di isi ulang

Nah untuk yang sekarang ada kekurangan neh, saat menampilkan looping batang pohon, jeda yang sebelumnya ada di buat, tidak terpangil lagi, hanya random saja, sedangkan game ini designya harus ada jeda setiap ranting di panggil.

Oleh sebab itu kita akan membuat gameobject container berisi data dengan menggunakan Data Manager dalam phaser.

Menambahkan Phaser Data Manager

Sekarang kita tambahkan saat phaserContainer dibuat panggil fungsi setDataEnabled()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
this.tambahkanBatangPohon = function () {
var container = this.add.container(0, 0);
//code dibawah ini yang ditambahkan
container.setDataEnabled();

var batangPohon = this.add.image(0, 0, "log");
var rantingKanan = this.add.image(45, 0, "ranting");
var rantingKiri = this.add.image(-45, 0, "ranting");
rantingKiri.setFlip(true);

container.add(batangPohon);
container.add(rantingKanan);
container.add(rantingKiri);

return container;
};

Setelah itu kita set data ranting untuk memudahkan kita melakukan pengecheckan saat looping batang pohon di ulang kembali.

Ubah code pada fungsi this.mengisiBatangPohon menjadi seperit ini

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (posisiRanting == 0) {
var rantingKanan = batangPohonBaru.getAt(1);
rantingKanan.visible = false;
var rantingKiri = batangPohonBaru.getAt(2);
rantingKiri.visible = false;
batangPohonBaru.data.set("ranting", 0);//tambahkan ini
} else if (posisiRanting == 2) {
var rantingKiri = batangPohonBaru.getAt(2);
rantingKiri.visible = false;
batangPohonBaru.data.set("ranting", 2);//tambahkan ini
} else if (posisiRanting == 1) {
var rantingKanan = batangPohonBaru.getAt(1);
rantingKanan.visible = false;
batangPohonBaru.data.set("ranting", 1);//tambahkan ini
}

juga code saat batang pohon di buat.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for (var i = 1; i < 10; i++) {
var batangPohon = this.tambahkanBatangPohon();
if (i % 2 == 0 || i == 1) {
var rantingKanan = batangPohon.getAt(1);
rantingKanan.visible = false;
var rantingKiri = batangPohon.getAt(2);
rantingKiri.visible = false;
batangPohon.data.set("ranting", 0);//tambahkan ini
} else {
var random = Phaser.Math.Between(1, 2);
var ranting = batangPohon.getAt(random);
ranting.visible = false;
batangPohon.data.set("ranting", random);//tambahkan ini
}

batangPohon.setPosition(240, config.height - 70 * i);
arrayBatangPohon.push(batangPohon);
}

Jika sudah baru kita check apakah posisi paling atas batangPohon ada rantingnya? Jika ada maka kita akan menghilangkanya, dengan code dibawah ini.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
this.turunkanBatangPohon = function () {
for (var i = 0; i < arrayBatangPohon.length; i++) {
batangPohon = arrayBatangPohon[i];
batangPohon.y = config.height - 70 * (i + 1);
}

var pilihRanting = Phaser.Math.Between(1, 2);
var batangPohonTeratas = arrayBatangPohon[arrayBatangPohon.length - 1];
//cek ranting terlebih dahulu
var dataRanting = batangPohonTeratas.data.get("ranting");
if (dataRanting > 0) {//karena 1 dan 2 adalah batang pohon terisi
pilihRanting = 0;
}
var batangPohonBaru = this.mengisiBatangPohon(pilihRanting);

batangPohonBaru.y = batangPohonTeratas.y - 70;
batangPohonBaru.x = batangPohonTeratas.x;

//batangPohonBaru.setPosition(batangPohonTeratas.x, batangPohonTeratas.y-70);

batangPohonBaru.angle = 0;
arrayBatangPohon.push(batangPohonBaru);
};

Baru check kembali ke web-browser apakah gamenya sudah sesuai apa belum, tampilan seharusnya akan seperti gambar dibawah

tampilan tiang pohon dan ranting, yang random setelah di isi ulang yang benar

Membuat tumbukan dan permainan berakhir

Selanjutnya hanya tinggal menambahkan cek tumbukan dimana untuk memastikan apakah karakter bersentuhan dengan ranting atau tidak. Untuk kali ini saya hanya menggunakan data ranting yang sebelumnya sudah di buat untuk pengecekan-nya.

1
2
3
4
5
6
7
8
9
10
11
12
this.cekTumbukan = function (posisiPlayer) {
var batangPohon = arrayBatangPohon[0];
var posisiBatangPohon = batangPohon.data.get("ranting");
if (posisiPlayer == posisiBatangPohon) {
this.permainanBerakhir();
}
};

this.permainanBerakhir = function () {
console.log("permainan berakhir");
this.input.keyboard.enabled = false;
};

Lanjut, kita taruh fungsi cekTumbukan saat input keyboard kita tekan. Tapi sebelumnya kita buat const untuk memudahkan pengingat posisi player tepat dibawah kode array

1
2
3
var poolArrayBatangPohonTidakTerpakai = [];
const POSISI_PLAYER_KIRI = 1;
const POSISI_PLAYER_KANAN = 2;

setelah itu baru letakan cek posisitumbukan saat input keyboard

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
this.input.keyboard.on("keydown-RIGHT", () => {
char.x = 280;
char.flipX = true;
this.cekTumbukan(POSISI_PLAYER_KANAN);//tambahkan code ini
//tumbangkan pohon ke kiri
var batangpohon = arrayBatangPohon[0];
this.animasiBatangPohon(batangpohon, "kiri");
arrayBatangPohon.shift();
this.turunkanBatangPohon();
//check posisi batang pohon terbawah dan posisi player
this.cekTumbukan(POSISI_PLAYER_KANAN);//tambahkan code ini
});

this.input.keyboard.on("keydown-LEFT", () => {
char.x = 200;
char.flipX = false;
this.cekTumbukan(POSISI_PLAYER_KIRI);//tambahkan code ini
//tumbangkan pohon ke kiri
var batangpohon = arrayBatangPohon[0];
this.animasiBatangPohon(batangpohon, "kanan");
arrayBatangPohon.shift();
this.turunkanBatangPohon();
//check posisi batang pohon terbawah dan posisi player
this.cekTumbukan(POSISI_PLAYER_KIRI);//tambahkan code ini
});

Disini saya panggil 2x karena akan mengecheck posisi sebelum pohon di jatuhkan dan setelah pohon di jatuhkan.

Penutup

Untuk kali ini kita sudah mempelajari :

  1. Phaser.Math.Between(min, max) dimana akan mengembalikan antara kedua nilai yang sudah diatur
  2. Menambahkan data menggunakan digameobject dengan setDataEnable() atau Phaser.Data.DataManager
  3. Menggunakan fungsi iterate pada container yang kita gunakan untuk reset tampilan batang pohon.

Dan untuk keseluruhan codenya sekarnag bisa kalian check link github berikut.

Fiuh.. Tutorial yang cukup panjang dan semoga kalian masih bisa mengikuti tutorial ini yah, jika masih bingung bisa cek ulang lewat video atau cek tulisan ini kembali ataupun bertanya pada kolom komentar dibawah 😁