Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Platformer
Gamedevelopment

Asas 2D Fizik Platformer, Bahagian 1

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

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

Perlanggaran Karakter

Baiklah, jadi premis kelihatan seperti ini: kami mahu membuat platformer 2D dengan fizik yang mudah, mantap, responsif, tepat dan boleh diramal. Kami tidak mahu menggunakan enjin fizik 2D besar dalam kes ini, dan terdapat beberapa sebab untuk ini:

  • respons tabrakan tak terduga
  • sukar untuk menubuhkan pergerakan watak yang tepat dan mantap
  • lebih rumit untuk bekerjasama
  • mengambil lebih banyak kuasa pemprosesan daripada fizik mudah

Sudah tentu, terdapat juga banyak pro untuk menggunakan enjin fizik luar, seperti dapat membuat interaksi fizik kompleks dengan mudah, tetapi itu bukan apa yang kita perlukan untuk permainan kami.

Enjin fizik tersuai membantu permainan untuk merasakan adat, dan itu sangat penting! Walaupun anda akan memulakan dengan persediaan yang agak asas, cara di mana perkara akan bergerak dan berinteraksi antara satu sama lain akan sentiasa dipengaruhi oleh peraturan anda sendiri, bukannya orang lain. Mari kita dapatkannya!

Bounds Watak

Mari kita mulakan dengan menentukan jenis bentuk yang akan kita gunakan dalam fizik kita. Salah satu bentuk yang paling asas yang boleh kita gunakan untuk mewakili objek fizikal dalam permainan adalah Kotak Border Axis Aligned (AABB). AABB pada asasnya adalah segi empat yang tidak dilindungi.

Example of an AABB

Dalam banyak permainan platformer, AABBs cukup untuk menghampiri badan setiap objek dalam permainan. Mereka sangat berkesan, kerana sangat mudah untuk mengira pertindihan antara AABB dan memerlukan sedikit data-untuk menggambarkan AABB, cukup untuk mengetahui pusat dan ukurannya.

Tanpa berlengah lagi, mari kita buat struct untuk AABB kami.

Seperti yang dinyatakan sebelum ini, semua yang kita perlukan di sini sejauh data yang berkenaan adalah dua vektor; yang pertama akan menjadi pusat AABB, dan yang kedua adalah saiz separuh. Mengapa saiz separuh? Kebanyakan masa untuk pengiraan kami memerlukan separuh saiz, jadi bukannya mengira setiap kali kami hanya menghafafnya bukan saiz penuh.

Mari bermula dengan menambah pembina, jadi mungkin untuk membuat struct dengan parameter tersuai.

Dengan ini kita boleh membuat fungsi pemeriksaan perlanggaran. Mula-mula, mari buat pemeriksaan mudah sama ada dua AABBs bertembung antara satu sama lain. Ini sangat mudah-kita hanya perlu melihat sama ada jarak antara pusat pada setiap paksi kurang daripada jumlah separuh saiz.

Berikut adalah gambar yang menunjukkan pemeriksaan ini pada paksi x; paksi y diperiksa dengan cara yang sama.

Demonstrating a check on the X-Axis

Seperti yang anda dapat lihat, jika jumlah separuh saiz lebih kecil daripada jarak antara pusat, tiada pertindihan yang mungkin. Perhatikan bahawa dalam kod di atas, kita dapat melarikan diri dari pemeriksaan perlanggaran lebih awal jika kita mendapati bahawa objek tidak bertindih pada paksi pertama. Pertindihan mesti ada pada kedua-dua paksi, jika AABBs akan bertembung dalam ruang 2D.

Objek Bergerak

Mari kita mulakan dengan membuat kelas untuk objek yang dipengaruhi oleh fizik permainan. Kemudian, kami akan menggunakan ini sebagai pangkalan untuk objek pemain sebenar. Mari kita panggil MovingObject kelas ini.

Sekarang mari kita isi kelas ini dengan data. Kami akan memerlukan banyak maklumat untuk objek ini:

  • Posisi dan Kedudukan bingkai sebelumnya
  • kelajuan dan kelajuan bingkai sebelumnya
  • skala
  • AABB dan offset untuk itu (supaya kita dapat menyelaraskannya dengan sprit)
  • adalah objek di atas tanah dan sama ada ia berada di kerangka terakhir tanah
  • adalah objek di sebelah dinding di sebelah kiri dan sama ada di sebelahnya bingkai terakhir
  • adalah objek di sebelah dinding di sebelah kanan dan sama ada di sebelahnya bingkai terakhir
  • adalah objek di siling dan sama ada di bingkai terakhir siling

