Advertisement
  1. Game Development
  2. Programming
Gamedevelopment

Menjana Tahap Gua Rawak Menggunakan Automata Selular

by
Difficulty:IntermediateLength:LongLanguages:

Malay (Melayu) translation by Meyria (you can also view the original English article)

Penjana kandungan Prosedur adalah bit kod yang ditulis ke dalam permainan anda yang boleh membuat keping kandungan permainan baru pada bila-bila masa - walaupun permainan sedang dijalankan! Pemaju permainan telah mencuba untuk menghasilkan semuanya dari dunia 3D ke soundtrack muzik. Menambah beberapa generasi ke permainan anda adalah cara terbaik untuk memasangkan nilai tambahan: pemain menyukainya kerana mereka mendapat kandungan baru, tidak dapat diprediksi dan menarik setiap kali mereka bermain.

Dalam tutorial ini, kita akan melihat satu kaedah yang baik untuk menghasilkan tahap rawak, dan cuba untuk meregangkan sempadan apa yang anda fikirkan boleh dijana.


Selamat Datang ke Gua!

Dalam tutorial ini, kami akan membina penjana gua. Gua adalah hebat untuk semua jenis genre permainan dan tetapan, tetapi mereka terutamanya mengingatkan saya kepada penjara bawah tanah lama dalam permainan peranan.

Lihat demo di bawah untuk melihat jenis output yang anda akan dapat. Klik 'Dunia Baru' untuk menghasilkan gua baru untuk dilihat. Kami akan membincangkan tentang tetapan yang berlainan dalam masa terdekat.


Penjana ini sebenarnya mengembalikan kita blok pelbagai dimensi yang besar, masing-masing sama ada pepejal atau kosong. Jadi sebenarnya, anda boleh menggunakan penjana ini untuk pelbagai jenis permainan selain crawler penjara: peringkat secara rawak untuk permainan strategi, gim untuk permainan platform, mungkin juga sebagai arena penembak multiplayer! Jika anda melihat dengan teliti, membalikkan blok padu dan kosong menjadikan penjana pulau juga. Ia semua menggunakan kod dan output yang sama, yang menjadikan alat ini sangat fleksibel.

Mari kita mulakan dengan bertanya soalan mudah: apa yang ada di bumi adalah automaton selular?


Bermula Dengan Sel

Pada tahun 1970 an, ahli matematik yang dipanggil John Conway menerbitkan deskripsi The Game Of Life, kadang-kadang hanya dipanggil Life. Kehidupan bukanlah suatu permainan; ia lebih seperti simulasi yang mengambil grid sel (yang boleh hidup atau mati) dan memohon beberapa peraturan mudah kepada mereka.

Empat peraturan digunakan untuk setiap sel dalam setiap langkah simulasi:

  1. Jika sel hidup mempunyai kurang daripada dua orang jiran yang tinggal, ia mati.
  2. Jika sel hidup mempunyai dua atau tiga jiran yang tinggal, ia tetap hidup.
  3. Jika sel hidup mempunyai lebih daripada tiga jiran hidup, ia mati.
  4. Jika sel mati mempunyai tiga jiran yang hidup, ia menjadi hidup.

Bagus dan mudah! Tetapi jika anda mencuba kombinasi grid grid yang berbeza, anda boleh mendapatkan hasil yang sangat pelik. Gelung infinit, mesin yang meludah bentuk, dan banyak lagi. The Game of Life adalah contoh automaton selular - sel grid sel yang ditadbir oleh peraturan tertentu.

Kami akan melaksanakan sistem yang hampir sama dengan Life, tetapi bukannya menghasilkan corak dan bentuk lucu, ia akan mewujudkan sistem gua yang menakjubkan untuk permainan kami.


Melaksanakan Automaton Selular

Kami akan mewakili grid selular kami sebagai satu nilai dua nilai Boolean (benar atau salah). Ini sesuai dengan kami kerana kami hanya berminat sama ada jubin adalah pepejal atau tidak.

