Mencari bayangan yang menjanjikan untuk roguelike



Dear Khabrovchans, saya sajikan untuk perhatian Anda kelanjutan penelitian tentang topik menemukan bayangan yang cocok untuk bagel 2D.

Posting ini adalah sekuel publikasi , semacam pengerjaan kesalahan dan pengembangan ide selanjutnya.

Dalam komentar mereka, para kritikus yang disegani dengan tepat mencatat bahwa di ruang tertutup bayang-bayang berubah menjadi bersudut, dan agak tidak wajar. Beberapa solusi diajukan, saya menyukai proposal yang menggunakan ray casting untuk menghitung bayangan.



Saya mengklarifikasi, saya tidak bekerja dengan kartu video (saya belum bekerja), semua hasil dimodelkan pada CPU.

Dalam pekerjaan ini tentang reykasting, kami memahami metode membangun gambar dengan melemparkan sinar dari pengamat ke ruang angkasa sampai bersinggungan dengan hambatan (batas layar) dan menyoroti tempat tabrakan mereka.

Di sini kita akan menggunakan versi disederhanakan dari rakecasting berdasarkan persimpangan ubin dengan sinar. Metode ini telah banyak digunakan dalam permainan pseudo-tiga dimensi di masa lalu (misalnya, Wolfenstein_3D , sehubungan dengan mereka yang ada dalam subjek), kami mengadaptasinya untuk ruang dua dimensi.



Algoritma ini cukup sederhana untuk pemahaman dan perwujudan. Saya akan membawa implementasi saya sendiri:

Pascal
// i,j -  ,  -  // X,Y -    // r -     //   if cos(a)<0 then begin di :=-1; ddi:= 0; end else begin di := 1; ddi:= 1; end; if sin(a)<0 then begin dj :=-1; ddj:= 0; end else begin dj := 1; ddj:= 1; end; //        Y x1 := (i+ddi) * tile_size; y1 := y+ (x1-x) * tan(a); Dx := len(x,y,x1,y1); y1 := (j+ddj) * tile_size; x1 := x+ (y1-y) * cotan(a); Dy := len(x,y,x1,y1); sum_lenX := 0; sum_lenY := 0; //    X  Y   a rX := abs(tile_size / cos(a)); rY := abs(tile_size / sin(a)); //    repeat if sum_lenX+DX < sum_lenY+DY then begin x1 := (i+ddi) * tile_size; y1 := y+ (x1-x) * tan(a); i := i+di; //         key := is_wall(i,j); sum_lenX := sum_lenX + DX; if DX<>rX then DX:=rX; //       if r<sum_lenX then Break; end else begin y1 := (j+ddj) * tile_size; x1 := x+ (y1-y) * cotan(a); j := j+dj; //         key := is_wall(i,j); sum_lenY := sum_lenY + DY; if DY<>rY then DY:=rY; //       if r<sum_lenY then Break; end; until (      ); // x1,y1   

Karena balok melintasi sel pada setiap sumbu pada jarak yang sama, Anda dapat menghemat perhitungan dan hanya memeriksa apakah ada dinding di dalam ubin. Kita perlu persimpangan dengan penghalang dan ingat koordinatnya.

Dalam implementasi saya, saya meletakkan semua trigonometri dan divisi ke dalam tabel terpisah untuk setiap sudut, yang sangat mempercepat algoritma.

Setelah meluncurkan sinar ke segala arah dengan langkah yang diinginkan, kita mendapatkan kira-kira gambar berikut:



Meningkatkan jumlah sinar hingga beberapa ribu dan mendapatkan polyhedron yang diinginkan dari ruang lingkup. Tentu saja dimungkinkan untuk melemparkan sinar untuk setiap piksel gambar, seperti pada akselerator 3D, tetapi Anda tidak dapat melakukannya tanpa kartu video di sini.



Pekerjaan lebih lanjut dengan lapisan dimulai.

Lingkup Selanjutnya, sinar melewati sedikit ke kedalaman benda. Konvensi permainan semacam itu menciptakan karakteristik lingkungan unik dari Game 2D.



Pembuatan peta pencahayaan. Kami menghasilkan sumber cahaya statis terlebih dahulu dan menyimpan cache untuk meningkatkan kinerja, kami menerapkan yang dinamis dalam proses menampilkan di layar.



Menyatukan semuanya. Yang hilang hanyalah monster dan harta yang mengerikan ... banyak harta.



Dinding dengan kelengkungan variabel penetrasi cahaya tidak pergi ke saya, tapi mungkin itu amatir.



Dalam proses pembuatan prototipe, saya mencoba banyak variasi model, beberapa di antaranya lebih cocok untuk horor :



Saya terutama menyukai efek beberapa pantulan sinar dari dinding, tetapi bahkan penerapan naifnya sangat lambat sehingga saya meninggalkannya untuk masa depan ketika saya menjadi teman dengan kartu video.

Terima kasih atas perhatian anda

Tautan untuk bermain (exe untuk windows)

Bagian 1 , Bagian 3

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


All Articles