Kedudukan, kelajuan dan skala adalah vektor 2D.

Sekarang mari kita tambahkan AABB dan mengimbangi. Offset diperlukan supaya kami boleh melawan AABB secara bebas untuk sprite objek.

Dan akhirnya, mari kita mengisytiharkan pemboleh ubah yang menunjukkan keadaan kedudukan objek, sama ada di atas tanah, di sebelah dinding atau di siling. Ini sangat penting kerana mereka akan memberitahu kami sama ada kita boleh melompat atau, sebagai contoh, perlu memainkan bunyi selepas menabrak tembok.

Ini adalah asas-asas. Sekarang, mari buat fungsi yang akan mengemas kini objek. Buat masa sekarang kita tidak akan menetapkan segala-galanya, tetapi hanya cukup supaya kita boleh mula mewujudkan kawalan watak asas.

Perkara pertama yang akan kami lakukan di sini adalah untuk menyimpan data bingkai sebelumnya kepada pembolehubah yang sesuai.

Kini mari kita kemas kini kedudukan menggunakan kelajuan semasa.

Dan hanya untuk sekarang, mari kita buatkan supaya jika kedudukan menegak kurang daripada sifar, kita menganggap watak itu di atas tanah. Ini hanya untuk masa sekarang, jadi kami boleh menetapkan kawalan watak. Kemudian, kami akan melakukan perlanggaran dengan tilemap.

Selepas ini, kita perlu juga mengemas kini pusat AABB, jadi ia sebenarnya sepadan dengan kedudukan baru.

Untuk projek demo, saya menggunakan Perpaduan, dan untuk mengemas kini kedudukan objek yang perlu diterapkan pada komponen transformasi, jadi mari lakukan itu juga. Perkara yang sama perlu dilakukan untuk skala.

Seperti yang dapat anda lihat, kedudukan yang diberikan adalah bulat. Ini adalah untuk memastikan watak yang diberikan sentiasa digegarkan pada piksel.

Kawalan Watak

Data

Sekarang bahawa kami mempunyai kelas MovingObject asas kami, kita boleh mula dengan bermain dengan pergerakan watak. Ia adalah bahagian yang sangat penting dari permainan ini, selepas semua, dan boleh dilakukan cukup lama-tidak perlu untuk menyelidiki terlalu jauh ke dalam sistem permainan baru lagi, dan ia akan siap apabila kita perlu menguji watak kita- pelanggaran peta.

Pertama, mari kita buat kelas Character dan dapatkannya dari kelas MovingObject.

Kita perlu mengendalikan beberapa perkara di sini. Pertama sekali, input-mari kita buat enum yang akan merangkumi semua kawalan untuk watak itu. Mari buat dalam fail lain dan sebut sebagai KeyInput.

Seperti yang dapat anda lihat, watak kita boleh bergerak ke kiri, kanan, bawah dan melompat. Bergerak hanya akan berfungsi pada platform sehala, apabila kita mahu jatuh melalui mereka.

Sekarang mari kita mengisytiharkan dua array dalam kelas Watak, satu untuk input bingkai semasa dan satu lagi untuk bingkai sebelumnya. Bergantung pada permainan, persediaan ini mungkin membuat rasa lebih atau kurang. Biasanya, bukannya menyimpan keadaan utama pada tatasusunan, ia diperiksa mengikut permintaan menggunakan fungsi khusus enjin atau rangka kerja. Walau bagaimanapun, mempunyai tatasusunan yang tidak terikat dengan input nyata boleh memberi manfaat, jika misalnya kita mahu mensimulasikan penekan utama.

Array ini akan diindeks oleh enum KeyInput. Untuk menggunakan array ini dengan mudah, mari kita buat beberapa fungsi yang akan membantu kita menyemak kunci tertentu.

Tidak ada yang istimewa di sini — kami ingin dapat melihat apakah kunci hanya ditekan, baru dirilis, atau jika tombolnya aktif atau tidak aktif.

Sekarang mari kita buat enum lain yang akan memegang semua keadaan yang mungkin watak itu.

Seperti yang dapat anda lihat, watak kita boleh berdiri tegak, berjalan, melompat, atau merebut langkan. Sekarang ini, kita perlu menambah pemboleh ubah seperti kelajuan melompat, kelajuan berjalan, dan keadaan semasa.