Inilah kami memulakan grid grid kami:

Petua: Perhatikan bahawa indeks pertama adalah koordinat-x bagi array, dan indeks kedua ialah koordinat y. Ini membuat pengaksesan larik lebih alami dalam kode.

Dalam kebanyakan bahasa pengaturcaraan, array ini akan dimulakan dengan semua nilai yang ditetapkan pada false. Itu baik untuk kita! Jika indeks array (x, y) adalah false, kita akan mengatakan bahawa sel kosong; jika benar, jubin itu akan menjadi batu padat.

Setiap satu daripada kedudukan pelbagai ini mewakili salah satu "sel" dalam grid selular kami. Sekarang kita perlu menyediakan grid supaya kita boleh mula membina gua-gua kita.

Kami akan memulakan dengan secara rawak menetapkan setiap sel sama ada mati atau hidup. Setiap sel akan mempunyai peluang rawak yang sama dihidupkan, dan anda harus memastikan bahawa nilai peluang ini ditetapkan dalam pembolehubah di mana-mana, kerana kami pasti ingin tweak kemudian dan memilikinya di suatu tempat yang mudah untuk mengakses akan membantu kami itu. Saya akan menggunakan 45% untuk bermula dengan.

Our random cave before any cellular automaton simulation steps
Gua rawak kami sebelum sebarang langkah simulasi automatis selular.

Sekiranya kita menjalankan kod ini, kita akan mempunyai grid besar sel seperti yang di atas yang secara rawak hidup atau mati. It's messy, dan ia pasti tidak kelihatan seperti sistem gua yang pernah saya lihat. Jadi apa yang seterusnya?


Menumbuhkan Gua Gua Kami

Ingat peraturan yang mengawal sel-sel di The Game Of Life? Setiap kali simulasi diteruskan dengan satu langkah, setiap sel akan memeriksa peraturan Kehidupan dan melihat apakah ia akan berubah menjadi hidup atau mati. Kita akan menggunakan idea yang sama untuk membina gua-gua kita - kita akan menulis fungsi sekarang bahawa gelung ke atas setiap sel dalam grid, dan menggunakan beberapa peraturan asas untuk menentukan sama ada ia hidup atau mati.

Seperti yang akan anda lihat kemudian, kami akan menggunakan sedikit kod ini lebih daripada sekali, jadi meletakkannya dalam fungsinya sendiri bermakna kita boleh memanggilnya seberapa banyak atau beberapa kali yang kita suka. Kami akan memberikan nama informatif yang bagus seperti doSimulationStep(), juga.

Apakah fungsi yang perlu dilakukan? Pertama sekali, kami akan membuat grid baru yang boleh kami masukkan nilai sel dikemas kini kami. Untuk memahami mengapa kita perlu melakukan ini, ingatlah bahawa untuk mengira nilai baru sel dalam grid, kita perlu melihat lapan jirannya:

gdt_1

Tetapi jika kita telah mengira nilai baru beberapa sel dan meletakkannya kembali dalam grid, maka pengiraan kami akan menjadi gabungan data baru dan lama, seperti ini:

gdt_2

Oops! Bukan itu yang kita mahukan. Oleh itu, setiap kali kita mengira nilai sel baru, bukannya memasukkannya semula ke dalam peta lama, kita akan menulisnya kepada yang baru.

Mari kita mulakan fungsi doSimulationStep(), maka:

Kami ingin mempertimbangkan setiap sel dalam grid seterusnya, dan mengira jumlah jirannya hidup dan mati. Mengira jiran anda dalam tatasusunan adalah salah satu daripada kod kod yang membosankan anda perlu menulis satu juta kali. Inilah pelaksanaan yang cepat dalam fungsi yang saya panggil countAliveNeighbours():

Beberapa perkara mengenai fungsi ini:

