Jadi sebelumnya aku sudah mulai bikin
AI sederhana (sekali) untuk musuh, walaupun hasil akhirnya adalah
musuh baru mengikuti pemain saja. Sebelum aku membuat AI dalam bentuk
code yang lebih kompleks, aku ingin merancangnya terlebih dulu. Oh
iya, walaupun contoh kasusnya untuk musuh, AI ini nantinya bukan cuma
untuk musuh saja, tapi juga party member lain dalam kelompok pemain.
Dan juga, AI untuk boss juga akan kusamakan dengan AI untuk musuh
biasa, hanya saja nilai parameternya kubuat lebih susah.
Baik musuh maupun anggota party member
ada yang berperan sebagai penyerang jarak dekat dan penyerang jarak
jauh, ada pula penyerang fisik dan penyerang sihir. Jadi dibagi
berdasarkan tipenya, musuh dan party member bisa dikategorikan
seperti ini:
- Penyerang fisik jarak dekat
- Penyerang fisik jarak jauh
- Penyerang sihir jarak jauh
- Penyembuh / support
Aku nggak menuliskan penyerang sihir
jarak dekat, karena aku menganggap semua penyerang sihir adalah
penyerang jarak jauh, lagipula kalau penyerang sihir menyerang dari
jarak dekat dia bisa diserang duluan sebelum sempat mengeluarkan
sihirnya. Masing-masing penyerang fisik akan punya radius serangan
yang jaraknya beda antara jarak dekat dan jarak jauh, penyerang fisik
akan mendekat sampai musuh masuk dalam radius serangan sebelum
akhirnya menyerang. Penyerang sihir nggak perlu mendekat buat
menyerang musuh, jarak jangkau sihirnya adalah seluruh battle screen,
jadi mereka bisa menyerang musuh tanpa peduli jarak. Bedanya adalah
sihir perlu casting time untuk bisa dirapalkan dan mereka bisa
diserang sewaktu ini.
Jadi bagaimana kita akan membuat AI?
Aku akan membedakan antara AI penyerang fisik dan penyerang sihir,
inilah kira-kira proses logika AI penyerang fisik:
- Kalau belum ada musuh dalam radius serangan, cari musuh
- Dekati musuh sampai masuk dalam radius serangan
- Serang
- Tentukan apakah akan bertahan atau tidak?
- Kalau musuh yang tadi diserang masih hidup, kembali ke poin 3
- Kalau musuh yang tadi diserang sudah mati, kembali ke poin 1
Ini masih sekedar gambaran kasar, masih
bisa dijabarkan lebih banyak lagi, misalnya poin 3. Apakah menyerang
itu dengan serangan biasa atau dengan skill? Kalau dengan skill,
skill yang mana yang dipakai? Dan juga, kalau aku membuatnya begini,
nantinya aku nggak bisa membuat sistem costumize AI untuk party
member yang lain (misalnya, utamakan menyerang musuh dengan HP
tertinggi, utamakan menyerang penyihir, dsb.). Jadi 6 poin ini akan
aku perjelas sambil jalan.
Semua petarung baik musuh maupun party
member punya instance variable bernama radius, kalau nggak ada musuh
dalam radius ini, petarung akan menentukan akan mendekati musuh yang
mana. Untuk melakukan ini, di awal pertarungan semua petarung harus
sudah tau tentang siapa saja musuh-musuh yang hadir di battle screen
(party member tau tentang musuh, musuh tau tentang party member). Ada
dua cara untuk melakukan ini, dengan menambahkan instance variable
baru yang mengandung data tentang nama musuh, atau dengan family baru
yang bisa dibaca semua petarung. Karena masing-masing kubu
mendapatkan data yang sama tentang musuh mereka kapanpun juga sewaktu
pertarungan berlangsung, aku akan membuat dua family yang berisi data
siapa saja party member dan siapa saja musuh yang masih hidup dalam
battle. Buatku, ini lebih efisien daripada meng-update instance
variable semua petarung dalam battle.
Ada beberapa logika yang bisa kita
pakai untuk mencari musuh mana yang akan jadi target serangan
petarung:
- Jaraknya terdekat dengan petarung
- Jaraknya terjauh dengan petarung
- Current HP-nya terbanyak
- Current HP-nya paling sedikit
- Utamakan menyerang penyihir
Karena setiap petarung akan menyimpan
logika pemilihan musuh mana yang akan mereka pakai, maka perlu satu
lagi instance variable logika pemilihan musuh, untuk sementara aku
namakan instance variable ini enemySelection.
Logika-logika pemilihan ini juga akan aku beri nama dengan tipe
string.
- Jaraknya terdekat = "closest"
- Jaraknya terjauh = "farthest"
- HP terbanyak = "strongest"
- HP paling sedikit = "weakest"
- Utamakan penyihir = "mages"
dengan begini akan mudah nantinya
sewaktu kita menulis dalam code.
Kemudian setelah menentukan bagaimana
petarung memilih musuh, petarung akan mendekati musuh. Tentunya
petarung harus tau musuh mana yang harus didekati dan nggak mengganti
targetnya sampai targetnya mati. Jadi nanti ada lagi instance
variable baru bernama targetName yang
berisi nama target yang akan diserang. Tapi di sini ada satu masalah:
bagaimana kalau ada lebih dari satu musuh yang punya nama sama,
misalnya ada tiga yellow wolf dalam satu battle screen, yang mana
yang akan dijadikan target? Penyelesaiannya adalah dengan memberi
instance variable baru di family yang menyimpan musuh yang bertarung,
kalau kita beri battleName dan membuat
battleName ini berisi seperti "yellowWolf1", "yellowWolf2"
dan seterusnya, petarung bisa menyerang target yang tepat.
Langkah berikutnya adalah menyerang.
Menyerang bisa dengan serangan biasa atau dengan skill. Dan akan ada
jeda di antara tiap serangan (tapi kita sudah coding soal jeda
serangan ini sebelumnya). Tiap petarung punya persentase serangan
sendiri antara serangan biasa dan skill, ada yang cuma menyerang
biasa saja, ada yang lebih banyak menyerang skill. Sama seperti
logika pemilihan musuh, aku juga akan menamai dan menyimpan logika
menyerang ini dalam instance variable bernama attackMethod.
Sekarang mari kita list apa saja logika penyerangannya.
- Hanya serangan biasa saja = "normals"
- Gunakan skill, tapi sedikit saja = "few"
- Gunakan cukup banyak skill (50:50) = "balanced"
- Lebih sering menggunakan skill daripada serangan biasa = "frontal"
masing-masing logika serangan punya
persentase serangan biasa:serangan skill masing-masing, nantinya
penentuan apakah petarung akan menyerang dengan skill atau tidak
dilihat berdasarkan persentase itu. Tentu saja petarung cuma
menyerang dengan skill kalau SP mereka mencukupi, kalau nggak mereka
akan menyerang dengan serangan biasa.
Pertanyaan berikutnya adalah: kalau
petarung memutuskan untuk menyerang dengan skill, skill apakah yang
dipakai? Sebenarnya susah juga menentukan skill apa yang akan dipakai
dan tidak dipakai, karena nantinya masing-masing petarung akan punya
banyak skill, dan buatku susah untuk membuat AI yang memilih hanya
satu dari sekian banyak itu (kecuali memang sudah ditentukan dari
code bahwa petarung harus memilih skill itu). Jadi tiap kali petarung
akan memilih skill, dia akan memilih secara acak skill apa yang akan
dia pakai dari list skill aktif yang mereka miliki (skill bisa
diaktifkan dan nonaktif, nanti akan aku desain lebih jelas).
Langkah terakhir adalah menentukan
apakah petarung akan bertahan atau tidak. Sebenarnya petarung nggak
harus masuk tahap bertahan sesudah menyerang (supaya bisa diserang
oleh pemain lebih mudah), tapi aku tambahkan kemampuan bertahan untuk
membuat pertarungan lebih seru dan menantang. Sama seperti logika
menyerang, aku akan membuat persentase apakah petarung akan bertahan
atau nggak lalu menyimpannya dalam instance variable, kali ini
bernama defenseMethod. Logika-logika
pertahanannya adalah seperti di bawah ini.
- Nggak bertahan sama sekali = "defenseless"
- Mungkin saja bertahan = "defensive"
- Lebih sering bertahan (kemungkinan 50:50) = "defender"
- Hampir selalu bertahan = "guardian"
kalau petarung memutuskan untuk
bertahan, dia akan memasuki mode bertahan selama 2 detik sebelum
melanjutkan ke poin 5 dari alur AI yang kita buat di awal tadi.
Sebenarnya aku juga ingin menulis soal
AI para penyihir, tapi karena sepertinya blog post kali ini sudah
terlalu panjang, mungkin aku akan menulisnya di blog post berikutnya.
Sampai ketemu.
Tidak ada komentar:
Posting Komentar