Sudah tentu terdapat beberapa lagi data yang diperlukan di sini seperti sprite watak, tetapi bagaimana ini akan kelihatan bergantung kepada jenis enjin yang akan digunakan. Oleh kerana saya menggunakan Perpaduan, saya akan menggunakan rujukan kepada Animator untuk memastikan riang memainkan animasi untuk keadaan yang sesuai.

Kemas kini Gelung

Baiklah, sekarang kita boleh memulakan kerja pada gelung kemas kini. Apa yang akan kita lakukan di sini akan bergantung pada keadaan semasa watak itu.

Stand State

Mari bermula dengan mengisi apa yang perlu dilakukan apabila watak itu tidak bergerak-dalam keadaan pendirian. Pertama sekali, kelajuan harus ditetapkan kepada sifar.

Kami juga ingin menunjukkan sprit yang sesuai untuk negeri ini.

Sekarang, jika watak itu tidak di atas tanah, ia tidak boleh lagi berdiri, jadi kita perlu mengubah keadaan untuk melompat.

Sekiranya kunci GoLeft atau GoRight ditekan, maka kita perlu menukar keadaan kita untuk berjalan.

Sekiranya kunci Lompat ditekan, kami mahu menetapkan kelajuan menegak ke kelajuan lompat dan menukar keadaan untuk melompat.

Itu akan berlaku untuk negeri ini sekurang-kurangnya buat masa ini.

Walk State

Sekarang mari kita buat logik untuk bergerak di atas tanah, dan segera mula bermain animasi berjalan.

Di sini, jika kita tidak menekan butang kiri atau kanan atau kedua-duanya ditekan, kita mahu kembali ke keadaan tetap.

Sekiranya kunci GoRight ditekan, kita perlu menetapkan kelajuan mendatar ke mWalkSpeed ​​dan memastikan bahawa sprite dikecilkan dengan sewajarnya - skala mendatar perlu diubah jika kita mahu melipatkan sprit secara mendatar.

Kita juga harus bergerak hanya jika tidak ada hambatan di hadapan, jadi jika mPushesRightWall ditetapkan kepada benar, maka kelajuan mendatar harus ditetapkan kepada sifar jika kita bergerak ke kanan.

Kita juga perlu mengendalikan bahagian kiri dengan cara yang sama.

Seperti yang kita lakukan untuk keadaan berdiri, kita perlu melihat jika butang lompat ditekan, dan tetapkan kelajuan menegak jika itu begitu.

Jika tidak, jika watak itu tidak di atas tanah maka ia perlu mengubah keadaan untuk melompat juga, tetapi tanpa penambahan kelajuan menegak, maka ia hanya jatuh ke bawah.

Itu sahaja untuk berjalan. Mari kita bergerak ke keadaan lompat.

Jump State

Mari kita mulakan dengan menetapkan animasi yang sesuai untuk sprite.

Dalam keadaan Lompat, kita perlu menambah graviti kepada kelajuan watak, jadi ia berjalan lebih cepat dan lebih cepat ke arah tanah.

Tetapi akan masuk akal untuk menambah had, jadi watak itu tidak boleh jatuh terlalu cepat.

Dalam banyak permainan, apabila watak berada di udara, daya kendalian berkurangan, tetapi kami akan pergi untuk beberapa kawalan yang sangat mudah dan tepat yang membolehkan fleksibiliti penuh apabila di udara. Jadi, jika kita menekan kekunci GoLeft atau GoRight, watak bergerak ke arah sambil melompat secepatnya jika ia berada di atas tanah. Dalam kes ini kita boleh menyalin logik pergerakan dari keadaan berjalan.

Akhirnya, kami akan membuat lompat lebih tinggi jika butang lompat ditekan lebih lama. Untuk melakukan ini, apa yang sebenarnya akan kita lakukan adalah melompat lebih rendah jika butang melompat tidak ditekan.

Sekarang, mari buat fungsi yang akan mengemas kini objek.Seperti yang anda dapat lihat, jika kunci melompat tidak ditekan dan kelajuan menegak adalah positif, maka kami mengepam laju ke nilai maksimum cMinJumpSpeed ​​(200 piksel per saat). Ini bermakna bahawa jika kita hanya menekan butang lompat, kelajuan lompat, bukannya sama dengan mJumpSpeed ​​(410 secara lalai), akan turun ke 200, dan oleh itu lompat akan menjadi lebih pendek.

