Dalam game balap 3d yang sangat sederhana, bagaimana penanganan benturan?

9

Saya bertanya-tanya bagaimana tabrakan di beberapa game balap mobil 3d sederhana dilakukan (terutama di game seperti Outrun 2 / Motoracer).

Dalam permainan balap mobil klasik dengan lingkungan yang kompleks (dunia terbuka), saya kira ini dilakukan dengan kotak dasar (untuk mobil) untuk tabrakan pesawat (untuk trek, bangunan dan hal-hal lain). Semuanya akan dioptimalkan menggunakan beberapa kotak pembatas (ini adalah cara tabrakan dilakukan di banyak game).

Dalam game seperti Outrun 2 / Motoracer, gameplaynya sangat sederhana sehingga pengembang mungkin tidak membutuhkannya dan semuanya bisa disederhanakan banyak. Bagi mereka yang tidak pernah memainkannya, inilah yang sangat spesifik:

  • Mobil / sepeda selalu terpaku di jalan.
  • Ukuran jalan selalu sama dan memiliki bentuk yang sangat sederhana.
  • Satu-satunya kemungkinan adalah mengikuti jalan itu, tidak mungkin untuk meninggalkan jalan, atau bertabrakan dengan sesuatu yang lain (kecuali mobil / sepeda lain tetapi kami tidak peduli).
  • Ketika Anda bertabrakan dengan jalan, tabrakan arcade yang sangat mendasar dilakukan (mobil hanya didorong menjauh darinya)

Beginilah menurut saya tabrakan (bisa) dilakukan:

Seluruh trek bisa dianggap sebagai kurva bezier 3d raksasa. Dari kurva itu, poligon jalan dapat dihasilkan (menggunakan vektor depan, kiri dan atas yang dihasilkan dari kurva). Elemen-elemen lain (seperti rumah, pohon, ...) dapat juga ditempatkan dan disejajarkan menggunakan metode ini.

Kemudian, untuk menangani tabrakan (dan menggambar mobil):

1) Temukan posisi terdekat pada kurva 3d dari posisi 3d mobil saat ini. Dengan kata lain, ubah posisi mobil 3d menjadi posisi kurva bezier. Setiap posisi 3d di jalan dapat dianggap sebagai perpindahan sepanjang kurva 3d ( t) + perpindahan lateral ( d). Periksa gambar di bawah ini jika tidak jelas (ini adalah contoh 2d tapi ini berlaku untuk 3d dengan mudah).

masukkan deskripsi gambar di sini

ketika t = 0 mobil di awal bagian lintasan, ketika t = 1 mobil di akhir. ketika d = -1 atau 1 mobil berada di perbatasan lintasan, ketika d = 0 mobil berada di tengah jalan

2) sejajarkan mobil ke jalan menggunakan tdan d(sangat sederhana: untuk apa pun tdan dnilai - nilai saya bisa mendapatkan posisi 3d + vektor atas / depan / kiri). mobil sekarang terpaku di jalan

3) periksa perpindahan lateral dmobil. jika nilainya terlalu besar (d > 1)atau rendah, (d < -1)mobil berada di luar jalur. hanya klip itu untuk meletakkan mobil di tempat yang benar.

Ini juga membuat pemusnahan 3d menjadi sangat sederhana, cukup tarik trek dari tposisi mobil saat ini ke t + some_big_enough_value_to_avoid_visible_clipping.

Atau mungkin saya benar-benar salah: akan jauh lebih cepat dan sederhana untuk hanya memeriksa tabrakan mobil (kotak pembatas) dan satu set poligon yang sangat sederhana yang mewakili trek (tanpa bangunan dan semacamnya). Dunia 3d (dan model tumbukan yang dihasilkan) hanya akan dihasilkan sebelumnya, menggunakan beberapa alat pihak ke-3 (tidak ada lagi kurva 3d saat menjalankan game, hanya sekelompok poligon).

tigrou
sumber

Jawaban:

16

Saya telah mengerjakan beberapa game komersial yang mirip dengan yang Anda gambarkan.

Di setiap permainan itu, kami sebenarnya memiliki poligon yang menciptakan "dinding" yang tidak terlihat di sepanjang sisi lintasan, dan melakukan uji tabrakan tradisional terhadap dinding itu. Ini berarti bahwa kami dapat memiliki beberapa bahaya tambahan yang dapat di collidable di sisi jalan, di dalam dinding yang tidak terlihat, dan juga membiarkan kami memvariasikan lebar jalan lebih cepat dari biasanya dengan pendekatan spline.

Tetapi dengan itu, kami juga melakukan apa yang Anda sebutkan di bagian bagaimana saya pikir tabrakan akan berfungsi untuk menjaga dari tabrakan tunneling / gangguan, dan sistem ini juga banyak digunakan untuk balap logika AI. Kami juga menggunakannya untuk menentukan mobil mana yang berada di depan, sehingga kami dapat menampilkan indikator "1/2/3 / etc" pada HUD. Terkadang data ini juga digunakan untuk respawning mobil setelah kecelakaan besar.

