Bagaimana cara kerja peluru di video game?

64

Saya menemukan pertanyaan ini ketika saya sedang merancang sebuah video game di C #.

Jika kami mempertimbangkan game seperti Battlefield atau Call of Duty , ratusan atau bahkan ribuan peluru terbang pada saat bersamaan. Peristiwa dipicu terus-menerus, dan dari apa yang saya tahu, ini menyedot banyak kekuatan pemrosesan ... atau apakah itu? Saya ingin tahu bagaimana berbagai pengembang game mengelola peluru (2D dan 3D) dan apa metode yang paling efisien untuk masing-masingnya.

Saya membaca pertanyaan Bagaimana peluru disimulasikan dalam video game? tetapi itu tidak menyentuh bagaimana peluru bekerja dari perspektif desain program.

Saya punya beberapa ide, tetapi masing-masing memiliki kekurangan:


Metode paling efisien yang bisa saya pikirkan (untuk game 2D):

Katakanlah saya akan membuat kelas yang disebut Bullet, dan untuk berapa lama pengguna menekan tombol, setiap 0,01 detik objek Bullet akan dibuat. Peluru ini memiliki:

  • 1 Kecepatan

  • 2 Posisi awal dari tempat pengambilan gambar

  • 3 Tekstur sprite

  • 4 Efek on-hit

Karena peluru akan menjadi kelasnya sendiri, ia bisa mengatur pendengar menggambar, bergerak, dan bertindak itu sendiri.

Tidakkah akan sulit pada prosesor untuk memproses ribuan objek ini yang dipakai, kemudian dihancurkan (ketika efek on-hit dipicu)? Ruang RAM?


Metode yang efisien untuk game 3D - Pikiran lain yang saya miliki adalah:

Katakanlah saya membuat kelas senjata. Senjata ini memiliki berbagai fitur, beberapa di antaranya:

  • 1 Deteksi kemana arah senjata, dan tentukan apakah senjata itu melihat sasaran

  • 2. Memicu animasi penembakan pistol

  • 3 Memiliki metode doDamage () yang menunjukkan sesuatu untuk mengurangi kesehatan dari senjata apa pun yang diarahkan

  • 4 Memberitahu kelas animasi peluru ketika tombol ditekan

Saya kemudian dapat membuat kelas statis, kata BulletAnimation, yang bisa mendapatkan pemberitahuan dari mana senjata yang memicu itu, di mana senjata itu diarahkan (untuk tujuan peluru), dan informasi tentang sprite dan kecepatan yang tepat untuk digunakan untuk peluru. . Kelas ini kemudian menggambar sprite (pada utas baru mungkin, idk) berdasarkan kedua posisi dan sprite yang diinginkan, untuk mensimulasikan peluru yang ditembakkan dari pistol.


Yang terakhir tampaknya jauh lebih sulit untuk dikodekan, dan tidakkah akan membutuhkan banyak kekuatan pemrosesan untuk terus-menerus memanggil statis untuk melakukan ini untuk ribuan peluru pada satu waktu? Mendapatkan pembaruan yang konstan pada posisi awal dan akhir juga akan sulit.

Pertanyaan saya adalah, apa cara pembuat game paling efisien melakukannya? Apakah metode ini berubah dari game 2D ke 3D?

