Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Game Development
  2. Game Physics
Gamedevelopment

Asas 2D Fizik Platform , Bahagian 6: Objek vs Tindak Balas Pelanggaran Objek

by
Difficulty:BeginnerLength:LongLanguages:
This post is part of a series called Basic 2D Platformer Physics .
Basic 2D Platformer Physics, Part 5: Object vs. Object Collision Detection
Basic 2D Platformer Physics, Part 7: Slopes Groundwork

Malay (Melayu) translation by Meyria (you can also view the original English article)

Dalam ansuran sebelumnya siri ini, kami melaksanakan mekanisme pengesanan perlanggaran antara objek permainan. Di bahagian ini, kami akan menggunakan mekanisme pengesanan perlanggaran untuk membina tindak balas fizikal yang sederhana tetapi mantap di antara objek.

Demo menunjukkan hasil akhir tutorial ini. Gunakan WASD untuk menggerakkan watak. Butang mouse tengah menanam platform satu hala, butang kanan tetikus melancarkan jubin pepejal, dan bar ruang spawns menimbulkan klon aksara. Slider menukar saiz watak pemain.

Demo telah diterbitkan di bawah Perpaduan 5.4.0f3, dan kod sumber juga serasi dengan versi Perpaduan ini.

Tindak balas Perlanggaran

Sekarang bahawa kita mempunyai semua data perlanggaran dari kerja yang telah kita lakukan pada bahagian sebelumnya, kita boleh menambah tindak balas yang mudah untuk objek bertabrakan. Matlamat kami di sini adalah untuk membolehkan benda-benda tidak dapat menembusi satu sama lain seolah-olah mereka berada di pesawat yang berbeza-kita mahu mereka menjadi kukuh dan bertindak sebagai penghalang atau platform kepada objek lain. Untuk itu, kita perlu melakukan satu perkara sahaja: menggerakkan objek keluar dari tumpang tindih jika terjadi.

Tutup Data Tambahan

Kami memerlukan beberapa data tambahan untuk kelas MovingObject untuk mengendalikan objek berbanding tindak balas objek. Pertama sekali, sangat baik untuk mempunyai boolean untuk menandakan objek sebagai kinematik-iaitu, objek ini tidak akan ditolak oleh mana-mana objek lain.

Objek ini akan berfungsi dengan baik sebagai platform, dan mereka juga dapat menggerakkan platform. Mereka sepatutnya menjadi perkara paling berat di sekitar, jadi kedudukan mereka tidak akan diperbetulkan dalam apa-apa cara-objek lain perlu bergerak untuk memberi ruang kepada mereka.

Data lain yang saya suka mempunyai maklumat sama ada kita berdiri di atas objek atau ke kiri atau kanannya, dan sebagainya. Setakat ini kita hanya dapat berinteraksi dengan jubin, tetapi sekarang kita juga boleh berinteraksi dengan objek lain.

Untuk membawa keharmonian ke dalam ini, kami memerlukan kumpulan pembolehubah baru yang menggambarkan sama ada watak itu menolak sesuatu di sebelah kiri, kanan, atas, atau bawah.

Sekarang itu banyak pembolehubah. Dalam penetapan pengeluaran, ia akan berbaloi menjadi bendera dan hanya mempunyai satu integer dan bukan semua boolean ini, tetapi demi kesederhanaan, kami akan mengendalikan cuti ini kerana mereka.

Seperti yang anda perhatikan, kami mempunyai data yang agak halus di sini. Kami tahu sama ada watak itu menolak atau menolak halangan dalam arah tertentu secara umum, tetapi kami juga boleh dengan mudah bertanya sama ada kami bersebelahan dengan jubin atau objek.

Pindah Daripada Bertindih

Mari buat fungsi UpdatePhysicsResponse, di mana kita akan mengendalikan objek berbanding tindak balas objek.

Pertama sekali, jika objek ditandakan sebagai kinematik, kita hanya kembali. Kami tidak mengendalikan tindak balas kerana objek kinematik tidak perlu bertindak balas terhadap objek lain-objek lain perlu menjawabnya.

Sekarang, ini mengandaikan bahawa kita tidak memerlukan objek kinematik untuk mempunyai data yang betul mengenai sama ada ia menolak objek di sebelah kiri, dan lain-lain. Jika itu tidak berlaku, maka ini perlu diubah sedikit, yang saya akan menyentuh kemudian ke garisan.

