Saya sedang berusaha meningkatkan pathfinding untuk musuh-musuh gim saya. Saat ini, mereka pada dasarnya hanya terus bergerak menuju posisi tepat pemain dengan menghitung sudut antara mereka dan para pemain dan bergerak ke arah itu. Saya juga memiliki algoritma berkelompok yang mencegah musuh menumpuk di atas satu sama lain, sehingga mereka akan membentuk ke dalam kelompok daripada klip melalui satu sama lain.
Namun, sekarang saya telah menambahkan peta berbasis ubin, saya membutuhkan musuh untuk juga dapat berjalan di sekitar rintangan dan dinding misalnya. Saya awalnya mencoba menambahkan nilai pemisahan ke ubin "non-walkable" sehingga algoritma berkelompok akan mempertimbangkan dinding dan rintangan sebagai objek untuk menjauh. Saya belum mencari tahu apakah ini layak atau tidak karena tes awal saya menunjukkan musuh memukul "dinding" yang tidak terlihat di mana tidak ada ubin yang tidak dapat dilewati, namun untuk beberapa alasan, mereka menabraknya dan mulai memuntahkannya.
Saya bertanya-tanya apakah itu mungkin terlalu berat untuk menghitung jalan ke pemain menggunakan A * dan kemudian menggunakan algoritma berkelompok untuk mencegah penggumpalan. Awalnya gim saya akan menjadi penembak berbasis gelombang, tetapi saya memutuskan untuk menjadikannya berbasis level di jalur Hotline Miami, jadi kemungkinan saya akan memiliki lebih sedikit musuh, dengan gerombolan sesekali, dan hanya membuat mereka lebih kuat.
Apakah ini solusi yang layak? Saya menggunakan Java dengan Slick2D sebagai mesin game saya. Atau adakah solusi / algoritma yang lebih baik yang menangani kedua masalah ini?
sumber
Jawaban:
Ini terdengar seperti kasus penggunaan untuk Field Fields.
Dalam teknik ini, Anda melakukan kueri penelusuran jalan keluar tunggal dari objek pemain Anda, menandai setiap sel yang Anda temui dengan sel tempat Anda menjangkaunya.
Jika semua ubin Anda / tepi memiliki biaya traversal yang sama, maka Anda dapat menggunakan pencarian sederhana pertama untuk ini. Jika tidak, algoritma Dijkstra (seperti A * tanpa tujuan / heuristik) berfungsi.
Ini menciptakan bidang aliran: tabel pencarian yang mengaitkan setiap sel dengan langkah berikutnya menuju objek pemain terdekat dari posisi itu.
Sekarang musuh Anda masing-masing dapat mencari posisi mereka saat ini di bidang aliran untuk menemukan langkah berikutnya dalam jalur penghindaran rintangan tersingkat mereka ke objek pemain terdekat, tanpa masing-masing melakukan kueri penelusuran jalan mereka sendiri.
Ini berskala lebih baik dan lebih baik semakin banyak musuh yang Anda miliki dalam kawanan Anda. Untuk musuh tunggal, ini lebih mahal daripada A * karena ia mencari seluruh peta (meskipun Anda bisa lebih awal begitu Anda mencapai semua agen merintis jalan). Tetapi saat Anda menambahkan lebih banyak musuh, mereka dapat berbagi lebih banyak dan lebih banyak biaya pencarian jalan dengan menghitung segmen jalan bersama sekali daripada berulang kali. Anda juga mendapatkan keunggulan dari fakta bahwa BFS / Dijkdtra lebih sederhana daripada A *, dan biasanya lebih murah untuk mengevaluasi per sel yang diperiksa.
Tepat saat titik impas mencapai, dari individu A * menjadi lebih murah, ke A * dengan memoisasi menjadi lebih murah (di mana Anda menggunakan kembali beberapa hasil untuk kueri penelusuran jalan yang lalu untuk mempercepat yang berikutnya), untuk mengalirkan bidang menjadi lebih murah, akan tergantung pada implementasi Anda, jumlah agen, dan ukuran peta Anda. Tetapi jika Anda pernah merencanakan segerombolan besar musuh mendekati dari berbagai arah di area terbatas, satu bidang aliran hampir pasti akan lebih murah daripada A * yang diulang.
Sebagai contoh ekstrem, Anda dapat melihat video di sini dengan 20.000 agen yang secara bersamaan merintis jalur di kotak yang cukup kecil .
sumber
A * tidak terlalu berat kinerjanya. Saya akan mendekati situasi ini dengan memvariasikan algoritma. Lakukan A * dari waktu ke waktu dan di antara waktu memeriksa apakah langkah berikutnya bebas untuk melangkah ke atas atau Anda perlu menghindari.
Misalnya, lacak jarak pemain dari lokasi target A *, jika di atas ambang batas hitung ulang a * dan kemudian lakukan gerakan pembaruan. Sebagian besar gim menggunakan kombinasi titik jalan, misalnya kisi yang disederhanakan untuk pencarian jalur dan logika yang menangani pergerakan antara titik jalan dengan algoritme penghindaran menggunakan raycast. Para agen mencoba lari ke titik jauh dengan bermanuver di sekitar rintangan di dekat mereka adalah pendekatan terbaik menurut saya.
Cara terbaik adalah bekerja dengan mesin negara yang terbatas di sini dan membaca buku "Programming Game AI By Example" oleh Mat Buckland. Buku ini menawarkan teknik yang terbukti untuk masalah Anda dan detail matematika yang diperlukan. Kode sumber dari buku tersedia di web; buku ini dalam C ++ tetapi beberapa terjemahan (termasuk Java) tersedia.
sumber
Tidak hanya itu layak, saya percaya itu dilakukan dalam permainan komersial di tahun 90-an - BattleZone (1998).
Game itu memiliki unit 3D dengan gerakan bebas berbasis ubin, dan konstruksi basis berbasis ubin.
Begini cara kerjanya:
Pertama, A * atau sesuatu yang serupa (kemungkinan variasi A * dengan batas ketat pada berapa lama jalur itu dapat ditemukan, sehingga tidak pernah membutuhkan terlalu banyak sumber daya untuk berjalan tetapi tidak selalu menemukan jalur sepanjang jalan ke tujuan) akan digunakan untuk menemukan jalan bagi hovertank untuk mencapai tujuannya tanpa terjebak dalam hambatan berbasis ubin.
Kemudian tangki akan terbang mengitari ruang yang sebelumnya seolah-olah tertarik ke tengah ubin terdekat di jalurnya, dan jijik oleh rintangan, tank terdekat lainnya, dll.
sumber