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

Asas 2D Fizik Pelantar, Bahagian 2

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called Basic 2D Platformer Physics .
Basic 2D Platformer Physics, Part 1
Basic 2D Platformer Physics, Part 3

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

Tahap Geometri

Terdapat dua pendekatan asas untuk membina tahap platformer. Salah satu daripada mereka adalah menggunakan grid dan meletakkan jubin yang sesuai di dalam sel, dan yang lain adalah satu bentuk yang lebih bebas, di mana anda boleh meletakkan geometri tahap di mana-mana dan di mana sahaja yang anda mahu.

Terdapat kebaikan untuk kedua-dua pendekatan. Kami akan menggunakan grid, jadi mari lihat apa jenis pro yang mempunyai kaedah lain:

  • Pengesanan perlanggaran prestasi yang lebih baik terhadap grid adalah lebih murah daripada menentang objek yang diletakkan secara longgar dalam kebanyakan kes.
  • Membuatnya lebih mudah untuk mengendalikan laluan laluan.
  • Jubin lebih tepat dan dapat diprediksi daripada objek ditempatkan secara longgar, terutama ketika mempertimbangkan hal-hal seperti medan destructible.

Membina Kelas Peta

Mari kita mulakan dengan membuat kelas Peta. Ia akan memegang semua data khusus peta.

Sekarang kita perlu menentukan semua jubin yang dimuat peta, tetapi sebelum kita melakukannya, kita perlu tahu apa jenis jubin yang wujud dalam permainan kita. Buat masa ini, kami merancang hanya tiga: jubin kosong, jubin pepejal, dan platform satu hala.

Dalam demo, jenis jubin sesuai secara langsung dengan jenis perlanggaran yang kami ingin mempunyai jubin, tetapi dalam permainan sebenar yang tidak semestinya begitu. Memandangkan anda mempunyai lebih banyak jubin yang lebih visual, lebih baik untuk menambah jenis baru seperti GrassBlock, GrassOneWay dan sebagainya, untuk membiarkan enum TileType menentukan bukan sahaja jenis perlanggaran tetapi juga rupa jubin.

Kini di dalam kelas peta kita boleh menambah pelbagai jubin.

Sudah tentu, tilemap yang tidak dapat kita lihat tidak banyak digunakan untuk kita, jadi kita juga memerlukan sprite untuk membuat sandaran data jubin. Biasanya dalam Perpaduan adalah sangat tidak cekap untuk mempunyai setiap jubin menjadi objek yang berasingan, tetapi kerana kita hanya menggunakan ini untuk menguji fizik kita, tidak mengapa untuk membuatnya dalam demo ini.

Peta itu juga memerlukan kedudukan dalam ruang dunia, supaya jika kita perlu mempunyai lebih daripada sekadar satu, kita boleh memisahkannya.

Lebar dan ketinggian, dalam jubin.

Dan saiz jubin: dalam demo kami akan bekerjasama dengan saiz jubin yang agak kecil, iaitu 16 hingga 16 piksel.

Itu sahaja. Kini kami memerlukan beberapa fungsi penolong untuk membolehkan kami mengakses data peta dengan mudah. Mari mulakan dengan membuat fungsi yang akan menukar koordinat dunia ke koordinat jubin peta.

Seperti yang anda dapat lihat, fungsi ini mengambil Vector2 sebagai parameter dan mengembalikan Vector2i, yang pada dasarnya adalah vektor 2D yang beroperasi pada bilangan bulat dan bukannya terapung.

Menukar kedudukan dunia ke kedudukan peta sangat mudah-kita hanya perlu mengalihkan titik dengan mPosition supaya kita kembali relatif jubin ke kedudukan peta dan kemudian membahagikan hasilnya dengan saiz jubin.

Perhatikan bahawa kita terpaksa mengalihkan mata tambahan oleh cTileSize / 2.0f, kerana pangsi jubin berada di tengahnya. Mari kita buat dua fungsi tambahan yang akan kembali hanya komponen X dan Y dari posisi dalam ruang peta. Ia akan berguna kemudian.