Eric
sumber
16
Perhatikan bahwa bahkan hari ini, sebagian besar game tidak mensimulasikan penerbangan peluru. Untuk apa pun yang dianggap "cukup cepat", hitcan sederhana dilakukan sebagai gantinya - pada dasarnya, itu diasumsikan dampak terjadi pada saat yang sama ketika Anda menekan pelatuk. Dalam kasus apa pun "ratusan atau ribuan peluru" sebenarnya bukan jumlah yang besar - itu adalah sesuatu yang dimiliki permainan sejak konsol yang sangat awal (berbagai permainan neraka), ribuan kali lebih kuat daripada mesin saat ini. Anda hanya perlu memastikan untuk hanya melakukan pekerjaan sesedikit mungkin per peluru :)
Luaan
42
Peluru biasanya bekerja melalui pew-pew-pewteknologi :)
MonkeyZeus
5
Tidak pernah ada ratusan atau ribuan peluru terbang di saat yang bersamaan. Tidak ada senjata yang menembakkan mereka secepat itu. Bahkan Phalanx yang perkasa mencapai 75 peluru per detik. Berdasarkan "Jarak tembak efektif" yang tercantum di Wikipedia, peluru terbang paling banyak sekitar 3 detik, sehingga Phalanx dapat menempatkan 225 peluru di udara pada satu waktu. M16 berada di atas sekitar 12 putaran / detik dan tidak dapat mempertahankan laju itu (maks untuk api berkelanjutan adalah 0,25 sekeliling / detik). Hanya saja tidak banyak senjata yang ditembakkan pada satu waktu!
Cort Ammon
3
Hanya untuk menunjukkan ini, tidak pernah baik untuk membuat objek kelas individu ketika mereka sangat sederhana. Jauh lebih baik untuk memiliki satu contoh bulletField untuk setiap jenis peluru. Overhead sedikit dalam panjang kode dan yang lainnya akan menghemat kata 4 byte tambahan per peluru (jika jenisnya bilangan bulat). Plus, satu objek dapat dengan mudah memindai daftar.
The Great Duck
4
@Cort - itu benar seandainya hanya ada satu senjata api di ruang permainan. OP menyebutkan game seperti Battlefield dan CoD, di mana puluhan pemain bisa menembakkan senjata otomatis secara bersamaan. Bukanlah tidak masuk akal jika ada angka yang menggelikan jika setiap putaran benar-benar diperhitungkan secara fisik dalam ruang.
Jesse Williams

Jawaban:

78

Saya pasti bisa melihat mengapa Anda akan berpikir bahwa akan sulit untuk mensimulasikan itu, tetapi ada cukup banyak kendala pada peluru (semua proyektil, sungguh) untuk membuatnya lebih mudah.

  1. Mereka umumnya disimulasikan sebagai satu titik, bukan sebagai sesuatu dengan volume. Ini membuat deteksi tabrakan secara signifikan lebih mudah, karena sekarang saya hanya perlu melakukan tabrakan terhadap permukaan yang sangat sederhana, seperti garis melawan lingkaran.

  2. Kami tahu bagaimana mereka akan bergerak, jadi tidak banyak informasi yang kami perlukan untuk menyimpan atau menghitungnya. Daftar Anda cukup akurat, umumnya kita akan memiliki beberapa hal lagi yang terkait dengannya, seperti siapa yang menembakkan peluru, dan apa tipenya.

  3. Karena semua proyektil akan sangat mirip, kita dapat melakukan pra-alokasi mereka, untuk menghindari semua biaya pembuatannya secara dinamis. Saya dapat mengalokasikan array 1000 proyektil, dan sekarang mereka dapat diakses hanya dengan indeks, dan semuanya berurutan dalam memori, jadi memprosesnya akan cepat.

  4. Mereka memiliki masa hidup / rentang yang tetap, jadi saya bisa kedaluwarsa peluru lama dan mendaur ulang memori menjadi peluru baru dengan sangat cepat.

  5. Begitu mereka menabrak sesuatu, saya juga bisa kedaluwarsa, sehingga mereka memiliki masa hidup yang terbatas.

  6. Karena kami tahu kapan mereka dibuat, jika kami membutuhkan yang baru dan kami tidak memiliki yang gratis di daftar yang telah kami alokasikan, saya bisa mengambil yang tertua dan mendaur ulangnya, dan orang-orang tidak akan melihat jika peluru kedaluwarsa sedikit lebih awal .

  7. Mereka diberikan sebagai sprite (biasanya) atau sebagai model poli rendah, dan mengambil sedikit ruang di layar, sehingga mereka cepat untuk di-render.

