Ada beberapa masalah yang saya temui dalam game berbasis kebisingan Perlin saya. Lihatlah screenshot terlampir di bawah ini.
Area putih yang Anda lihat adalah dinding, dan area hitam bisa dilalui dengan berjalan kaki. Segitiga di tengah adalah pemain.
Saya telah mengimplementasikan fisika dalam game ini dengan menggambarnya menjadi tekstur (piksel putih atau hitam), dan kemudian mendapatkannya dari CPU.
Namun, sekarang saya berdiri dengan masalah yang berbeda. Saya ingin unit (atau merayap, apa pun sebutan Anda) untuk terus-menerus muncul, di tepi layar. Intinya di sini adalah bahwa dalam pertandingan terakhir, akan ada "kabut perang" yang tidak memungkinkan pemain untuk melihat sejauh itu.
Saya pikir saya hanya bisa memindai piksel di tepi layar dan melihat apakah tekstur fisiknya hitam, lalu menelurkan barang secara acak di sana. Namun, jika Anda melihat screenshot kedua, ada (di sudut kiri atas) contoh di mana saya tidak ingin creep muncul (karena mereka tidak akan dapat menjangkau pemain dari sana) .
Apakah mungkin untuk memiliki GPU menentukan spawn-spot ini untuk saya, atau cara lain? Saya berpikir untuk membuat vektor antara titik yang diusulkan di tepi layar dan pemain, dan kemudian mengikutinya setiap 10 voxel, dan melihat apakah dinding bertabrakan, sebelum menelurkan unit di sana.
Namun, solusi yang diusulkan di atas mungkin terlalu intensif CPU.
Ada saran tentang masalah ini?
Catatan 1 Untuk unit yang muncul, saya tidak ingin menggunakan bentuk pathfinding apa pun untuk menghindari tabrakan di dinding saat unit ini berjalan ke arah pemain. Oleh karena itu, unit harus menelurkan di tepi layar, di lokasi di mana berjalan dalam garis lurus ke arah pemain tidak akan bertabrakan dengan dinding apa pun.
sumber
Jawaban:
Ada algoritma yang cukup berguna untuk pekerjaan ini, jauh lebih efisien daripada algoritma banjir dalam situasi ini (kerumitannya adalah runtime sebanding dengan ukuran batas daripada area yang dibanjiri): ini adalah algoritma kotak marching. Konsepnya sederhana: mulai dari lokasi pemain (titik tengah layar), pilih arah dan berjalan sampai Anda menemukan dinding. Ketika Anda bertabrakan dengan dinding, Anda memulai algoritme: Anda memilih orientasi (atas atau bawah) dan mulai berbaris di atas batas area ini, menyoroti piksel. Ini memberi Anda batas dalam untuk area yang diizinkan. Setelah itu, Anda cukup memeriksa apakah kandidat poin untuk unit pemijahan terletak pada batas ini.
Ini adalah prinsip yang harus Anda ikuti untuk menjalankan batas:
http://en.wikipedia.org/wiki/File:Marchsquares.png (meh saya belum bisa memposting foto)
Deskripsi Wikipedia (walaupun memiliki banyak kompleksitas karena digunakan dengan aplikasi lain dalam pikiran):
http://en.wikipedia.org/wiki/Marching_squares
sumber
Membuat banjir mengisi dari posisi pemain; setiap area "banjir" kemudian merupakan area bermain yang valid, dan yang lainnya adalah tembok.
EDIT: Mengenai persyaratan tambahan "yang dapat dijangkau dalam garis lurus", ingatlah bahwa dalam ruang diskrit , Anda harus mendefinisikannya sedikit lebih jauh. Misalnya, semua jalur di atas bisa menjadi "garis lurus" yang valid di lingkungan seperti itu, dan saya telah melihat semuanya digunakan dalam permainan di beberapa titik:
Secara khusus, sebagian besar dari itu tidak komutatif - yang berarti hanya karena Anda dapat mencapai B dari A dalam "garis lurus" tidak berarti Anda juga dapat mencapai A dari B; tidak sebaliknya yang benar.
Selain itu, ada pertanyaan tentang bagaimana Anda menangani gerakan diagonal jika salah satu atau kedua titik "samping" menghalangi.
sumber
Bagaimana kalau membiarkan saja terjadi? Saya tidak melihat ada masalah khusus dalam hal itu.
sumber
jika penting bagi Anda untuk hanya menandai poin dengan garis lurus yang valid ke pemain, Anda dapat menggunakan algoritme seperti berikut (ini adalah kode c ++), ia menghabiskan lebih dari sekadar penimbunan banjir. mungkin ada beberapa bug kecil (saya akan senang jika ada yang memperbaiki mereka) karena saya tidak menguji kode sendiri tetapi Anda akan mendapatkan ide.
sumber
Anda dapat mengisi peta dengan warna-warna yang mewakili area cembung ..., dengan cara ini Anda dapat menelurkan unit Anda jika terletak di area yang sama. Atau Anda dapat mencari area yang mudah dijangkau dengan lebih mudah.
Ini adalah data statis sehingga Anda dapat melakukan precalc.
Anda harus mengisi titik-titik penemuan gambar di mana ada perubahan dari konvave ke cembung, secara visual sepertinya mudah ditemukan, Anda memiliki dua situasi:
sumber
Berikut adalah sesuatu yang saya benar-benar digunakan dalam permainan saya sendiri (dunia 2d dihasilkan suara simpleks, hampir persis seperti milik Anda) - Sinar. Mulai dari pemain, tentukan orientasi (acak jika Anda mau), dan ikuti garis itu sampai Anda menekan sesuatu (tepi layar ATAU asteroid). Jika Anda menekan tepi layar (dan bukan asteroid / gumpalan putih), maka Anda tahu ada garis lurus dan terbuka dari tepi layar ke pemain. Kemudian muncul monster pada titik yang Anda tekan. Jika Anda menabrak asteroid, lakukan tes ulang.
sumber
Solusi (non-GPU) lain yang dapat Anda gunakan adalah pencarian jalur. Sebelum menggambar peta, cari jalan dari setiap titik potensial di setiap tepi peta dan lihat apakah ada jalur ke tengah. Pencarian jalur * cukup baik untuk biaya / kinerja, tetapi Anda dapat melakukan ini sebelum permainan dimulai jika itu masalah.
Titik bertelur yang tidak memiliki jalur dapat diletakkan pada daftar pengecualian; atau sebaliknya (titik mana pun dengan jalur dapat diletakkan pada daftar penyertaan).
sumber