• Tidak ada hasil yang ditemukan

LANDASAN TEOR

2.4 Teori Finite State Machine

(Bevilacqua, 2013) Finite State Machine (FSM) adalah model yang digunakan untuk menggambarkan dan mengatur aliran eksekusi yang biasanya digunakan untuk program komputer dan urutan logika sirkuit. Hal ini cocok diterapkan terhadap AI pada game, memproduksi hasil yang bagus tanpa kode yang kompleks. (Warden, 2012) Untuk pemrograman AI, penulis memiliki pilihan deterministic atau non-deterministic. Kebanyakan video game memiliki deterministic. Berarti anda tahu bagaimana musuh akan bereaksi berdasarkan masukan yang berbeda. Jika mereka akan menyerang. Jika anda bersembunyi dan menunggu, mereka akan menyerang anda. FSM pendeknya adalah model komputasi yang berbasis pada mesin hipotesis yang terbuat dari satu atau banyak state. FSM biasanya digunakan untuk mengatur dan menggambarkan aliran eksekusi yang berguna diterapkan pada game. “Otak” dari musuh, misalnya bisa diimplementasikan menggunakan FSM setiap state merupakan suatu tindakan, seperti attack atau evade. FSM dapat digambarkan dengan grafik, dimana node adalah state dan ujung-ujungnya adalah transisi. Setiap sisi memiliki label yang menginformasikan ketika transisi terjadi, seperti player is near pada gambar 2.5, yang menunjukkan bahwa mesin akan beralih dari wander ke attack jika player is near.

17

2.4.1 Perencanaan State dan Transisi

(Bevilacqua, 2013) Penerapan FSM dimulai dengan states dan transisi yang dibutuhkan. Bayangkan FSM pada Gambar 2.6, menggambarkan otak dari semut yang membawa daun ke rumah. Titik awal adalah state find leaf, yang mana akan aktif sampai semut menemukan daunnya. Ketika itu terjadi, kondisi state di transisikan ke go home, yang mana akan aktif sampai semut sampai di sarang. Ketika semut sampai sarang, state yang aktif menjadi find leaf lagi, jadi semut mengulangi perjalanannya. Jika state yang aktif adalah find leaf dan kursor mouse mendekati semut, transisinya menjadi state run away. Ketika state aktif, semut akan lari dari kursor mouse. Ketika kursor tidak lagi menjadi ancaman, transisi state kembali ke find leaf. Karena ada transisi yang menghubungkan antara find leaf dan run away, semut akan selalu melarikan diri dari kursor mouse ketika itu mendekati semut selama semut mencari daun. Itu tidak akan terjadi jika state yang aktif adalah go home (cek gambar 2.7). Dalam kasus ini semut akan pulang kerumah tanpa rasa takut, hanya transisi ke find leaf ketika semut sampai rumah.

2.4.2 Menerapkan Finite State Machine

(Bevilacqua, 2013) FSM dapat diimplementasikan dan dikemas dalam satu kelas, bernama FSM misalnya. Idenya adalah untuk menjalankan setiap state sebagai fungsi atau metode, menggunakan properti yang disebut activeState didalam kelas untuk menentukan state mana yang aktif. Karena setiap state adalah fungsi, selama fungsi state tertentu aktif mempresentasikan keadaan state tersebut akan dipanggil setiap membaharui game. Metode Update () pada FSM harus dipanggil setiap game frame, sehingga dapat memanggil fungsi yang ditunjukkan oleh properti activeState. Panggilan yang akan memperbaharui tindakan dari state yang sedang aktif. Metode setState () akan mentransisikan FSM ke state yang baru dengan mengarahkan properti activeState untuk fungsi state baru. Fungsi state tidak harus menjadi anggota FSM, bisa saja menjadi kelas lain, yang mana membuat kelas FSM lebih umum dan dapat digunakan kembali.

Gambar 2.6 Menggambarkan Otak dari semut (Bevilacqua, 2013)

Gambar 2.7 FSM menggambarkan otak dari semut. Perhatikan kurangnya transisi antara run away dan go home (Bevilacqua, 2013)

19

public class FSM {

private var activeState : Function; // menunjukkan fungsi state yang aktif

public function FSM () {}

public function setState(state :Function) :void { activeState = state ; }

public function update () :void { if ( activeState != null )

{ activeState(); } }

}

Menggunakan kelas FSM yang telah dijelaskan sebelumnya, saatnya untuk menerapkan “brain” karakternya. Pada penjelasan sebelumnya semut digunakan dan dikendalikan dengan FSM. Pada Gambar 2.8 adalah gambaran dari state dan transisi, fokus pada kodenya. Semut direpresentasikan dengan class Ant, yang memiliki properti bernama otak dan metode untuk tiap state. Properti brain adalah turunan dari kelas FSM :