Dengan mempertimbangkan semua hal itu, peluru cenderung relatif murah. Jika anggaran kami dikonsumsi oleh peluru dan menghasilkannya, kami biasanya hanya akan mendesain ulang untuk membatasi jumlah tembakan yang dapat Anda tembak sekaligus (Anda akan melihat ini di banyak game arcade lama), gunakan senjata sinar yang langsung bergerak , atau memperlambat laju kebakaran untuk memastikan kami tetap sesuai anggaran.

Tom K
sumber
12
Saya harus tidak setuju dengan 5), yang sebenarnya hanya membuat semuanya rumit di game modern. Pada penembak sebelumnya ini dapat diterima, saat ini bahkan COD memungkinkan pemain untuk menembak melalui dinding kayu. 6) tidak dapat diterima untuk sistem persaingan apa pun, meskipun itu akan menjadi masalah yang jarang.
SBoss
17
@SBoss lalu ulangi: "Begitu mereka mengenai sesuatu yang tidak bisa mereka tembus, saya juga bisa kedaluwarsa, sehingga mereka memiliki masa hidup yang terbatas.". Dan untuk 6 Anda bisa mendapatkan kasus terburuk dengan membatasi laju api maksimal per karakter dan kemudian menjaga array panjangnum_characters * max_bullets_per_character
ratchet freak
14
@Boss Saya pikir # 6 lebih untuk eg. permainan luar angkasa top-down, di mana peluru yang bergerak lambat dapat melakukan perjalanan jauh di luar layar sebelum memukul sesuatu / menghilang. Jelas itu bukan masalah di game tipe CoD, di mana peluru bergerak cepat dan dengan cepat mencapai batas dunia.
BlueRaja - Danny Pflughoeft
1
Sebagian besar permainan TIDAK memodelkan peluru (balistik eksternal) sama sekali. Sebagian besar game menggunakan teknik yang disebut "pemindaian hit".
Aron
44

Mungkin salah satu cara paling efisien untuk menerapkan peluru adalah menggunakan apa yang dikenal sebagai hitscan . Ini agak sederhana dalam implementasinya - ketika Anda menembak, Anda memeriksa untuk melihat apa yang diarahkan oleh pistol (mungkin menggunakan sinar untuk menemukan entitas / objek / mesh terdekat), dan kemudian Anda 'memukulnya', melakukan kerusakan. Jika Anda ingin membuatnya tampak seperti peluru tak terlihat yang bergerak cepat dan aktual dipecat, Anda dapat memalsunya dengan menambahkan sedikit penundaan tergantung pada jarak sebelum melakukan kerusakan.

Pendekatan ini pada dasarnya mengasumsikan proyektil yang ditembakkan memiliki kecepatan tak terbatas, dan biasanya digunakan untuk jenis senjata seperti laser dan partikel / meriam dan mungkin beberapa bentuk senapan sniper .

Pendekatan selanjutnya adalah memodelkan peluru yang ditembakkan sebagai proyektil, yang dimodelkan sebagai entitas / objeknya sendiri yang dapat mengalami tabrakan, dan kemungkinan gravitasi dan / atau hambatan udara yang mengubah arah dan kecepatannya. Ini lebih kompleks daripada pendekatan hitcan karena persamaan fisika tambahan, dan lebih banyak sumber daya intensif karena ada objek peluru yang sebenarnya, tetapi dapat memberikan peluru yang lebih realistis.

Sedangkan untuk mengelola tabrakan antara peluru berbasis proyektil dan objek lain dalam game, deteksi tabrakan dapat sangat disederhanakan dengan menyortir objek Anda menjadi quad atau octrees . Oktaf terutama digunakan dalam game 3d, sedangkan quadtrees dapat digunakan dalam game 2d atau 3d. Keuntungan menggunakan salah satu dari pohon-pohon ini adalah Anda dapat sangat mengurangi jumlah kemungkinan tabrakan. Misalnya, jika Anda memiliki 20 objek aktif di level, tanpa menggunakan salah satu pohon ini, Anda harus memeriksa semua 20 untuk tabrakan dengan peluru. Membagi 20 objek di antara daun (end node) dari pohon, dan Anda dapat mengurangi jumlah cek hingga berapa banyak entitas hadir dalam daun yang sama dengan peluru.