Satu bagian yang Anda lewatkan dalam bagaimana saya pikir tabrakan akan bekerja adalah ketika Anda bekerja dengan splines seperti ini, Anda biasanya akan memberikan tulang rusuk splines. Rusuk adalah bit data yang menyatakan seberapa jauh lintasan memanjang ke samping di setiap arah dari spline. Jadi untuk spline yang panjangnya 100 meter, Anda mungkin memiliki 50 tulang rusuk, memberikan lebar lintasan setiap dua meter sepanjang panjangnya. Ini memungkinkan trek Anda untuk mengubah lebar sepanjang luasnya. Dalam gim yang saya garap, tulang rusuk ini juga membedakan antara "permukaan trek" dan "area yang bisa dilalui". Jadi, Anda akan memiliki satu set lebar jalan yang mengatakan seberapa jauh dari tengah spline Anda memiliki tarmak yang bagus, dan kemudian lebar lainnya mengatakan seberapa jauh pasir / rumput / apa pun yang berada di luar itu. Itu memungkinkan kita memiliki pemain yang bisa berkendara dalam jarak yang wajar di luar lintasan, tetapi masih ada AI yang tahu di mana permukaan jalan yang sebenarnya.

Banyak game yang telah saya kerjakan juga menyimpan data lain di tulang rusuk; satu permainan memasukkan informasi pencahayaan trek ke dalam tulang rusuk, untuk dengan mudah menghitung apakah suatu area dalam bayangan (yang kemudian digunakan untuk rendering mobil, memutuskan apakah akan menggambar suar lensa atau tidak, dan efek lainnya). Informasi lain yang terpanggang tentang penempatan kamera sinematik mana yang dapat melihat bagian spline itu, jadi kami tidak perlu melakukan perhitungan garis pandang selama pemutaran ulang. Yang lain lagi termasuk informasi tentang berapa banyak jalur yang ada di spline, ke arah mana mereka pergi, dan perpindahan horizontal di mana masing-masing jalur berada. Ini memungkinkan kami untuk memasukkan mobil lalu lintas yang dapat mengemudi dengan benar di jalur jalan. Iga sangat bagus untuk menyimpan segala jenis data yang mungkin Anda butuhkan tentang permukaan jalan Anda.

Iga biasanya disimpan dalam array yang terkait dengan spline. Untuk alasan kecepatan, implementasi normal akan memiliki rusuk spasi merata, jadi setelah Anda mengetahui jarak objek di sepanjang spline, Anda dapat menghitung indeks tulang rusuk terdekat dalam array dengan membagi jarak sepanjang spline dengan jarak antara tulang rusuk. Kalau tidak, Anda akan terjebak melakukan pencarian biner melalui array rusuk Anda untuk menemukan data lebar jalan yang benar.

Deskripsi pemusnahan Anda memberikan deskripsi dasar yang baik tentang bagaimana pendekatan spline dapat digunakan, tetapi sebenarnya sedikit lebih rumit daripada yang Anda sarankan - jika Anda menggunakan splines untuk pemusnahan dengan cara ini, belokan jepit rambut panjang seringkali tidak akan menarik sisi yang berlawanan. dari belokan, karena ketika diukur dengan jarak sepanjang lintasan, sisi yang berlawanan dari belokan bisa sangat jauh, bahkan jika itu hanya beberapa meter jauhnya ketika diukur saat gagak terbang. Selain itu, jarak di mana geometri dunia dapat dilihat biasanya berbeda dari yang di mana track mesh dapat dilihat, sehingga mereka tidak benar-benar cocok dengan sistem ini. Pengalaman saya adalah bahwa dalam kebanyakan kasus, lebih baik untuk tidak bergantung pada logika mengikuti jejak untuk menentukan apakah suatu model harus digambar; itu jauh lebih dapat diandalkan dan menyebabkan lebih sedikit gangguan untuk menggunakan pengujian frustrasi kamera standar untuk itu.

Trevor Powell
sumber
Informatif dan menyenangkan untuk membaca jawaban
onedayitwillmake
0

Dalam pembalap OpenGL saya, saya awalnya mulai dengan menggunakan dua lingkaran untuk menentukan batas trek, tapi sepertinya terlalu merepotkan. Saya hanya menggunakan glReadPixel untuk membaca warna piksel. Jika mobil pemain melebihi piksel hijau (rumput berwarna), maka pergerakannya semakin terbatas. Ada sedikit efek pada kinerja.

ztech79
sumber
Ini terdengar seperti Anda menggambarkan game 2D (lingkaran, bertabrakan dengan warna piksel). Benarkah begitu? Maka jawabannya adalah offtopic.
Kromster
Saya mengacu pada permainan dalam proyeksi perspektif. glReadpixel dapat diterapkan dalam mode perspektif 2d ortho atau 3d.
ztech79