Oleh kerana kita tidak mempunyai sebarang geometri peringkat lagi, kita harus melangkau pelaksanaan GrabLedge untuk sekarang.

Kemas kini Input Terdahulu

Setelah selesai selesai, kami boleh mengemas kini input sebelumnya. Mari buat fungsi baru untuk ini. Apa yang perlu kita lakukan di sini adalah menggerakkan nilai-nilai keadaan utama dari array mInputs ke array mPrevInputs.

Pada akhir fungsi CharacterUpdate, kita masih perlu melakukan beberapa perkara. Yang pertama adalah untuk mengemaskini fizik.

Sekarang fizik dikemas kini, kita dapat melihat sama ada kita perlu memainkan sebarang bunyi. Kami ingin memainkan suara ketika karakter menabrak permukaan apa saja, tetapi saat ini hanya dapat menyentuh tanah karena tabrakan dengan tilemap belum diimplementasikan.

Mari kita periksa sama ada watak itu baru jatuh ke tanah. Ia sangat mudah untuk melakukannya dengan persediaan semasa-kita hanya perlu mencari jika wataknya berada di tanah sekarang, tetapi tidak berada di dalam bingkai sebelumnya.

Akhirnya, mari kita kemas kini input sebelumnya.

Secara keseluruhannya, ini adalah bagaimana fungsi CharacterUpdate perlu dilihat sekarang, dengan perbezaan kecil bergantung pada jenis enjin atau kerangka yang anda gunakan.

Init the Character

Mari tulis fungsi Init untuk watak itu. Fungsi ini akan mengambil array input sebagai parameter. Kami akan membekalkan ini dari kelas pengurus di kemudian hari. Selain itu, kita perlu melakukan perkara-perkara seperti:

  • tetapkan skala
  • tetapkan kelajuan melompat
  • menetapkan kelajuan berjalan kaki
  • tetapkan kedudukan awal
  • tetapkan AABB

Kami akan menggunakan beberapa pemalar yang ditakrifkan di sini.

Dalam hal demo, kita dapat menetapkan kedudukan awal ke posisi dalam editor.

Untuk AABB, kita perlu menetapkan setimbang dan separuh saiz. Diimbangi dalam kes sprit demo perlu hanya separuh saiz.

Sekarang kita dapat menjaga kebolehubahkan selebihnya.

Kita perlu memanggil fungsi ini dari pengurus permainan. Pengurus boleh diatur dalam banyak cara, semua bergantung pada alat yang anda gunakan, tetapi secara umum idea itu sama. Dalam haba pengurus, kita perlu membuat array input, membuat pemain, dan initkannya.

Di samping itu, dalam kemas kini pengurus, kita perlu mengemas kini input pemain dan pemain.

Ambil perhatian bahawa kami mengemas kini fizik watak dalam kemas kini tetap. Ini akan memastikan bahawa lompatan akan sentiasa menjadi ketinggian yang sama, tidak kira berapa kadar bingkai permainan kami berfungsi dengan. Ada satu artikel yang sangat baik oleh Glenn Fiedler mengenai bagaimana menetapkan waktu tamat, sekiranya anda tidak menggunakan Perpaduan.

Uji Pengawal Watak

Pada ketika ini kita dapat menguji pergerakan watak dan melihat bagaimana perasaannya. Sekiranya kita tidak menyukainya, kita sentiasa boleh menukar parameter atau cara kelajuan diubah apabila menekan kekunci.

An animation of the character controller

Ringkasan

Kawalan watak mungkin kelihatan sangat tidak berminat dan bukan semudah pergerakan berasaskan momentum bagi sesetengah orang, tetapi ini semua adalah perkara jenis kawalan yang sesuai dengan permainan terbaik anda. Nasib baik, hanya mengubah cara bergerak watak agak mudah; ia cukup untuk mengubah suai bagaimana perubahan kelajuan berubah dalam keadaan berjalan dan melompat.

Itu sahaja untuk bahagian pertama siri ini. Kami telah berakhir dengan skim gerakan watak yang mudah, tetapi tidak banyak lagi. Perkara yang paling penting ialah kami meletakkan jalan untuk bahagian seterusnya, di mana kami akan membuat watak itu berinteraksi dengan tilemap.

Advertisement
Advertisement
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.