Kita juga perlu mewujudkan fungsi pelengkap yang, memandangkan jubin, akan mengembalikan kedudukannya di ruang dunia.

Selain daripada menerjemahkan kedudukan, kita juga perlu mempunyai beberapa fungsi untuk melihat sama ada jubin di kedudukan tertentu kosong, adalah jubin pepejal atau platform sehala. Mari kita mulakan dengan fungsi GetTile yang sangat generik, yang akan mengembalikan jenis jubin tertentu.

Seperti yang anda dapat lihat, sebelum kita memulangkan jenis jubin, kita periksa sama ada kedudukan yang diberikan tidak melebihi had. Sekiranya ia, maka kami mahu merawatnya sebagai blok pepejal, kalau tidak kami mengembalikan jenis yang benar.

Antrian seterusnya adalah fungsi untuk memeriksa sama ada jubin adalah penghalang.

Dengan cara yang sama seperti sebelum ini, kita periksa sama ada jubin itu berada di luar batas, dan jika ia kemudiannya kembali benar, maka mana-mana jubin yang tidak terikat dianggap sebagai penghalang.

Sekarang mari kita periksa sama ada jubin adalah jubin tanah. Kita boleh berdiri di kedua-dua blok dan platform sehala, jadi kita perlu kembali benar jika jubin adalah salah satu dari kedua-dua ini.

Akhir sekali, mari tambah fungsi IsOneWayPlatform dan IsEmpty dengan cara yang sama.

Itulah semua yang kita perlukan untuk membuat kelas peta kita. Sekarang kita boleh bergerak dan melaksanakan pelanggaran watak terhadapnya.

Perlanggaran Watak-Peta

Mari kita kembali ke kelas MovingObject. Kita perlu membuat beberapa fungsi yang akan mengesan sama ada watak bertabrakan dengan tilemap.

Kaedah yang kita akan tahu sama ada watak bertembok dengan jubin atau tidak adalah sangat mudah. Kami akan memeriksa semua jubin yang ada di luar objek AABB yang bergerak.


Kotak kuning mewakili watak AABB, dan kami akan memeriksa jubin di sepanjang garis merah. Jika mana-mana daripada mereka bertindih dengan jubin, kami menetapkan pemboleh ubah perlanggaran yang sepadan dengan benar (seperti mOnGround, mPushesLeftWall, mAtCeiling atau mPushesRightWall).

Mari kita mulakan dengan mencipta fungsi HasGround, yang akan memeriksa sama ada watak itu bertembung dengan jubin tanah.

Fungsi ini kembali benar jika Watak bertindih dengan mana-mana jubin bawah. Ia mengambil kedudukan lama, kedudukan semasa dan kelajuan semasa sebagai parameter, dan juga mengembalikan kedudukan Y dari bahagian atas jubin yang kita bertembung dengan dan sama ada jubin bertembung adalah platform sehala atau tidak.

Perkara pertama yang kita mahu lakukan adalah mengira pusat AABB.

Sekarang bahawa kita telah mendapatnya, untuk pemeriksaan perlanggaran bawah kita perlu mengira permulaan dan akhir garisan sensor bawah. Talian sensor hanya satu piksel di bawah kontur bawah AABB.

BottomLeft dan bottomRight mewakili dua hujung sensor. Sekarang bahawa kita mempunyai ini, kita boleh mengira jubin mana yang perlu kita periksa. Mari kita mulakan dengan membuat gelung di mana kita akan melalui jubin dari kiri ke kanan.

Perhatikan bahawa tidak ada syarat untuk keluar dari gelung di sini-kami akan melakukannya pada akhir gelung.

