Dalam permainan platform 2D, bagaimana memastikan pemain bergerak dengan lancar di atas tanah yang miring?

18

Saya sedang mengembangkan mesin fisika untuk game platform 2D. Saya menggunakan teorema sumbu pemisah untuk deteksi tabrakan. Permukaan tanah dibangun dari kotak pembatas yang berorientasi, dengan pemain sebagai kotak pembatas yang selaras sumbu. (Secara khusus, saya menggunakan algoritma dari buku "Deteksi Tabrakan Realtime" yang melakukan deteksi tabrakan untuk OBB menggunakan SAT). Saya menggunakan koefisien restitusi yang cukup kecil (hampir nol) dalam respons tabrakan, untuk memastikan bahwa objek dinamis tidak menembus lingkungan.

Sebagian besar mesin bekerja dengan baik, hanya saja saya khawatir tentang beberapa kasus tepi yang mungkin terjadi. Misalnya, dalam diagram, A, B dan C adalah permukaan tanah. Pemain mengarah ke kiri di sepanjang B menuju A. Tampaknya bagi saya bahwa karena ketidaktepatan, kotak pemain bisa sedikit di bawah kotak B saat terus naik dan pergi. Ketika mencapai A, oleh karena itu, sudut kiri bawah pemain mungkin kemudian bertabrakan dengan sisi kanan A, yang tidak diinginkan (karena tujuannya adalah agar pemain bergerak dengan lancar di atas A). Sepertinya masalah serupa dapat terjadi ketika pemain berada di atas kotak C, bergerak ke kiri menuju B - titik paling ekstrim B bisa bertabrakan dengan sisi kiri pemain, alih-alih sudut kiri bawah pemain meluncur ke atas dan ke kiri di atas B.

Box2D tampaknya menangani masalah ini dengan menyimpan informasi konektivitas untuk bentuk tepi, tetapi saya tidak begitu yakin bagaimana menggunakan informasi ini untuk menyelesaikan masalah, dan setelah melihat kode saya tidak benar-benar memahami apa yang dilakukannya.

Setiap saran akan sangat dihargai.

Nick Kovac
sumber
Mesin fisika umum sangat bagus untuk efek dan kotak jatuh dan semua itu, tetapi tidak untuk fisika karakter, seperti yang dijelaskan di bagian jawaban. Pertimbangkan untuk menulis fisika "statis" untuk karakter Anda, sehingga Anda dapat 100% memegang kendali, dan gunakan dinamika simulasi yang tepat untuk sisanya.
Domi

Jawaban:

14

Platform dan Fisika

Kasing tepi ini banyak. Gim platform yang menyenangkan tidak berperilaku dengan cara yang akurat secara fisik, dan kontrol dan perilaku yang diharapkan pemain setelah bertahun-tahun gim platformer "sempurna" seperti Mario sangat sulit diimplementasikan dengan teknik umum seperti yang Anda dapatkan dengan Box2D atau mesin fisika lainnya. Kebanyakan platformer yang baik tidak menggunakan segala jenis fisika generik atau respons tabrakan di pengontrol pemain mereka.

Hasilkan Hulls

Mengenai pertanyaan spesifik Anda, solusi terbaik adalah berhenti menggunakan kotak sebagai alasan Anda. Gunakan serangkaian segmen garis yang terhubung (lambung). Itu memungkinkan mesin pendeteksi benturan hanya fokus pada permukaan yang sebenarnya bisa dilalui dan tidak melihat tepi "palsu" yang ada antara AB dan BC. Itulah yang dilakukan Box2D. Bentuknya digunakan untuk menghasilkan permukaan luar, yang dihubungkan bersama untuk membentuk lambung.

Anda memerlukan ini bahkan dalam permainan berbasis ubin, atau dalam situasi di mana Anda memiliki dua objek AABB di samping yang lain bertindak sebagai lantai. Mesin tabrakan akan mengambil tepi-tepi vertikal dan menyebabkan pemain menangkapnya. Ada retas yang bisa membantu, tetapi tidak menghilangkan masalah. Solusinya adalah dengan hanya memiliki segmen garis tunggal yang mewakili permukaan daripada kotak 2D penuh.

Anda dapat membuat lambung dalam wadah generik dengan memotong poligon satu sama lain dan menggabungkan titik klip ke daftar tepi.

Permukaan Miring