Gambar 2.8 FSM dari otak semut dengan berfokus pada kode (Bevilacqua, 2013) public class Ant

{

public var position :Vector3D; public var velocity :Vector3D; public var brain :FSM ;

public function Ant (posX : Number, posY :Number) { position = new Vector3D (posX, posY); velocity = new Vector3D (-1,-1);

brain = new FSM () ;

//beritahu brain untuk memulai mencari daun (leaf).

brain.setState (findLeaf); }

/** state findLeaf membuat semut menuju daun. */

21

}

/** state goHome membuat semut menuju rumah. */

public function goHome () :void { }

public function update() :void {

// memperbaharui FSM yang mengendalikan “brain”. Ini akan memanggil fungsi state yang sedang aktif : findLeaf (), goHome(), atau runaway().

brain.update();

//menerapkan vektor kecepatan untuk posisi, membuat semut berjalan.

moveBasedOnVelocity (); } (….) }

Kelas Ant juga memiliki kecepatan dan properti posisi, keduanya digunakan untuk menghitung pergerakan dengan menggunakan integrasi Euler. Metode update ini dipanggil di setiap kerangka game, sehingga akan memperbaharui FSM. Dibawah ini penerapan tiap state, dimulai dengan findLeaf (), state bertanggung jawab untuk memandu semut ke posisi daun :

public function findLeaf() :void {

// menggerakkan semut ke daun

velocity = new Vector3D(Game.instance.leaf.x - position.x, Game.instance.leaf.y - position.y);

if (distance(Game.instance.leaf, this) <= 10) {

// semut sangat dekat dengan daun.inilah waktunya. // pulang.

brain.setState(goHome); }

if (distance(Game.mouse, this) <= MOUSE_THREAT_RADIUS) { // kursos mouse mengancam kita. Ayo lari !

// ini akan membuat brain mulai memanggil runAway() // sekarang.

brain.setState(runAway); }

}

State goHome () digunakan untuk membuat semut pulang kerumah :