Kini mari kita mulakan pembolehubah yang baru-baru ini kami baru diisytiharkan.

Kami menyimpan hasil bingkai sebelumnya kepada pembolehubah yang sesuai dan pada masa ini mengandaikan bahawa kami tidak menyentuh sebarang objek lain.

Mari mulailah melewati semua data perlanggaran kami sekarang.

Mula-mula, mari kita mengendalikan kes-kes di mana objek hampir tidak menyentuh antara satu sama lain, tidak benar-benar bertindih. Dalam kes ini, kita tahu kita tidak perlu memindahkan apa-apa, hanya menetapkan pembolehubah.

Seperti yang dinyatakan sebelum ini, penunjuk bahawa objek menyentuh ialah tumpang tindih pada salah satu paksi adalah sama dengan 0. Mari kita mulakan dengan memeriksa paksi-x.

Jika keadaan itu benar, kita perlu melihat sama ada objek lain berada di sebelah kiri atau kanan AABB kami.

Akhirnya, jika ia berada di sebelah kanan, tetapkan mPushesRightObject menjadi benar dan tetapkan kelajuan supaya tidak lebih besar dari 0, kerana objek kami tidak lagi bergerak ke kanan ketika laluan disekat.

Mari kita mengendalikan bahagian kiri dengan cara yang sama.

Akhir sekali, kita tahu bahawa kita tidak perlu melakukan apa-apa lagi di sini, jadi mari kita terus ke lelaran gelung seterusnya.

Mari kita mengendalikan paksi y dengan cara yang sama.

Ini juga merupakan tempat yang baik untuk menetapkan pembolehubah bagi badan kinematik, jika kita perlu berbuat demikian. Kami tidak peduli jika tumpang tindih sama dengan sifar atau tidak, kerana kami tidak akan memindahkan objek kinematic lagi. Kita juga perlu melangkau pelarasan laju kerana kita tidak mahu menghentikan objek kinematik. Kami akan melangkau melakukan semua ini untuk demo, walaupun, kerana kami tidak akan menggunakan pemboleh ubah pembantu untuk objek kinematik.

Sekarang bahawa ini dilindungi, kita boleh mengendalikan objek yang telah bertindih dengan AABB kami. Sebelum kita berbuat demikian, biarlah saya jelaskan pendekatan yang saya ambil untuk balas tindak balas dalam demo.

Pertama sekali, jika objek tidak bergerak, dan kita bertemu dengannya, objek lain harus tetap tidak dapat ditarik. Kami menganggapnya sebagai badan kinematik. Saya memutuskan untuk pergi dengan cara ini kerana saya rasa ia lebih generik, dan tingkah laku yang mendorong selalu dapat ditangani lebih lanjut dalam garis dalam kemas kini khusus sesuatu objek tertentu.

When we bump into another object the other object should not move

Jika kedua-dua objek bergerak semasa perlanggaran, kami berpisah dengan mereka berdasarkan kelajuan mereka. Semakin pantas mereka pergi, sebahagian besar nilai pertindihan mereka akan dipindahkan kembali.

Sekarang pastikan untuk mengunci offset untuk setiap jenis perlanggaran jubin.

When we bump into another object the other object should not move even if its coming vertically

Saya fikir ini adalah pendekatan yang paling mudah dibentuk, dan mengubahnya tidak semestinya sangat sukar jika anda mahu mengendalikan beberapa respon secara berbeza.

Mari meneruskan pelaksanaan dengan mengira vektor laju mutlak untuk kedua-dua objek semasa perlanggaran. Kami juga memerlukan jumlah kelajuan, jadi kami tahu berapa peratusan tumpang tindih objek kami harus dipindahkan.

Ambil perhatian bahawa bukannya menggunakan kelajuan yang disimpan dalam data perlanggaran, kami menggunakan mengimbangi antara kedudukan pada masa perlanggaran dan bingkai sebelum itu. Ini hanya akan lebih tepat dalam kes ini, kerana kelajuan mewakili vektor pergerakan sebelum pembetulan fizikal. Posisinya sendiri diperbetulkan jika objek telah memukul jubin pepejal, misalnya, jadi jika kita ingin mendapatkan vektor laju yang diperbetulkan kita harus mengira ia seperti ini.

