Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Programming

Pengekodkan Penjana Sequence Custom untuk Menaikan Starscape

by
Difficulty:IntermediateLength:LongLanguages:

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

Dalam artikel terdahulu saya, saya menjelaskan perbezaan antara penjana nombor pseudorandom dan penjana urutan, dan memeriksa kelebihan penjana urutan mempunyai PRNG.   Dalam tutorial ini kita akan kod penjana urutan yang agak mudah. Ia menjana rentetan nombor, memanipulasi dan menafsirkan urutan ini, dan kemudian menggunakannya untuk menarik bintang-bintang yang sangat mudah.

Nota: Walaupun tutorial ini ditulis menggunakan Java, anda harus menggunakan teknik dan konsep yang sama dalam hampir semua persekitaran pembangunan permainan.


Mencipta dan Memulakan Imej

Perkara pertama yang perlu kita lakukan ialah membuat imej. Untuk penjana urutan ini, kami akan membuat imej 1000 × 1000px untuk memastikan penjanaan nombor semudah mungkin. Bahasa yang berlainan melakukannya dengan berbeza, jadi gunakan kod yang diperlukan untuk platform dev anda.

Apabila anda berjaya membuat imej, tiba masanya untuk memberikan warna latar belakang. Oleh kerana kita bercakap tentang langit berbintang, lebih masuk akal untuk bermula dengan latar belakang hitam (#000000) dan kemudian menambah bintang-bintang putih, bukan sebaliknya.


Membuat Profil Bintang dan Bidang Bintang

Sebelum kita mula bekerja pada penjana urutan, anda perlu memikirkan di mana anda ingin mengetuai dengannya. Ini bermakna mengetahui apa yang anda ingin buat, dan bagaimana biji dan nombor yang berlainan berbeza-beza seperti yang anda mahu buat - dalam kes ini bintang-bintang.

Untuk melakukan ini, kita perlu membuat profil bintang sampel yang akan mengandungi pembolehubah kelas yang menunjukkan beberapa sifat bintang. Untuk memastikan perkara mudah, kita akan bermula dengan hanya tiga sifat:

  • koordinat-x
  • koordinat-y
  • saiz

Setiap tiga sifat tersebut akan mempunyai nilai antara 0 hingga 999, yang bermaksud setiap atribut akan mempunyai tiga angka yang diperuntukkan kepadanya. Semua ini akan disimpan dalam kelas Bintang.

Dua kaedah penting dalam kelas Bintang ialah getSize() dan getRadiusPx(). Kaedah getSize() mengembalikan saiz bintang, dikurangkan ke nombor perpuluhan antara sifar dan satu, dan kaedah getRadiusPx() mengembalikan betapa besar jejari bintang harus berada pada imej akhir.

Saya telah mendapati bahawa 4 piksel membuat radius maksimum yang baik dalam demo saya, jadi getRadiusPx() hanya akan mengembalikan nilai getSize() didarab dengan empat. Sebagai contoh, jika kaedah getSize() mengembalikan radius 0.4, kaedah getRadiusPx() akan memberi jejari sebanyak 1.6px.

Kita juga harus membuat kelas yang sangat sederhana yang tugasnya untuk menjejaki semua bintang dalam setiap urutan bintang. Kelas Starfield hanya terdiri daripada kaedah yang menambah, mengeluarkan atau mengambil bintang dari ArrayList. Ia juga harus dapat mengembalikan ArrayList.


Merancang Penjana Urutan

Sekarang bahawa kami telah selesai profil bintang dan memaparkan imej, kami mengetahui beberapa perkara penting mengenai penjana urutan yang ingin kami buat.

Pertama sekali, kita tahu bahawa lebar dan ketinggian imej adalah 1000px. Ini bermakna, untuk mengeksploitasi sumber-sumber yang ada, pelbagai koordinat x- dan y- harus jatuh dalam julat 0-999. Oleh kerana dua nombor yang dikehendaki jatuh dalam julat yang sama, kita boleh menggunakan julat yang sama dengan saiz bintang supaya keseragaman. Saiznya kemudiannya akan dinyalakan kemudian apabila kita mentafsirkan siri nombor.

Kami akan menggunakan beberapa pembolehubah kelas. Ini termasuk: s_seed, integer tunggal yang mentakrifkan keseluruhan urutan; s_start dan s_end, dua bulat yang dijana dengan memisahkan benih menjadi dua; dan s_current, integer yang mengandungi nombor terbaharu yang dihasilkan dalam urutan.

Creating a sequence
Lihat imej ini dari artikel terdahulu saya. 1234 adalah benih, dan 12 dan 34 adalah nilai awal s_start dan s_end.
Tip: Perhatikan bahawa setiap nombor yang dijana berasal dari benih; tidak ada panggilan untuk rawak(). Ini bermakna bahawa benih yang sama akan sentiasa menjana bintang yang sama.

Kami juga akan menggunakan s_sequence, String yang akan memegang urutan keseluruhan. Dua pemboleh ubah kelas terakhir ialah s_image (jenis Imej - kelas yang akan kami buat kemudian) dan s_starfield (jenis Starfield, kelas yang baru saja kita buat). Yang pertama menyimpan imej, sementara yang kedua mengandungi bintang bintang.

Laluan yang akan kami ambil untuk mencipta penjana ini agak mudah. Pertama, kita perlu membuat pembina yang menerima benih. Apabila ini dilakukan, kita perlu membuat kaedah yang menerima integer mewakili bilangan bintang yang mesti dibuat. Kaedah ini kemudiannya memanggil penjana sebenar untuk menghasilkan angka. Dan kini memulakan kerja nyata ... mewujudkan penjana urutan.


Mengekod Penjana Urutan

Perkara pertama penjana urutan yang perlu dilakukan adalah menerima benih. Seperti yang disebutkan, kita akan memisahkan benih menjadi dua: dua digit pertama, dan dua digit terakhir. Atas sebab ini, kita mesti memeriksa sama ada benih mempunyai empat digit, dan pad dengan nol jika tidak. Apabila ini dilakukan, kita kemudian boleh memisahkan rentetan benang menjadi dua pembolehubah: s_start dan s_end. (Perhatikan bahawa benih sendiri tidak akan menjadi sebahagian daripada urutan sebenar.)

Jadi:

  • benih = 1234 bermakna s_start = 12 dan s_end = 34
  • benih = 7 bermakna s_start = 00 dan s_end = 07
  • biji = 303 bermaksud s_start = 03 dan s_end = 03

Selanjutnya dalam baris: buat satu lagi kaedah yang, memandangkan kedua-dua nombor, menjana nombor seterusnya dalam urutan.

Mencari formula yang betul adalah proses yang lelah. Ini biasanya bererti jam kerja percubaan dan kesilapan yang cuba mencari jujukan yang tidak melibatkan banyak corak dalam imej yang dihasilkan. Oleh itu, lebih bijak untuk mencari formula terbaik sebaik sahaja kita dapat melihat imej, dan bukannya sekarang. Apa yang kita berminat sekarang ialah mencari formula yang menjana urutan yang lebih rawak. Atas sebab ini, kami akan menggunakan formula yang sama yang digunakan dalam urutan Fibonacci: penambahan kedua-dua nombor.

Apabila ini dilakukan, kita kini boleh bergerak dan mula membuat urutan. Dalam kaedah yang lain, kita akan memanipulasi benih awal untuk menghasilkan aliran keseluruhan nombor, yang kemudiannya boleh ditafsirkan sebagai sifat profil bintang.

Kita tahu bahawa untuk bintang tertentu kita memerlukan sembilan digit: tiga yang pertama menentukan koordinat x, tiga pertengahan menentukan koordinat y, dan tiga yang terakhir menentukan saiznya. Oleh itu, seperti halnya ketika memberi makan benih, untuk menjaga keseragaman di sepanjang hal itu penting untuk memastikan setiap angka yang dihasilkan memiliki tiga digit. Dalam kes ini, kita juga perlu memotong nombor jika lebih besar daripada 999.

Ini agak serupa dengan apa yang telah kita lakukan sebelum ini. Kami hanya perlu menyimpan nombor dalam String sementara, temp, kemudian buang digit pertama. Sekiranya nombor itu tidak mempunyai tiga digit, kita harus padanya dengan nol seperti yang kita lakukan sebelum ini.

Dengan itu dibungkus, sekarang kita harus membuat satu lagi kaedah yang mencipta dan mengembalikan profil bintang setiap kali kita menghasilkan tiga nombor. Dengan menggunakan kaedah ini, kita kemudian boleh menambah bintang ke ArrayList bintang.


Meletakkan Semuanya Bersama-sama

Selepas ini selesai, kita boleh memasang penjana. Ia sepatutnya menerima bilangan bintang yang telah dihasilkannya.

Kita sudah tahu bahawa untuk satu bintang, kita memerlukan sembilan digit, jadi penjana ini perlu mengira bilangan aksara dalam rentetan. Kaunter, s_counter, akan menyimpan panjang maksimum jujukan tersebut. Oleh itu, kita mengalikan bilangan bintang dengan sembilan dan mengeluarkan satu sejak String bermula dari indeks sifar.

Kita juga perlu mengira jumlah aksara yang telah kita buat sejak kita membuat bintang. Untuk tugas ini, kami akan menggunakan s_starcounter. Untuk gelung, yang akan berulang sehingga panjang siri sama dengan s_counter, kini kita boleh memanggil kaedah yang telah kami buat setakat ini.

Tip: Kita tidak boleh lupa untuk menggantikan s_start dan s_end, atau kita akan terus menghasilkan nombor yang sama berulang kali!

Lukisan Bintang

Sekarang bahawa bahagian yang sukar berakhir, akhirnya adalah masa untuk bergerak ke kelas Imej, dan mula menarik bintang.

Dalam kaedah yang menerima Starfield, kami mula-mula membuat contoh Warna, kemudian mengambil bilangan bintang yang mesti kita lukis. Dalam gelung for, kita akan menarik semua bintang. Setelah membuat salinan bintang semasa, penting untuk mendapatkan jejari bintang. Memandangkan bilangan piksel adalah integer, kita harus menambah jejari untuk menjadikannya integer.

Untuk menarik bintang, kami akan menggunakan kecerunan jejari.

An example of a radial gradient
Contoh kecerunan radial

Kelegapan gradien radial bergantung kepada jarak piksel dari pusat. Pusat bulatan akan mempunyai koordinat (0,0). Menggunakan konvensyen yang paling biasa, mana-mana piksel di sebelah kiri pusat mempunyai koordinat-x negatif, dan mana-mana piksel di bawah mempunyai koordinat-y negatif.

Oleh itu, sarang for gelung bermula dengan nombor negatif. Menggunakan teorem Pythagoras kita mengira jarak dari pusat bulatan dan menggunakannya untuk mendapatkan kelegapan. Bagi bintang yang mempunyai jejari terkecil yang mungkin (1px), kelegapan mereka bergantung semata-mata pada saiz mereka.

Untuk membungkus perkara, kita perlu membuat satu kaedah yang menerima String dan menggunakannya untuk menyimpan imej dengan nama fail itu. Dalam penjana, kita harus membuat imej terlebih dahulu. Kemudian, kita perlu memanggil dua kaedah terakhir ini dari penjana urutan.

Di dalam kelas Utama, kita harus membuat contoh generator penjana, menetapkannya sebagai benih dan mendapatkan bilangan bintang yang baik (400 sepatutnya cukup). Cuba jalankan program ini, perbaiki sebarang kesalahan, dan semak laluan destinasi untuk melihat imej yang dibuat.

The resulting image with a seed 1234
Imej yang terhasil dengan benih 1234

Kemajuan

Masih ada beberapa perubahan yang boleh kita buat. Sebagai contoh, perkara pertama yang anda perhatikan adalah bahawa bintang-bintang berkumpul di pusat. Untuk membetulkannya, anda perlu membuat formula yang baik yang menghilangkan apa-apa corak. Sebagai alternatif anda boleh membuat beberapa formula dan ganti antara mereka menggunakan kaunter. Rumus yang kami gunakan adalah:

Terdapat satu peningkatan yang lebih mudah yang boleh kita laksanakan. Jika anda melihat ke langit, anda akan melihat beberapa bintang besar dan banyak lagi yang kecil. Walau bagaimanapun, dalam kes kita bilangan bintang kecil kira-kira sama dengan bilangan bintang besar. Untuk membetulkannya, kami hanya perlu kembali kepada kaedah getSize() dalam kelas Bintang. Selepas membuat saiz pecahan satu, kita perlu menaikkan nombor ini kepada kuasa integer - contohnya empat atau lima.

Menjalankan program kali terakhir harus memberi anda hasil yang memuaskan.

The final result – a whole starscape procedurally generated by our Sequence Generator!
Hasil akhir - keseluruhan pemandangan yang dihasilkan oleh Generator Sequence!

Kesimpulan

Dalam kes ini, kami menggunakan Penjana Urutan untuk menghasilkan latar belakang secara procedural. Penjana Sequence seperti ini boleh mempunyai lebih banyak kegunaan –  contohnya, koordinat z boleh ditambah kepada bintang supaya bukan gambar lukisan, boleh menghasilkan bintang sebagai objek dalam persekitaran 3D.

Advertisement
Advertisement
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.