Karena contoh Anda termasuk kemiringan dan Anda menyebutkan restitusi dan properti fisik lainnya, saya akan menunjukkan beberapa masalah lain yang akan segera Anda perhatikan, yang selanjutnya menggambarkan mengapa deteksi dan respons tabrakan generik tidak bekerja dengan baik untuk platformer. Pertama, coba berdiri di platform miring, melompat ke atas, lalu mendarat. Anda mungkin akan melihat bahwa karakter akan "meluncur" sedikit ketika mendarat. Masalahnya adalah kontak normal yang Anda hasilkan biasanya akan menunjuk keluar dari permukaan miring. Kemudian, ketika menyelesaikan tabrakan, pemain didorong ke arah itu. Meskipun karakter itu jatuh lurus ke bawah, dia akan didorong ke atas dan sedikit ke kanan saat mendarat, menghasilkan slide. Ini dapat diretas dengan mempertimbangkan kecepatan relatif ke dalam akun,

Masalah kedua yang akan Anda perhatikan, yang jauh lebih sulit untuk diperbaiki, adalah apa yang terjadi ketika Anda mencoba berlari cepat menuruni jalan. Pemain akan "melompat" menuruni jalan. Ini sangat terlihat bahkan di sebagian besar game AAA saat ini. Itu tidak hanya terlihat konyol, tetapi jika permainan Anda mengharuskan pemain untuk menginjakkan kaki di tanah untuk melompat, itu membuat sulit untuk berlari menuruni jalan dan melompat setengah jalan, karena pemain hanya menghubungi jalan selama sebagian kecil dari waktu yang dihabiskan turun itu. Perbaikan yang lebih sederhana adalah dengan hanya melakukan beberapa sinar gips ketika pemain bergerak, dan pasang posisi pemain ke permukaan terdekat (jika sangat dekat dengan pemain) jika pemain tidak melompat dan sebelumnya di tanah.

Anda juga dapat menemukan bahwa pemain meluncur ke udara ketika berlari menanjak jika Anda mencoba memodelkan kecepatan, gesekan, dan pengembalian pada pemain seolah-olah ia adalah tubuh kaku yang normal. Gerakan pemain harus dibatasi pada gerakan horizontal kecuali jatuh / melompat. Tentu saja, jika Anda bermain platformer zaman keemasan yang lebih tua, Anda mungkin memperhatikan bahwa kecepatan horizontal pemain seringkali konstan antara permukaan horizontal dan miring. Ini perlu diperhitungkan saat berjalan naik / turun lereng juga.

Akan ada sejumlah kasus sudut aneh lainnya yang pada akhirnya akan Anda temui juga. Jika Anda mencoba membuat platformer yang baik, yang terbaik adalah mengimplementasikan pengontrol pemain platformer yang terpisah dari fisika dan hardcode gerakan dan perilaku kontrol yang Anda inginkan, daripada mengandalkan fisika generik dan algoritma respons tabrakan.

Sean Middleditch
sumber
Terima kasih untuk balasan Anda. Saya telah mempertimbangkan mengurangi kotak yang mewakili tanah menjadi garis-garis, tetapi saya sebenarnya tidak berpikir bahwa dengan sendirinya akan memperbaiki masalah. Misalnya, jika kotak tanah sekarang adalah garis, dan jika pemain berdiri di jalur C dan bergerak ke kiri menuju B, karena ketidaktepatan, mungkin kotak pemain sedikit di bawah garis C. Kemudian, tepi kiri kotak pemain masih bisa bertabrakan dengan garis B dan menyebabkan tabrakan yang tidak diinginkan,
Nick Kovac
kecuali ada mekanisme lain untuk menghentikan hal ini terjadi. Bukan fakta bahwa Box2D menggunakan garis, bukan kotak yang memperbaiki masalah, itu adalah bahwa Box2D menggunakan bentuk rantai, yang menggunakan informasi konektivitas antara segmen garis untuk mencegah beberapa tabrakan terjadi. Masalah utama saat ini adalah saya tidak begitu mengerti detail bagaimana tepatnya melakukan ini.
Nick Kovac
Anda mengangkat beberapa poin lain yang sangat bagus tentang masalah dengan mengambil ide dari mesin fisika generik dan menerapkannya ke permainan platform. Saya telah melihat mesin serupa yang menerapkan ide-ide yang Anda diskusikan (memodifikasi tabrakan normal untuk lereng, dan menyedot pemain ke lereng), jadi setidaknya masalah-masalah itu cukup mudah dipecahkan. Titik lengket utama bagi saya adalah kasus tepi rumit terkait dengan kesalahan numerik.
Nick Kovac
@Kovsa: sekali lagi, kesalahan-kesalahan khusus itu menghilang ketika Anda menyingkirkan tepi yang seharusnya tidak menjadi bagian dari tabrakan di tempat pertama. Rangkai ujung-ujungnya bersama untuk membentuk bentuk yang tidak terputus. Saat mendesain level Anda, saya juga merekomendasikan untuk menjentikkan simpul sehingga Anda tidak memiliki celah kecil di permukaan. Tidak ada bedanya dengan bagaimana Anda mendesain level dalam editor mesh 3D.
Sean Middleditch
Hmm ... Saya rasa saya tidak mengikuti. Dalam diagram saya, jika saya menyatukan ujung-ujungnya untuk membuat bentuk yang tidak terputus, saya akan mendapatkan bentuk yang terdiri dari tiga segmen garis: bagian atas kotak A, B, dan C, kan? Meskipun itu bentuk tunggal, saya masih perlu melakukan deteksi tabrakan secara terpisah terhadap garis A, lalu B, lalu C, bukan? Kecuali Anda bermaksud algoritma yang dapat mendeteksi tabrakan antara kotak dan bentuk gabungan ini? Saya berasumsi itu tidak akan SAT, karena serangkaian tepi bisa cekung?
Nick Kovac
5