Adapun pendekatan ini - hitscan dan proyektil, keduanya dapat digunakan secara bebas di game 2d atau 3d. Itu lebih tergantung pada apa senjata itu, dan bagaimana pembuatnya memutuskan bahwa senjata itu akan berfungsi.

Seta
sumber
Informasi tentang pola desain, Hitscan, dan quad / octrees sangat membantu. Juga, terima kasih atas informasinya!
Eric
8
Jika Anda tidak menuntut Hitscan tetapi mensimulasikan proyektil mereka dapat membengkokkan benda tipis karena mereka bergerak begitu cepat. Dalam hal ini ingatlah bahwa semua yang ada di game palsu. Meskipun panjang peluru hanya beberapa sentimeter, Anda dapat melakukan deteksi tabrakan seolah-olah panjangnya satu meter. Dengan cara ini Anda masih dapat melakukan drop peluru yang bagus dan waktu simulasi penerbangan tanpa harus terlalu khawatir tentang peluru yang melengkung melalui benda-benda tanpa memukul mereka :).
Roy T.
2
Apakah ada permainan di mana fisika peluru (yang bertentangan dengan, katakanlah, peluru meriam) menghargai hal-hal seperti gravitasi (penurunan peluru), hambatan udara? (Yaitu, permainan selain permainan khusus di mana fokusnya adalah pemotretan target presisi atau sesuatu seperti itu: FPS, dll.) Saya bukan seorang gamer, tetapi saya terkejut bahwa tingkat kesetiaan itu (bahkan kadang-kadang) diperlukan.
davidbak
3
@davidbak: ini sangat bergantung pada perjumpaan dalam game dan realisme yang diharapkan dari genre game. Jika Anda sebagian besar (hanya?) Bertempur jarak dekat pertempuran, maka memang, tingkat kesetiaan tidak diperlukan. Tetapi jika opsi untuk pertempuran jarak jauh ada (mis. Penembak jitu, atau pemanah dalam pengaturan yang lebih mirip RPG), gravitasi yang mempengaruhi rudal saat ini sudah diperkirakan. Jika Anda mengarahkan peluncur roket Anda ke atas, Anda masih akan berharap roket itu mendarat dan meledak di suatu tempat, bukan? Namun, lintasan tidak selalu dihitung dari fisika nyata, hanya perkiraan (untuk alasan kinerja)
hoffmale
1
@davidbak Battlefield sejak Bad Company 2 mengalami penurunan peluru. Baik untuk senapan, pistol, peluru tank, roket, semuanya. Battlefield 3 gratis di Origin, Anda dapat memeriksa (IIRC). Battlefield 4 tentu saja, juga memiliki 'fitur' ini. Game lain yang bisa Anda lihat adalah "Sniper Elite". 2 atau 3 adalah judul yang lebih baru. Fisika memainkan peran penting dalam game itu.
Apache
7

Saya bukan ahli, tetapi untuk menjawab pertanyaan Anda, ya, Anda akan membutuhkan banyak hal yang Anda sebutkan.

Sebagai contoh 2D Anda, Anda bisa memiliki posisi dan kecepatan untuk peluru. (Anda mungkin juga membutuhkan jarak seumur hidup atau maksimum, tergantung pada bagaimana Anda menerapkan peluru Anda.) Itu biasanya melibatkan 2 (x, y) nilai. Jika mereka mengapung, itu 16 byte. Jika Anda memiliki 100 peluru, itu hanya 1600 byte atau sekitar 1,5 ribu. Itu bukan apa-apa pada mesin hari ini.