Pertama, untuk gelung adalah agak pelik jika anda tidak melakukan sesuatu seperti ini sebelum ini. Ideanya ialah kita mahu melihat semua sel yang berada di sekitar titik (x, y). Jika anda melihat ilustrasi di bawah, anda dapat melihat bagaimana indeks yang kami inginkan adalah kurang, sama, dan satu lagi indeks asal. Dua kami untuk gelung memberi kita hanya itu, bermula pada -1, dan berulang hingga +1. Kami kemudian menambah bahawa ke indeks asal di dalam gelung untuk mencari setiap jiran.

gdt_3

Kedua, notis bagaimana jika kita menyemak rujukan grid yang tidak nyata (contohnya, ia tidak berada di tepi peta) yang kita anggap sebagai jiran. Saya lebih suka ini untuk generasi gua kerana ia cenderung untuk membantu mengisi tepi peta, tetapi anda boleh mencuba dengan tidak melakukan ini jika anda suka.

Jadi sekarang, mari kita kembali ke fungsi doSimulationStep() kami dan tambahkan beberapa lagi kod:

Gelung ini ke atas seluruh peta, memohon peraturan kami ke setiap sel grid untuk mengira nilai baru dan meletakkannya di newMap. Peraturannya lebih mudah daripada Game of Life - kita mempunyai dua pemboleh ubah khusus, satu untuk sel-sel mati yang lahir (birthLimit), dan satu untuk membunuh sel hidup (deathLimit). Jika sel-sel hidup dikelilingi oleh kurang daripada kematianLimit sel mati, dan jika sel mati hampir sekurang-kurangnya lahirLimit sel mereka menjadi hidup. Nice dan mudah!

Semua yang ditinggalkan pada akhir adalah sentuhan terakhir untuk mengembalikan peta yang dikemas kini. Fungsi ini mewakili satu langkah dari peraturan automatis selular kami - langkah seterusnya adalah untuk memahami apa yang berlaku seperti yang kita gunakan sekali, dua kali atau lebih banyak kali pada peta permulaan kami.


Tweaking dan Tuning

Mari lihat apa kod utama generasi kini kelihatan seperti, menggunakan kod yang telah kami tulis setakat ini.

Satu-satunya kod yang benar-benar baru adalah gelang untuk menjalankan kaedah simulasi kami dengan beberapa kali. Sekali lagi, popkannya dalam pemboleh ubah supaya kita dapat mengubahnya, kerana kita akan mula bermain dengan nilai-nilai ini sekarang!

Setakat ini kami telah menetapkan pemboleh ubah ini:

  • chanceToStartAlive menetapkan bagaimana padat grid awal adalah dengan sel hidup.
  • kelaparanLimit adalah batas jiran yang lebih rendah di mana sel-sel mula mati.
  • overpopLimit adalah batas jiran di mana sel-sel mula mati.
  • NomborKelahiran adalah bilangan jiran yang menyebabkan sel mati menjadi hidup.
  • numberOfSteps adalah bilangan kali kita melakukan langkah simulasi.
Our random cave after two cellular automaton simulation steps
Gua rawak kami selepas dua langkah simulasi automatis selular.

Anda boleh biola dengan pembolehubah ini dalam demo di bahagian atas halaman. Setiap nilai akan mengubah demo secara dramatik, jadi bermain di sekitar dan melihat apa yang sesuai.

Salah satu perubahan paling menarik yang boleh anda buat ialah pemboleh ubah nomborOfSteps. Semasa anda menjalankan simulasi untuk langkah-langkah yang lebih banyak, kekasaran peta hilang, dan pulau-pulau tidak kelihatan apa-apa. Saya telah menambah dalam butang supaya anda boleh memanggil fungsi secara manual sendiri, dan melihat kesannya. Eksperimen sedikit dan anda akan dapati kombinasi tetapan yang sesuai dengan gaya anda dan jenis tahap keperluan permainan anda.

Our random cave after six cellular automaton simulation steps
Gua rawak kami selepas enam langkah simulasi automatis selular.