Saya pikir kedua masalah dapat diselesaikan dengan memperlakukan kotak Anda, untuk tujuan respons tabrakan, seolah-olah mereka memiliki sudut bulat (dari jari-jari yang mirip dengan kesalahan numerik Anda). Ini akan membuat permukaan gabungan yang efektif dari sudut pertemuan antara A dan B, dan B dan C, lebih halus.

Jadi jika PLAYER bergerak kiri menyentuh sudut A, tabrakan normal akan diagonal daripada murni ke kanan, sehingga memungkinkan kelanjutan dari gerakan kiri-dan-atas.


Namun, solusi yang lebih umum, pada meninjau apa yang saya ketahui tentang fisika platformer, adalah membuat pemain lebih bulat, dan meninggalkan medan sendirian. Secara khusus, pertimbangkan untuk membuat bentuk pemain kapsul (membentang-in-the-middle lingkaran (2D) / sphere (3D)) - kemudian normals tabrakan Anda akan secara alami hampir vertikal, menghilangkan masalah penangkapan.

Anda mengatakan Anda menggunakan algoritme tabrakan khusus untuk OBB, tetapi Anda tetap harus bisa, setelah menemukan tabrakan OBB-OBB, gunakan tes lebih lanjut terhadap bentuk yang sepenuhnya berada dalam OBB.

Kevin Reid
sumber
Hmm, ide yang menarik ... bagaimana Anda akan mengimplementasikannya? Memang agak bertentangan dengan kesederhanaan menggunakan kotak: (Saya setuju bahwa sepertinya itu harus menjadi masalah umum dengan solusi definitif, tapi saya tidak dapat menemukan cakupan tentang hal itu benar-benar ... terlepas dari apa yang sedang dilakukan di Box2D. Saya memposting pertanyaan serupa di forum mereka untuk mudah-mudahan mendapatkan wawasan lebih
Nick Kovac
Saya tidak memiliki detail implementasi, maaf - Saya bukan ahli dalam kode mesin fisika semacam ini. Namun, saya memang memiliki ide yang lebih baik untuk solusi yang tidak didasarkan pada faktor fudge - lihat hasil edit saya.
Kevin Reid
1
Perhatikan bahwa meski menggunakan bentuk bundar memang berfungsi, keduanya lebih rumit secara matematis dan dapat menghasilkan perilaku yang kurang optimal untuk platformer. Pemain berharap memiliki kontrol pixel-hampir sempurna atas karakter berdiri di tepian, misalnya, yang bentuk bulat akan membuat lebih atau kurang mustahil, dan karakter akan meluncur dari tepian secara tak terduga.
Sean Middleditch
Tepi: Doh! OK, tidak sesederhana yang saya pikirkan.
Kevin Reid
Ya, setelah memikirkannya, pendekatan kapsul tampaknya mungkin lebih cocok untuk game 3D daripada platformer 2D. Memiliki kontrol pixel yang sempurna jelas merupakan prioritas bagi saya (seperti pada semua platformer 2D lama). Tetapi harus ada solusi yang memungkinkan kotak untuk digunakan!
Nick Kovac