Perkara pertama yang perlu kita lakukan dalam gelung adalah memastikan bahawa checkTile.x tidak lebih besar daripada hujung kanan sensor. Ini mungkin berlaku kerana kita menggerakkan titik diperiksa oleh gandaan saiz jubin, jadi sebagai contoh, jika wataknya adalah 1.5 jubin lebar, kita perlu memeriksa jubin di tepi kiri sensor, maka satu jubin ke kanan , dan kemudian 1.5 jubin ke kanan dan bukannya 2.

Sekarang kita perlu mendapatkan koordinat jubin di ruang peta untuk dapat memeriksa jenis jubin.

Pertama, mari kita mengira kedudukan teratas jubin.

Sekarang, jika jubin yang sedang diperiksa adalah penghalang, kami boleh dengan mudah kembali benar.

Akhirnya, mari kita periksa sama ada kita sudah melihat semua jubin yang berpotongan dengan sensor. Jika itu berlaku, maka kita dapat keluar dengan selamat dari gelung. Selepas kita keluar dari gelung tidak mencari jubin yang kita bertembung, kita perlu kembali false untuk membolehkan pemanggil mengetahui bahawa tidak ada tanah di bawah objek tersebut.

Itulah versi cek yang paling asas. Mari kita cuba untuk bekerja sekarang. Kembali dalam fungsi UpdatePhysics, pemeriksaan tanah lama kami kelihatan seperti ini.

Mari kita ganti menggunakan kaedah yang baru dibuat. Sekiranya watak jatuh dan kami telah menemui halangan dalam perjalanan kami, maka kami perlu mengalihkannya keluar dari perlanggaran dan juga menetapkan mOnGround kepada benar. Mari kita mulakan dengan keadaan ini.

Sekiranya keadaan itu terpenuhi maka kita perlu memindahkan watak di bahagian atas jubin yang kita bertembung.

Seperti yang anda dapat lihat, ia sangat mudah kerana fungsi itu mengembalikan paras tanah yang mana kita harus menyelaraskan objek tersebut. Selepas ini, kita hanya perlu menetapkan kelajuan menegak ke sifar dan tetapkan mOnGround kepada benar.

Jika kelajuan menegak kita lebih besar dari sifar atau kita tidak menyentuh apa-apa alasan, kita perlu menetapkan mOnGround ke false.

Sekarang mari kita lihat bagaimana ini berfungsi.

Seperti yang anda lihat, ia berfungsi dengan baik! Pengesanan perlanggaran untuk dinding di kedua-dua belah pihak dan di bahagian atas watak masih tidak ada, tetapi watak itu berhenti setiap kali ia memenuhi tanah. Kami masih perlu meletakkan lebih banyak kerja ke dalam fungsi periksa perlanggaran untuk menjadikannya lebih mantap.

Salah satu isu yang perlu kita selesaikan dapat dilihat jika watak yang diimbangi dari satu bingkai kepada yang lain terlalu besar untuk mengesan perlanggaran dengan betul. Ini digambarkan dalam gambar berikut.

Keadaan ini tidak berlaku sekarang kerana kami mengunci kelajuan maksimum maksimum kepada nilai yang munasabah dan mengemas kini fizik dengan 60 frekuensi FPS, jadi perbezaan kedudukan di antara bingkai agak kecil. Mari lihat apa yang berlaku jika kita mengemas kini fizik hanya 30 kali sesaat.

Seperti yang dapat anda lihat, dalam senario ini pemeriksaan perlanggaran tanah kami gagal. Untuk membetulkan ini, kita tidak boleh semata-mata semak jika watak itu mempunyai alasan di bawahnya pada kedudukan sekarang, tetapi kita perlu melihat sama ada terdapat sebarang halangan di sepanjang jalan dari kedudukan bingkai sebelumnya.

Mari kita kembali ke fungsi HasGround kami. Di sini, selain mengira pusat, kami juga ingin mengira pusat bingkai sebelumnya.

Kami juga perlu mendapatkan kedudukan sensor bingkai sebelumnya.