Selanjutnya, Anda menyebutkan sprite. Anda hanya perlu satu sprite untuk mewakili setiap peluru. Ukurannya akan tergantung pada kedalaman bit yang Anda gambar dan seberapa besar tampilannya di layar. Bahkan tanpa kompresi pada, katakanlah, 256x256 dalam float penuh 32-bit per saluran, itu 1MB untuk sprite. (Dan itu akan sangat besar!) Anda akan menggambar sprite yang sama di setiap lokasi peluru, tetapi itu tidak membutuhkan memori tambahan untuk setiap salinan sprite. Itu akan serupa untuk efek on-hit.

Anda menyebutkan menembak setiap 0,01 detik. Itu akan menjadi 100 peluru per detik dari senjatamu. Bahkan untuk senjata futuristik itu cukup banyak! Menurut artikel wikipedia ini :

Ketika pemicu ditarik, laju putaran yang ditembakkan adalah laju siklik. Laju siklik api tipikal adalah 600–900 RPM untuk senapan serbu, 1.000-1.100 RPM dalam beberapa kasus, 900-1.200 RPM untuk senapan mesin ringan dan senapan mesin, dan 600-1.200 RPM untuk senapan mesin. M134 Minigun yang dipasang pada helikopter serang dan kendaraan tempur lainnya dapat mencapai tingkat tembakan lebih dari 100 putaran per detik (6.000 RPM).

Jadi itu akan menjadi tingkat serangan helikopter!

Untuk dunia besar seperti yang Anda sebutkan di Battlefield / Call of Duty / dll., Mereka dapat menghitung semua posisi peluru itu, tetapi tidak menarik semuanya jika aksinya jauh. Atau mereka mungkin tidak mensimulasikan mereka sampai Anda mendekat. (Saya harus mengakui bahwa saya menebak sedikit tentang bagian ini karena saya belum mengerjakan apa pun yang sebesar itu.)

pengguna1118321
sumber
6

Tidakkah akan sulit pada prosesor untuk memproses ribuan objek ini yang dipakai, kemudian dihancurkan (ketika efek on-hit dipicu)? Ruang RAM?

Saya pikir Anda meremehkan seberapa cepat komputer itu. Ini adalah kadang-kadang masalah pada sistem 80-an dan 90-an. Ini sebagian alasan mengapa Space Invaders asli tidak akan membiarkan Anda menembakkan peluru lain sampai yang sekarang terkena. Beberapa game menderita "perlambatan" jika ada terlalu banyak sprite di layar.

Tapi sekarang ini? Anda memiliki kekuatan pemrosesan yang cukup untuk ribuan operasi per piksel yang diperlukan untuk melakukan tekstur dan pencahayaan. Tidak ada masalah dengan ribuan objek bergerak; ini memungkinkan Anda melakukan medan yang dapat dirusak (mis. Fraksi Merah) di mana setiap fragmen melakukan pemrosesan tabrakan dengan fragmen lain dan mengikuti kurva balistik.

Anda harus sedikit berhati-hati secara algoritmik - Anda tidak dapat melakukan pendekatan naif untuk memeriksa setiap objek terhadap setiap objek lain saat Anda memiliki ribuan objek. Peluru umumnya tidak memeriksa tabrakan dengan peluru lain.

Anekdot sisi kecil: versi pertama Doom jaringan (asli tahun 90-an) mengirim satu paket melalui jaringan untuk setiap peluru yang ditembakkan. Ketika satu atau lebih pemain mendapatkan senapan mesin, ini dapat dengan mudah membanjiri jaringan. Tahun 90-an penuh dengan orang-orang yang secara ilegal bermain Doom di universitas atau jaringan kerja yang bermasalah dengan administrator jaringan mereka ketika jaringan menjadi tidak dapat digunakan.

pjc50
sumber
Saya bertanya-tanya bagaimana gergaji bekerja dalam konteks ini
reas0n
1
IIRC, masalah sebenarnya dengan malapetaka jaringan pertama adalah bahwa ia menghindari perlunya setiap paket dikirim secara terpisah ke setiap pemain lawan dengan menggunakan paket siaran sebagai gantinya. Itu mengurangi jumlah paket yang dikirim, tetapi sayangnya menimbulkan beban CPU yang cukup besar pada setiap mesin di jaringan, termasuk yang tidak memainkan permainan.
supercat
1

