Pertanyaan ini adalah pertanyaan "tindak lanjut" dari pertanyaan saya sebelumnya, mengenai deteksi dan resolusi tabrakan, yang dapat Anda temukan di sini .
Jika Anda tidak ingin membaca pertanyaan sebelumnya, inilah uraian singkat tentang cara kerja mesin fisika saya:
Setiap entitas fisik disimpan dalam kelas yang disebut SSSPBody.
Hanya AABB yang didukung.
Setiap SSSPBody disimpan dalam kelas yang disebut SSSPWorld, yang memperbarui setiap tubuh dan menangani gravitasi.
Setiap frame, SSSPWorld memperbarui setiap orang.
Setiap badan yang diperbarui mencari benda-benda terdekat dalam hash spasial, memeriksa apakah mereka perlu mendeteksi tabrakan dengan mereka. Jika ya, mereka meminta acara "tabrakan" dan memeriksa apakah mereka perlu menyelesaikan tabrakan dengan mereka. Jika ya, mereka menghitung vektor penetrasi dan tumpang tindih terarah, kemudian mengubah posisi mereka untuk menyelesaikan penetrasi.
Ketika sebuah tubuh bertabrakan dengan yang lain, ia mentransfer kecepatannya ke yang lain hanya dengan mengatur kecepatan tubuh ke miliknya.
Kecepatan benda ditetapkan ke 0 bila posisi tidak berubah dari bingkai terakhir. Jika juga bertabrakan dengan benda yang bergerak (seperti lift atau platform yang bergerak), ia menghitung perbedaan gerakan lift untuk melihat apakah benda tersebut belum bergerak dari posisi terakhirnya.
Juga, tubuh memanggil peristiwa "hancur" ketika semua sudut AABB tumpang tindih sesuatu dalam bingkai.
Ini adalah kode sumber LENGKAP game saya. Ini dibagi dalam tiga proyek. SFMLStart adalah perpustakaan sederhana yang menangani input, menggambar, dan memperbarui entitas. SFMLStartPhysics adalah yang paling penting, di mana kelas SSSPBody dan SSSPWorld berada. PlatformerPhysicsTest adalah proyek game, berisi semua logika game.
Dan ini adalah metode "pembaruan" di kelas SSSPBody, berkomentar dan disederhanakan. Anda dapat melihat ini hanya jika Anda tidak ingin melihat keseluruhan proyek SFMLStartSimplePhysics. (Dan bahkan jika Anda melakukannya, Anda masih harus melihat ini sejak berkomentar.)
Gif menunjukkan dua masalah.
- Jika badan ditempatkan dalam urutan yang berbeda, hasil yang berbeda terjadi. Peti di sebelah kiri identik dengan peti di sebelah kanan, hanya ditempatkan dalam urutan terbalik (di editor).
- Kedua peti harus didorong ke bagian atas layar. Dalam situasi di sebelah kiri, tidak ada peti yang didorong. Di sebelah kanan, hanya satu dari mereka. Kedua situasi itu tidak disengaja.
Masalah pertama: urutan pembaruan
Ini cukup mudah dimengerti. Dalam situasi di sebelah kiri, peti paling atas diperbarui sebelum yang lain. Bahkan jika peti di bagian bawah "mentransfer" kecepatan ke yang lain, ia harus menunggu frame berikutnya untuk bergerak. Karena tidak bergerak, kecepatan peti bawah diatur ke 0.
Saya tidak tahu bagaimana cara memperbaikinya. Saya lebih suka solusi untuk tidak bergantung pada "menyortir" daftar pembaruan, karena saya merasa saya melakukan sesuatu yang salah di seluruh desain mesin fisika.
Bagaimana mesin fisika utama (Box2D, Bullet, Chipmunk) menangani urutan pembaruan?
Masalah kedua: hanya satu peti yang didorong ke langit-langit
Saya belum mengerti mengapa ini terjadi. Apa yang dilakukan entitas "pegas" adalah mengatur kecepatan tubuh menjadi -4000 dan menempatkannya kembali di atas pegas itu sendiri. Bahkan jika saya menonaktifkan kode pemosisian ulang, masalah masih terjadi.
Ide saya adalah ketika peti bawah bertabrakan dengan peti atas, kecepatannya diatur ke 0. Saya tidak yakin mengapa ini terjadi.
Meskipun ada kemungkinan terlihat seperti seseorang yang menyerah pada masalah pertama, saya memposting seluruh kode sumber proyek di atas. Saya tidak punya apa-apa untuk membuktikannya, tetapi percayalah, saya berusaha keras untuk memperbaikinya, tetapi saya tidak bisa menemukan solusi dan saya tidak punya pengalaman sebelumnya dengan fisika dan tabrakan. Saya sudah mencoba menyelesaikan dua masalah ini selama lebih dari seminggu dan sekarang saya putus asa.
Saya tidak berpikir saya dapat menemukan solusi sendiri tanpa menghilangkan banyak fitur dari permainan (transfer kecepatan dan pegas, misalnya).
Terima kasih banyak untuk waktu yang dihabiskan untuk membaca pertanyaan ini, dan terima kasih lebih banyak lagi jika Anda bahkan mencoba mencari solusi atau saran.