Sekarang kita perlu mengira di mana jubin menegak kita akan mula memeriksa sama ada terdapat perlanggaran atau tidak, dan di mana kita akan berhenti.

Kami memulakan carian dari jubin di kedudukan sensor bingkai sebelumnya, dan mengakhirinya pada kedudukan sensor bingkai semasa. Sudah tentu kerana apabila kita memeriksa perlanggaran tanah, kita menganggap kita jatuh ke bawah, dan itu bermakna kita bergerak dari posisi yang lebih tinggi ke yang lebih rendah.

Akhirnya, kita perlu mempunyai satu lagi gelaran lelaran. Sekarang, sebelum kita mengisi kod untuk gelang luar ini, mari kita pertimbangkan senario berikut.

Di sini anda dapat melihat anak panah bergerak cepat. Contoh ini menunjukkan bahawa kita tidak hanya perlu melewati semua jubin yang kita perlu lulus secara menegak, tetapi juga untuk menginterpolasi kedudukan objek untuk setiap jubin yang kita lalui untuk menghampiri jalan dari kedudukan bingkai sebelumnya kepada yang saat ini. Sekiranya kita terus menggunakan kedudukan objek semasa, maka dalam hal di atas, perlanggaran akan dikesan, walaupun tidak seharusnya.

Mari renarkan bottomLeft dan bawahRight sebagai newBottomLeft dan newBottomRight, jadi kami tahu bahawa ini adalah kedudukan sensor bingkai baru.

Sekarang, dalam gelung baru ini, mari kita sambungkan kedudukan sensor, supaya pada permulaan gelung kita mengandaikan sensor berada di kedudukan bingkai sebelumnya, dan pada akhirnya ia berada dalam kedudukan bingkai semasa.

Perhatikan bahawa kita menginterpolasi vektor berdasarkan perbezaan jubin pada paksi Y. Apabila kedudukan lama dan baru berada dalam jubin yang sama, jarak tegak akan menjadi sifar, jadi dalam hal ini kita tidak akan dapat membahagikan jarak. Jadi untuk menyelesaikan masalah ini, kami mahu jarak mempunyai nilai minimum 1, supaya jika senario seperti itu berlaku (dan ia akan berlaku sangat kerap), kami hanya akan menggunakan kedudukan baru untuk pengesanan perlanggaran.

Akhirnya, bagi setiap lelaran, kita perlu melaksanakan kod yang sama yang telah kita lakukan untuk memeriksa perlanggaran tanah sepanjang lebar objek tersebut.

Itu cukup banyak. Seperti yang anda bayangkan, jika objek permainan bergerak dengan pantas, cara mengatasi perlanggaran mungkin sedikit lebih mahal, tetapi ia juga meyakinkan kami bahawa tidak akan ada masalah aneh dengan objek bergerak melalui dinding pepejal.

Ringkasan

Phew, itu lebih kodak daripada yang kita fikir kita perlukan, bukan? Sekiranya anda melihat sebarang ralat atau cara pintas yang mungkin diambil, beritahu saya dan semua orang dalam komen! Pemeriksaan perlanggaran harus cukup teguh sehingga kita tidak perlu risau tentang kejadian benda yang tidak disenangi melalui blok tilemap.

Banyak kod yang ditulis untuk memastikan bahawa tiada objek yang melalui jubin pada kelajuan yang besar, tetapi jika itu bukan masalah untuk permainan tertentu, kami dengan selamat boleh mengeluarkan kod tambahan untuk meningkatkan prestasi. Ia mungkin menjadi idea yang baik untuk mempunyai bendera untuk objek bergerak pantas tertentu, supaya hanya mereka yang menggunakan versi cek yang lebih mahal.

Kami masih mempunyai banyak perkara yang perlu dipertahankan, tetapi kami berjaya membuat pemeriksaan perlanggaran yang boleh dipercayai untuk tanah, yang dapat dicerminkan dengan cukup jelas kepada tiga arah yang lain. Kami akan melakukannya pada bahagian seterusnya.

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.