Dengan itu, anda sudah selesai. Tahniah - anda baru sahaja membuat penjana tahap prosedur, dilakukan dengan baik! Duduk kembali, jalankan dan ulang semula kod anda, dan senyumlah pada sistem gua yang aneh dan indah yang keluar. Selamat datang ke dunia pembentukan prosedur.


Mengambil Lagi

Jika anda merenung penjana gua indah dan tertanya-tanya apa lagi yang boleh anda lakukan dengannya, berikut adalah beberapa idea tugasan "tambahan kredit":

Menggunakan Isi Banjir untuk Menjalankan Pemeriksaan Kualiti

Pengisi banjir adalah algoritma yang sangat mudah yang boleh anda gunakan untuk mencari semua ruang dalam pelbagai yang menyambung ke titik tertentu. Sama seperti namanya, algoritma berfungsi sedikit seperti menuangkan baldi air ke tahap anda - ia menyebar dari titik permulaan dan mengisi semua sudut.

Isi banjir sangat baik untuk automata selular kerana anda boleh menggunakannya untuk melihat betapa besar gua tertentu. Sekiranya anda menjalankan demo beberapa kali, anda akan melihat beberapa peta terdiri daripada satu gua besar, sementara yang lain mempunyai beberapa gua kecil yang terpisah dari satu sama lain. Pengisi banjir boleh membantu anda mengesan betapa besar gua itu, dan kemudian sama ada menaikkan tahap jika terlalu kecil, atau membuat keputusan di mana anda mahu pemain bermula jika anda fikir ia cukup besar. Terdapat sebuah garis banjir besar di Wikipedia.

Penempatan Treasure Cepat dan Mudah

Meletakkan harta karun di kawasan sejuk kadang-kadang memerlukan banyak kod, tetapi kita sebenarnya boleh menulis agak sedikit kod untuk meletakkan harta karun di dalam sistem gua kita. Kami sudah mempunyai kod kami yang mengira berapa banyak jiran yang mempunyai persegi, oleh itu dengan mengulangi sistem gua kami, kami dapat melihat bagaimana dikelilingi oleh dinding persegi tertentu.

Sekiranya sel grid kosong dikelilingi oleh banyak dinding pepejal, ia mungkin berada di hujung koridor atau tersimpan di dinding sistem gua. Ini adalah tempat yang bagus untuk menyembunyikan harta karun - jadi dengan melakukan pemeriksaan mudah terhadap jiran-jiran kita, kita dapat menyelinap harta karun ke sudut dan di lorong-lorong.

Ini tidak sempurna. Ia kadang-kadang meletakkan harta karun dalam lubang-lubang yang tidak dapat diakses dalam sistem gua, dan kadang-kadang bintik-bintik akan menjadi jelas juga. Tetapi, dalam secubit, ini cara yang baik untuk menyebarkan koleksi di sekeliling aras anda. Cuba dalam demo dengan memukul butang PlaceTreasure()!


Kesimpulan dan Bacaan Lanjut

Tutorial ini menunjukkan kepada anda bagaimana untuk membina penjana prosedur asas tetapi lengkap. Dengan hanya beberapa langkah mudah kami menulis kod yang boleh mencipta tahap baru dalam sekelip mata. Mudah-mudahan ini telah memberi anda pengantara potensi pembangun kandungan prosedur pembangun untuk permainan anda!

Sekiranya anda ingin membaca lebih lanjut, Roguebasin adalah sumber maklumat yang besar mengenai sistem penjanaan prosedural. Ia kebanyakannya memberi tumpuan kepada permainan roguelike, tetapi banyak tekniknya boleh digunakan dalam jenis permainan lain, dan terdapat banyak inspirasi untuk menghasilkan komponen lain dari permainan juga!

Jika anda mahukan lebih lanjut mengenai Generasi Kandungan Procedural atau Cellular Automata, inilah versi dalam talian The Game Of Life (walaupun saya sangat mengesyorkan menaip "Game Of Life Of Conway" ke Google). Anda juga mungkin menyukai Wolfram Tones, percubaan yang menawan dalam menggunakan automata selular untuk menghasilkan muzik!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.