Saya jauh dari ahli, tetapi saya telah mengerjakan game penembak 2D multi-pemain di waktu luang saya.

Metode saya

Ada berbagai kelas peluru antara klien dan server (bahkan ketika bermain offline, contoh server dimulai pada proses yang terpisah dan terhubung dengan permainan 'utama').

Setiap centang (60 per detik) klien membuat kaitan antara pointer mouse pemain dan bagian tengah layar (di mana karakter mereka) dan itu adalah bagian dari informasi yang dikirim ke server. Jika pemain juga menembak pada saat itu (dengan asumsi senjata dimuat dan siap), instance peluru sisi-server dibuat, dengan hanya beberapa koordinat, dan kerusakan pangkalan (yang berasal dari statistik senjata yang menembak saya t). Contoh peluru kemudian menggunakan beberapa fungsi matematika untuk menghitung kecepatan X dan Y dari bearing yang kami kumpulkan dari klien.

Untuk setiap kutu berikutnya, peluru bergerak sendiri oleh koordinat tersebut, dan mengurangi kerusakan pangkalannya dengan jumlah yang telah ditentukan. Jika nilai ini berada di bawah 1, atau jika menyentuh benda padat di dunia, instance peluru dihapus, dan karena tabrakan titik pengujian sangat murah dalam 2D, bahkan senjata penembakan cepat memiliki dampak yang dapat diabaikan pada kinerja.

Adapun klien, informasi peluru sebenarnya tidak diterima melalui jaringan (itu terbukti boros dalam pengujian), alih-alih sebagai bagian dari pembaruan per-centang setiap karakter memiliki Boolean 'dipecat', yang jika benar klien membuat lokal objek peluru yang bekerja hampir persis seperti yang ada di server, satu-satunya perbedaan adalah ia memiliki sprite.

Ini berarti bahwa meskipun peluru yang Anda lihat bukanlah representasi yang sepenuhnya akurat di server, perbedaan apa pun akan hampir tidak terlihat jika sama sekali bagi pemain, dan manfaat jaringan lebih besar daripada ketidakkonsistenan.

Perhatikan metode yang berbeda

Beberapa gim, termasuk gim saya sendiri, memindahkan peluru setiap kutu seolah-olah benda fisik, sedangkan yang lain hanya membuat vektor ke arah pemotretan, atau menghitung seluruh jalur peluru dalam kutu yang dibuatnya, misalnya dalam Counter- Game mogok. Ada beberapa trik sisi klien untuk menyamarkannya, seperti animasi tembakan peluru, tetapi untuk semua maksud dan tujuan, setiap peluru hanyalah laser .

Dengan model 3D yang mungkin memiliki hitbox kompleks, standar untuk menguji tabrakan terhadap kotak ikatan sederhana PERTAMA, dan jika itu berhasil, lanjutkan ke deteksi tabrakan yang lebih 'rinci'.

TheCatOfWar
sumber
0

Ini disebut deteksi tabrakan. Komputer 8-bit melakukan ini menggunakan grafis pemain-rudal dalam perangkat keras. Mesin game modern menggunakan mesin fisika dan aljabar linier. Arah senjata saat ini direpresentasikan sebagai vektor 3D. Itu memberikan garis tak terbatas ke arah api. Setiap objek yang bergerak memiliki satu atau lebih bola pengikat karena itulah objek paling sederhana untuk mendeteksi tabrakan dengan garis. Jika keduanya berpotongan, itu merupakan pukulan, jika tidak, tidak ada pukulan. Tapi pemandangannya mungkin menghalangi, sehingga harus diperiksa juga (menggunakan volume pembatas hierarkis). Objek terdekat yang memiliki persimpangan adalah objek yang telah dipukul.

Mikael
sumber