public function goHome() :void {

// menggerakan semut menuju rumah.

velocity = new Vector3D(Game.instance.home.x - position.x, Game.instance.home.y - position.y);

if (distance(Game.instance.home, this) <= 10) { // semut sampai dirumah. Cari daun lagi.

23

Akhirnya, state runAway () digunakan untuk membuat semut melarikan diri dari kursor mouse :

public function runAway() :void {

// menggerakkan semut untuk menjauh dari kursor mouse

velocity = new Vector3D(position.x - Game.mouse.x, position.y - Game.mouse.y);

// apakah kursor mouse masih dekat sini?

if (distance(Game.mouse, this) > MOUSE_THREAT_RADIUS) {

// tidak, kursor mouse telah pergi. Ayo cari daun lagi.

brain.setState(findLeaf); }

}

Hasilnya, semut akan dikendalikan oleh “brain” dari Finite State Machine. Bayangkan jika semut juga ingin lari dari kursor mouse ketika akan pulang. FSM dapat diperbaharui seperti pada gambar 2.9. Tampaknya adalah modifikasi yang sepele, penambahan transisi baru, tetapi ini menimbulkan masalah. Jika state run away dan kursor mouse tidak lagi mendekat, state apa yang seharusnya semut transisikan ke go home atau find leaf. Solusi dari masalah itu adalah dengan menggunakan Stack-based FSM. Tidak seperti FSM yang ada, Stack-based FSM menggunakan tumpukan untuk mengontrol state-state. Bagian atas tumpukan berisi state yang aktif, transisi ditangani dengan mendorong atau state muncul ke atas dari tumpukan. State bisa muncul ke atas dengan sendirinya dari tumpukan itu dan mendorong state yang lain, yang berarti transisi penuh (seperti FSM yang sederhana). State bisa muncul ke atas dengan sendirinya dari tumpukan yang berarti state saat ini telah selesai dan state selanjutnya di dalam tumpukan akan segera aktif. Pada akhirnya, itu akan mendorong state yang baru, yang artinya state aktif akan berubah untuk sementara waktu, tapi ketika state itu muncul lagi dari tumpukan, maka state aktif yang sebelumnya akan mengambil alih lagi.

Gambar 2.9 FSM semut diperbaharui dengan transisi baru (Bevilacqua, 2013) Stack-based FSM dapat diimplementasikan dengan menggunakan pendekatan yang sama seperti sebelumnya, tapi kali ini menggunakan sebuah array dari fungsi pointer untuk mengontrol tumpukan. Properti activeState tidak lagi diperlukan, karena tumpukan yang paling atas telah menjadi state aktif.

public class StackFSM { private var stack :Array;

public function StackFSM() { this.stack = new Array(); }

public function update() :void {

var currentStateFunction :Function = getCurrentState(); if (currentStateFunction != null) {

currentStateFunction(); }

25

public function popState() :Function { return stack.pop();

}

public function pushState(state :Function) :void { if (getCurrentState() != state) {

stack.push(state); }

}

public function getCurrentState() :Function {

return stack.length > 0 ? stack[stack.length - 1] : null; }

}

Metode setState () telah diganti dengan dua metode baru : pushState () dan popState (). pushState () menambahkan dua state baru ke atas tumpukan, sementara popState () menghapus state yang di atas tumpukan. Kedua metode ini secara otomatis mentransisikan mesinnya ke state yang baru, karena state yang di atas tumpukan telah berganti.Ketika menggunakan Stack-based FSM, yang menjadi catatan penting adalah bahwa setiap state bertanggung jawab muncul dari tumpukan. Biasanya state menghapus dirinya sendiri dari tumpukan ketika sudah tidak diperlukan lagi, seperti jika attack () aktif tapi targetnya baru saja mati. Menggunakan contoh semut, hanya beberapa perubahan yang diperlukan untuk menyesuaikan kode untuk digunakan pada Stack-based fsm. Masalah tidak tahu kemana state akan transisi sekarang sudah dapat diselesaikan berkat sifat dari Stack-based FSM. Hasilnya adalah seekor semut dapat melarikan diri dari kursor mouse, transisi kembali ke keadaan state aktif sebelum ancaman.

public class Ant { (...)

public var brain :StackFSM;

public function Ant(posX :Number, posY :Number) { (...)

brain = new StackFSM();

// beritahukan brain untuk mencari daun. brain.pushState(findLeaf); (...) } /** * state "findLeaf".

* membuat semut mendekati daun. */

public function findLeaf() :void { //gerakkan semut mendekati daun.

velocity = new Vector3D(Game.instance.leaf.x - position.x, Game.instance.leaf.y - position.y);

if (distance(Game.instance.leaf, this) <= 10) {

// semut sudah sangat dekat dengan daun.ini waktunya! // pulang.

brain.popState(); // memindahkan "findLeaf" dari tumpukan.

brain.pushState(goHome); // mendorong state "goHome" , membuatnya menjadi state aktif.

27

if (distance(Game.mouse, this) <= MOUSE_THREAT_RADIUS) { // kursor mouse mengancam kita. Ayo lari!

// state "runAway" didorong keatas "findLeaf", yang artinya

// state "findLeaf" akan aktif kembali ketika state"runAway" berakhir.

brain.pushState(runAway); } } /** * state "goHome".

*membuat semua menuju ke rumah. */

public function goHome() :void {

// gerakkan semut menuju rumah

velocity = new Vector3D(Game.instance.home.x - position.x,

Game.instance.home.y - position.y);

if (distance(Game.instance.home, this) <= 10) {

// semut sampai dirumah. Cari daun lagi.

brain.popState(); // pindahkan state “goHome” dari tumpukan.

brain.pushState(findLeaf); // dorong state "findLeaf", buat menjadi state aktif }

if (distance(Game.mouse, this) <= MOUSE_THREAT_RADIUS) { // kursor mouse mengancam kita. Ayo lari!

// state "runAway" terdorong diatas "goHome", yang artinya

// state"goHome" yang akan aktif lagi ketika state "runAway" berakhir.

brain.pushState(runAway); }

} /**

* state "runAway".

* membuat semut lari dari kursor mouse */

public function runAway() :void {

// gerakkan semut menjauhi kursor mouse

velocity = new Vector3D(position.x - Game.mouse.x, position.y -

Game.mouse.y);

// apakah kursor mouse masih disini?

if (distance(Game.mouse, this) > MOUSE_THREAT_RADIUS) { // tidak kursor mouse telah pergi. Ayo kembali ke sebelumnya. // state aktif. brain.popState(); } } (...) } 2.5 Pengertian NPC

Sebuah NPC dikenal sebagai karakter yang bukan orang atau karakter yang bukan dimainkan, dalam game adalah setiap karakter yang tidak dimainkan oleh player atau pemain. Dalam video game, ini biasanya berarti karakter yang dikendalikan oleh komputer melalui kecerdasan buatan. Jika player character (PC) dalam cerita protagonist, npc dapat dianggap sebagai “pemain pendukung” atau “ekstra” dari narasi Role playing.

29

Karakter npc mengisi dunia fiksi dari game dan dapat mengisi peran apapun yang tidak di tempati oleh player character. Karakter npc mungkin sekutu, para pengamat atau pesaing untuk player character. Npc juga bisa pedagang yang berdagang mata uang untuk hal-hal seperti peralatan atau perlengkapan Npc sehingga bervariasi dalam tingkat detail (Ellison, 2008).

Dokumen terkait