Kini mari kita mula menghitung nisbah kelajuan untuk objek kita. Jika objek lain adalah kinematik, kita akan menetapkan nisbah laju kepada satu, untuk memastikan bahawa kita menggerakkan vektor tumpang tindih, menghormati peraturan bahawa objek kinematik tidak boleh dipindahkan.

Sekarang mari kita mulakan dengan kes yang aneh di mana kedua-dua objek bertindih antara satu sama lain tetapi kedua-duanya tidak mempunyai kelajuan apa pun. Ini tidak sepatutnya berlaku, tetapi jika sesuatu objek dijadikan bertindih dengan objek lain, kami mahu mereka bergerak secara semula jadi. Dalam kes itu, kami ingin kedua-duanya bergerak 50% daripada vektor tumpang tindih.

Satu lagi kes adalah apabila speedSum pada paksi x sama dengan sifar. Dalam hal ini kita menghitung nisbah yang tepat untuk paksi y, dan menetapkan bahawa kita harus memindahkan 50% daripada tumpang tindih untuk paksi x.

Begitu juga kita mengendalikan kes di mana speedSum adalah sifar hanya pada paksi-y, dan untuk kes terakhir kita mengira kedua-dua nisbah dengan betul.

Sekarang bahawa nisbah dikira, kita dapat melihat betapa kita perlu mengimbangi objek kita.

Sekarang, sebelum kita memutuskan sama ada kita harus menggerakkan objek dari perlanggaran pada paksi x atau paksi y, mari kita kirakan arahan yang bertindih itu terjadi. Terdapat tiga kemungkinan: sama ada kita bertemu dengan objek lain secara mendatar, menegak, atau menyerong.

Dalam kes pertama, kita ingin bergerak keluar dari sumbu-paksi-x, dalam kes kedua kita mahu keluar dari tumpang tindih pada paksi y, dan dalam kes terakhir, kita mahu pindah dari tumpang tindih ke mana-mana paksi mempunyai sekurang-kurangnya bertindih.

Looking at our paths coming from each direction

Ingat bahawa untuk bertindih dengan objek lain kita memerlukan AABBs untuk bertindih antara kedua-dua paksi x dan y. Untuk memeriksa sama ada kita bertemu dengan objek secara mendatar, kita akan melihat jika bingkai sebelumnya kita sudah menjadi tumpang tindih objek pada paksi-y. Jika itu berlaku, dan kita tidak bertindih pada paksi-x, maka tumpang tindih itu mesti berlaku kerana dalam bingkai semasa AABB mula bertindih pada paksi x, dan dengan itu kita menolak bahawa kita bertemu dengan objek lain secara mendatar .

Pertama, mari kita kira jika kita bertindih dengan AABB yang lain dalam bingkai sebelumnya.

Sekarang mari kita sediakan keadaan untuk bergerak dari tumpang tindih secara mendatar. Seperti yang dijelaskan sebelum ini, kita perlu mempunyai overlapping pada paksi y dan tidak bertindih pada paksi x dalam bingkai sebelumnya.

Jika itu bukan kes itu, maka kita akan keluar dari tumpang tindih pada paksi-y.

Seperti yang disebutkan di atas, kita juga perlu menyembunyikan senario membentur objek tersebut secara menyerong. Kami menyerang objek tersebut secara menyerong jika AABB kami tidak bertindih pada bingkai sebelumnya pada mana-mana paksi, kerana kami tahu bahawa dalam bingkai semasa mereka bertindih pada kedua-dua, maka perlanggaran mesti berlaku pada kedua-dua paksi secara serentak.

Tetapi kita mahu bergerak keluar dari tumpang pada paksi sekiranya berlaku benjolan pepenjuru hanya jika tumpang tindih pada paksi x lebih kecil daripada tumpang tindih pada paksi-y.

Itulah kes yang diselesaikan. Sekarang kita sebenarnya perlu memindahkan objek dari tumpang tindih.

Seperti yang anda dapat lihat, kami mengendalikannya dengan sangat sama dengan kes di mana kami hampir tidak dapat menyentuh AABB lain, tetapi tambahan pula kami menggerakkan objek kami dengan mengimbangi yang dikira.

