Bayangan realistis untuk roguelike

gambar

Waktu yang baik, komunitas Habr.

Beberapa tahun yang lalu, saya menemukan posting (1) . Kemudian saya bingung dengan kesempatan untuk membuat elemen menarik untuk gameplay di roguelike (2) . Misalkan seorang musuh bisa berada di belakang tembok, kita tidak melihatnya sampai kita bertemu dengannya di garis pandang. Tapi saya lebih suka situasi ketika kita, bepergian di sepanjang koridor ruang bawah tanah, mengungkapkan fitur lokasi objek secara bertahap berdasarkan ruang lingkup.

Kemudian di posting: (3) , (4) dan (5) , pertanyaan tentang casting bayangan di game 2D dipertimbangkan. Sebagaimana dicatat oleh penulis sendiri dan dalam komentar, perhitungan bayangan cukup banyak dan bukan tugas yang mudah, baik untuk kalkulator dan untuk desain.

Entah bagaimana saya punya beberapa hari bebas, dan saya memutuskan untuk kembali ke pertanyaan tentang bayangan yang lebih menjanjikan. Jelas bahwa kartu video berhasil mengatasi bayangan dengan cepat dan sukses, tetapi dalam kasus ini, saya ingin memproses bayangan untuk permainan 2D, dan sepertinya berlebihan untuk mentransfer perhitungan ke kartu video. Ya, dan kekuatan prosesor dalam beberapa tahun terakhir secara keseluruhan telah berkembang, sebenarnya sebuah pos tentang apa yang terjadi pada akhirnya.

Program ini ditulis dalam Pascal, hanya karena saya mengetahuinya dengan baik, dan Lazarus adalah IDE terbuka dengan berbagai komponen.

Gagasan aslinya adalah menggambar garis, dari pengamat melalui masing-masing sudut ubin, dan kemudian menggelapkan gambar yang dihasilkan.

gambar

Namun, bayangan seperti itu terlihat agak tidak wajar ketika sudut pandang berubah. Bayangannya sekarang lebih luas, sekarang lebih sempit.

gambar

Bayangan benda bulat terlihat jauh lebih baik. Untuk membangun bayangan seperti itu, Anda perlu menggambar dua garis singgung dari titik pengamatan ke lingkaran, dan ke batas layar. Diameter lingkaran akan sesuai dengan ukuran ubin.

Dalam program saya, saya menggunakan fungsi berikut:

//       function tangent_to_circle(x1,y1,x2,y2,r:Single; var x3,y3,x4,y4:Single):Boolean; var l,dx,dy,i,ii,ij:Single; begin dx := x1 - x2; dy := y1 - y2; l := Sqrt(dx*dx + dy*dy); if l<=r then begin tangent_to_circle:=false; exit; end; i := r/l; ii := i*i; ij := i * Sqrt(1 - ii); x3 := x2 + dx*ii - dy*ij; y3 := y2 + dx*ij + dy*ii; x4 := x2 + dx*ii + dy*ij; y4 := y2 - dx*ij + dy*ii; tangent_to_circle:=true; end; 

Di mana (x1, y1) adalah titik pengamatan, (x2, y2) adalah pusat lingkaran, ® adalah jari-jarinya, dan (x3, y3) dan (x4, y4) adalah titik persimpangan dari garis dan lingkaran. Fungsi mengembalikan true hanya ketika pengamat berada di luar lingkaran.

Karena prosesornya tidak terlalu ramah dengan trigonometri, saya mencoba menggunakannya seminimal mungkin. Sebenarnya mengandalkan aturan sederhana (model kasar), para ahli akan memberi tahu Anda alasannya.

(Buruk) SIN, COS ..> '/', SQRT> 'DIV', 'MOD'> 'SHR', 'SHL'> '*'> ': =', '+', '-', 'DAN ',' XOR '.. (Bagus)

Sangat menyenangkan untuk mengimplementasikan bagian grafis primitif pada kanvas, ada banyak perpustakaan dan mesin yang memfasilitasi pekerjaan. Ketika mengembangkan pada Delphi, saya harus menggunakan perpustakaan Agg2D, pada Lazarus ada port-nya (6) , dan di atasnya saya memutuskan untuk mewujudkan ide tersebut. Sebenarnya, keuntungan dari perpustakaan adalah bahwa saluran alfa ditambahkan ke warna RGB, dan primitif dihaluskan, dan karena akses langsung ke piksel dan berbagai trik, pemrosesan jauh lebih cepat daripada kanvas.

Ketika menggambar bayangan ubin, saya awalnya akan mengisi sektor dengan bayangan, tetapi kemudian gambar di dalam ubin itu dibedakan dengan buruk (sektor yang dimaksud dalam Gambar 3. diisi dengan hijau). Setelah bereksperimen dengan berbagai opsi, saya berhenti memilih sektor dari area bayangan.

Untuk menggambar sektor ini, kita perlu sudut dalam radian, tetapi trigonometri masih belum bisa. (arctan2 - fungsi perpustakaan modul matematika)

 //     function alpha_angle(x1,y1,x2,y2:Single):Single; begin alpha_angle := arctan2(y1 - y2, x1 - x2); end; 

Sebenarnya, semuanya siap untuk perakitan gambar. Kami mengambil peta ubin dan pada layer terpisah kami secara berurutan menerapkan bayangan, satu per satu. Untuk pohon, bayangan lebih gelap, untuk objek lain, bayangan lebih transparan.

gambar

Gambar yang sudah selesai diaplikasikan di atas lapisan utama ubin. Sedikit desain latar belakang dan mengambil ubin lebih generik. Sebenarnya, saya butuh dua hari untuk mencari tileset yang cocok, yang ada dalam domain publik atau kualitas rendah atau biaya uang. Akibatnya, ia menggambar pohon sendiri, dan meminjam elemen lain dari pengguna Joe Williamson (7) (gaya sangat baik).

gambar

Itu akan berakhir, tetapi ada beberapa endapan tentang kinerja. Dengan jumlah objek sekitar lima ratus drawdown dimulai. Berbagai metode optimasi dipertimbangkan, dan membelah menjadi kernel dan membatasi area gambar ke radius tertentu, mengubah bentuk bayangan (menjadi lebih murah daripada busur), saya bahkan berpikir untuk mentransfer perhitungan ke video.

Sebagai hasilnya, saya sampai pada kesimpulan bahwa pilihan terbaik adalah mengurangi pengambilan sampel gambar yang berfungsi sebagai topeng bayangan. Karena jumlah perhitungan berkurang secara signifikan, serta efek tak terduga dari pixelation dari kontur bayangan, yang memberikan pesona jadul tertentu.

gambar

Saya sangat menyukai efeknya sehingga saya harus membuat skala proses yang dinamis, melalui parameter multiplisitas yang diberikan.

gambar

Yang tersisa hanyalah membuat dinding buram dan mempresentasikan hasilnya kepada masyarakat.

gambar

Saya menantikan game baru menggunakan efek ini atau perkembangannya.
Terima kasih

Demo di mana Anda dapat menyentuh gagang (exe untuk windows).

Bagian 2 , Bagian 3

Referensi:
1) habr.com/post/16927/
2) en.wikipedia.org/wiki/Roguelike
3) habr.com/post/204782/
4) habr.com/post/305252/
5) habr.com/post/319530/
6) wiki.freepascal.org/BGRABitmap
7) twitter.com/joecreates

Source: https://habr.com/ru/post/id430438/


All Articles