Pembetulan menegak dilakukan dengan cara yang sama.

Itulah hampir; terdapat hanya satu lagi kaveat untuk ditutupi. Bayangkan senario di mana kita mendarat di dua objek serentak. Kami mempunyai dua contoh data perlanggaran hampir sama. Apabila kita melelepsi melalui semua perlanggaran, kita membetulkan kedudukan perlanggaran dengan objek pertama, memindahkan kita sedikit.

Kemudian, kami mengendalikan perlanggaran untuk objek kedua. Tumpahan bertindih pada masa perlanggaran tidak lagi terkini, seperti yang kita sudah berpindah dari kedudukan asal, dan jika kita mengendalikan pelanggaran kedua sama kita mengendalikan yang pertama, kita akan bergerak sedikit lagi , menjadikan objek kami diperbetulkan dua kali jarak yang sepatutnya.

Vertically landing on a group of objects

Untuk menyelesaikan masalah ini, kami akan melihat sejauh mana kami telah membetulkan objek tersebut. Mari mengisytiharkan vektor offsetSum betul sebelum kita mula bergerak melalui semua perlanggaran.

Kini, mari pastikan untuk menambah semua offset yang kami gunakan untuk objek kami dalam vektor ini.

Dan akhirnya, mari kita mengimbangi pertindihan berturut-turut berturut-turut dengan vektor pembetulan terkumpul yang telah kami lakukan setakat ini.

Sekarang jika kita mendarat di dua objek yang sama tinggi pada masa yang sama, perlanggaran pertama akan diproses dengan betul, dan pertindihan kedua bertindih akan diimbangi kepada sifar, yang tidak akan memindahkan objek kita lagi.

Vertically landing on a group of objects

Sekarang bahawa fungsi kami sudah siap, mari pastikan kami menggunakannya. Tempat yang baik untuk memanggil fungsi ini akan selepas panggilan CheckCollisions. Ini akan menghendaki kami membahagikan fungsi UpdatePhysics kami kepada dua bahagian, jadi mari buat bahagian kedua sekarang, dalam kelas MovingObject.

Di bahagian kedua kami memanggil fungsi UpdatePhysicsResponse kami yang baru selesai dan mengemas kini menolak umum kiri, kanan, bawah, dan pembolehubah teratas. Selepas ini, kita hanya perlu memohon jawatan itu.

Sekarang, dalam gelung kemas kinian permainan utama, mari kita panggil bahagian kedua kemas kini fizik selepas panggilan CheckCollisions.

Selesai! Sekarang objek kita tidak boleh bertindih antara satu sama lain. Sudah tentu, dalam tetapan permainan kita perlu menambah beberapa perkara seperti kumpulan perlanggaran, dan lain-lain, jadi ia tidak wajib untuk mengesan atau membalas perlanggaran dengan setiap objek, tetapi ini adalah perkara yang bergantung pada bagaimana anda mahu mempunyai beberapa perkara dalam permainan anda, jadi kami tidak akan menyelidikinya.

Ringkasan

Itu sahaja untuk bahagian lain dari siri fizik 2D platformer yang mudah. Kami menggunakan mekanisme pengesanan perlanggaran yang dilaksanakan pada bahagian sebelumnya untuk membuat tindak balas fizikal yang sederhana antara objek.

Dengan alat ini, kemungkinan untuk membuat objek standard seperti platform bergerak, blok push, halangan tersuai, dan banyak objek lain yang tidak boleh menjadi sebahagian dari tilemap, tetapi masih perlu menjadi sebahagian daripada medan tahap dalam beberapa cara. Terdapat satu ciri yang lebih popular bahawa pelaksanaan fizik kami masih kurang, dan mereka adalah lereng.

Mudah-mudahan di bahagian seterusnya kami akan mula memperluas tilemap kami dengan sokongan untuk ini, yang akan melengkapkan set ciri-ciri asas pelaksanaan fizik yang mudah untuk platformer 2D yang perlu ada, dan itu akan menamatkan siri ini.

Sudah tentu, sentiasa ada ruang untuk penambahbaikan, jadi jika anda mempunyai soalan atau tip tentang cara melakukan sesuatu yang lebih baik, atau hanya mempunyai pendapat mengenai tutorial, sila gunakan bahagian komen untuk memberitahu saya!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.