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

Cara Buat Enjin Fizik 2D Kustom: Geseran, Pemandangan dan Jadual Lompat

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called How to Create a Custom Physics Engine.
How to Create a Custom 2D Physics Engine: The Core Engine
How to Create a Custom 2D Physics Engine: Oriented Rigid Bodies

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

Dalam dua tutorial pertama dalam siri ini, saya membincangkan topik Impulse Resolution dan Architecture Core. Kini sudah tiba masanya untuk menambah pada beberapa sentuhan akhir untuk enjin fizik berasaskan 2D, kami.

Topik yang akan kita lihat dalam artikel ini ialah:

  • Geseran
  • Adegan
  • Jadual Jumping Collision

Saya amat mengesyorkan membaca pada dua artikel sebelumnya dalam siri ini sebelum cuba mengatasi masalah ini. Beberapa maklumat penting dalam artikel sebelumnya dibina di dalam artikel ini.

Nota: Walaupun tutorial ini ditulis menggunakan C++, anda harus dapat menggunakan teknik dan konsep yang sama dalam hampir semua persekitaran pembangunan permainan.


Demo Video

Inilah demo cepat tentang apa yang sedang kita lakukan di bahagian ini:


Geseran

Geseran adalah sebahagian daripada resolusi perlanggaran. Geseran sentiasa menggunakan daya ke atas objek dalam arah yang bertentangan dengan gerakan yang mereka hendak bepergian.

Dalam kehidupan sebenar, geseran adalah interaksi yang sangat kompleks antara bahan-bahan yang berlainan, dan untuk memodelinya, andaian dan perkiraan yang luas dibuat. Andaian ini tersirat dalam matematik, dan biasanya sesuatu seperti "geseran boleh dihampiri oleh vektor tunggal" - sama seperti bagaimana dinamik badan tegar menyerupai interaksi kehidupan sebenar dengan menganggap badan dengan ketumpatan seragam yang tidak boleh ubah bentuk.

Lihatlah pantas demo video dari artikel pertama dalam siri ini:

Interaksi antara badan agak menarik, dan melantun semasa perlanggaran terasa realistis. Walau bagaimanapun, sebaik sahaja objek berada di atas platform padat, mereka hanya semata-mata menekan dan melepaskan tepi skrin. Ini disebabkan kekurangan simulasi geseran.

Impuls, Lagi?

Seperti yang anda harus ingat dari artikel pertama dalam siri ini, nilai tertentu, j, mewakili magnitud dorongan yang diperlukan untuk memisahkan dua penembusan objek semasa perlanggaran. Magnitud ini boleh dirujuk sebagai jnormal atau jN kerana ia digunakan untuk mengubah suai halaju di sepanjang perlanggaran normal.

Menggabungkan tindak balas geseran melibatkan pengiraan magnitud yang lain, yang disebut jtangent atau jT. Geseran akan dimodelkan sebagai dorongan. Magnitud ini akan mengubah halaju sesuatu objek sepanjang vektor tangen negatif pelanggaran, atau dengan kata lain di sepanjang vektor geseran. Dalam dua dimensi, penyelesaian untuk vektor geseran ini adalah masalah yang dapat diselesaikan, tetapi dalam 3D masalah menjadi lebih kompleks.

Geseran agak mudah, dan kita boleh menggunakan persamaan sebelumnya untuk j, kecuali kita akan menggantikan semua keadaan n normal dengan vektor tangen t.

\[Persamaan 1:\\
j = \frac{-(1 + e)(V^{B}-V^{A})\cdot n)}
{\frac{1}{mass^A} + \frac{1}{mass^B}}\]

Replace n with t:

\[ Equation 2:\\
j = \frac{-(1 + e)((V^{B}-V^{A})\cdot t)}
{\frac{1}{mass^A} + \frac{1}{mass^B}}\]

Walaupun hanya satu contoh n digantikan dengan t dalam persamaan ini, sekali putaran diperkenalkan beberapa lagi contoh mesti digantikan selain satu tunggal dalam pengangka Persamaan 2.

Sekarang perkara bagaimana mengira t timbul. Vektor tangen adalah vektor berserenjang dengan tabrakan yang normal yang menghadap ke arah normal. Ini mungkin membingungkan - jangan risau, saya mempunyai rajah!

Di bawah ini anda dapat melihat vektor tangen berserenjang dengan normal. Vektor tangen boleh menunjuk ke kiri atau kanan. Di sebelah kiri akan "lebih jauh" dari halaju relatif. Walau bagaimanapun, ia ditakrifkan sebagai tegak lurus dengan normal yang menunjuk "lebih ke arah" halaju relatif.

Vectors of various types within the timeframe of a collision of rigid bodies.
Vektor pelbagai jenis dalam jangka masa perlanggaran badan-badan yang tegar.

Sebagaimana yang dinyatakan sebelum ini, geseran akan menjadi vektor yang bertentangan dengan vektor tangen. Ini bermakna arah untuk memohon geseran boleh dikira secara langsung, kerana vektor normal dijumpai semasa pengesanan perlanggaran.

Mengetahui ini, vektor tangen adalah (di mana n adalah perlanggaran biasa):

\[ V^R = V^{B}-V^{A} \\
t = V^R - (V^R \cdot n) * n \]

Semua yang ditinggalkan untuk menyelesaikan jt, magnitud geseran, adalah untuk mengira nilai secara langsung menggunakan persamaan di atas. Terdapat beberapa kepingan yang sangat rumit selepas nilai ini dihitung yang akan dilindungi seketika, jadi ini bukan perkara terakhir yang diperlukan dalam pelarut perlanggaran kami:

Kod di atas mengikuti Persamaan 2 secara langsung. Sekali lagi, adalah penting untuk menyedari bahawa titik vektor geseran menunjukkan arah yang bertentangan dengan vektor tangen kami, dan oleh itu kita mesti memohon tanda negatif apabila kita mengetengahkan halaju relatif sepanjang tangen untuk menyelesaikan halaju relatif di sepanjang vektor tangen. Tanda negatif ini mengalir halaju tangen dan tiba-tiba menunjuk ke arah di mana geseran sepatutnya dianggarkan sebagai.

Undang-undang Coulomb

Undang-undang Coulomb adalah sebahagian daripada simulasi geseran yang kebanyakan masalah dalam programmer. Saya sendiri terpaksa melakukan sedikit kajian untuk mengetahui cara pemodelan yang betul. Caranya ialah undang-undang Coulomb adalah ketidaksamaan.

Geseran Coulomb menyatakan:

\[Persamaan 3:\\
F_f <= \mu F_n \]

Dengan kata lain, daya geseran sentiasa kurang daripada atau sama dengan gaya normal yang didarab dengan beberapa malar μ (yang nilai bergantung kepada bahan objek).

Daya biasa hanya magnitud j lama kami didarab dengan perlanggaran normal. Oleh itu, jika jt yang kita selesaikan (mewakili kekuatan geseran) adalah kurang daripada μ kali gaya normal, maka kita boleh menggunakan magnitud jt kita sebagai geseran. Sekiranya tidak, maka kita mesti menggunakan kuasa kali μ sebaliknya. Kes "lain" ini adalah satu bentuk pengikisan pergeseran geseran kita di bawah nilai maksima, max ialah masa berkekuatan normal μ.

Seluruh undang-undang Coulomb adalah untuk melaksanakan prosedur penjepit ini. Penjepit ini ternyata adalah bahagian yang paling sukar simulasi geseran untuk resolusi berdasarkan impuls untuk mencari dokumentasi di mana-mana - sehingga sekarang, sekurang-kurangnya! Kebanyakan kertas putih yang saya dapati mengenai subjek sama ada geseran yang dilangkau sepenuhnya, atau menghentikan prosedur pengekodan yang tidak betul (atau tidak ada) yang pendek dan dilaksanakan. Semoga sekarang anda mempunyai penghargaan untuk memahami bahawa mendapatkan hak ini penting.

Membolehkan hanya memasak mengepel semua dalam satu pergi sebelum menjelaskan apa-apa. Blok kod berikutnya adalah contoh kod sebelumnya dengan prosedur penjepit selesai dan aplikasi dedik geseran bersama-sama:

Saya memutuskan untuk menggunakan formula ini untuk menyelesaikan pekali geseran di antara dua badan, diberi pekali untuk setiap badan:

\[Persamaan 4: \\
Geseran = \sqrt [] {Friction ^ 2_A + Friction ^ 2_B}\]

Saya sebenarnya melihat orang lain melakukannya dalam enjin fizik mereka sendiri, dan saya suka hasilnya. Rata-rata kedua nilai akan berfungsi dengan baik untuk menyingkirkan penggunaan akar kuadrat. Sebenarnya, apa-apa bentuk memilih pekali geseran akan berfungsi; ini adalah apa yang saya lebih suka. Pilihan lain adalah dengan menggunakan jadual carian di mana jenis setiap badan digunakan sebagai indeks ke dalam jadual 2D.

Adalah penting bahawa nilai mutlak jt digunakan dalam perbandingan, kerana perbandingan secara teorinya mengetatkan magnitud mentah di bawah beberapa ambang. Oleh kerana j sentiasa positif, ia mesti dibalikkan untuk mewakili vektor geseran yang sesuai, dalam hal geseran dinamik digunakan.

Gangguan statik dan dinamik

Dalam coretan kod terakhir coretan statik dan dinamik diperkenalkan tanpa sebarang penjelasan! Saya akan mendedikasikan keseluruhan bahagian ini untuk menjelaskan perbezaan antara dan keperluan kedua-dua jenis nilai tersebut.

Sesuatu yang menarik berlaku dengan geseran: ia memerlukan "tenaga pengaktifan" agar benda-benda mula bergerak ketika rehat lengkap. Apabila dua benda berada di atas satu sama lain dalam kehidupan sebenar, ia mengambil sejumlah tenaga yang cukup untuk menolak satu dan mendapatkannya bergerak. Walau bagaimanapun, apabila anda mendapatkan sesuatu yang tergelincir, ia sering lebih mudah untuk mengekalkannya dari semasa ke semasa.

Ini adalah kerana bagaimana geseran berfungsi pada tahap mikroskopik. Gambar lain membantu di sini:

Microscopic view of what causes energy of activation due to friction.
Pandangan mikroskopis tentang apa yang menyebabkan tenaga pengaktifan akibat geseran.

Seperti yang anda lihat, kecacatan kecil di antara permukaan benar-benar punca utama yang menyebabkan geseran di tempat pertama. Apabila satu objek berada di atas yang lain, kecacatan mikroskopik terletak di antara objek, bersambung. Ini perlu dipecahkan atau dipisahkan agar objek berselerak antara satu sama lain.

Kami memerlukan satu cara untuk model ini di dalam enjin kami. Satu penyelesaian yang mudah adalah untuk menyediakan setiap jenis bahan dengan dua nilai geseran: satu untuk statik dan satu untuk dinamik.

Geseran statik digunakan untuk mengapit magnitud jt kami. Jika magnitud jt yang diselesaikan cukup rendah (di bawah ambang kita), maka kita boleh menganggap objek itu sedang berehat, atau hampir sebagai rehat dan menggunakan keseluruhan jt sebagai dorongan.

Pada flipside, jika jt yang diselesaikan di atas ambang, boleh diandaikan bahawa objek telah memecahkan "tenaga pengaktifan", dan dalam keadaan sedemikian dedik geseran yang lebih rendah digunakan, yang diwakili oleh pekali geseran yang lebih kecil dan pengiraan impuls yang sedikit berbeza.


Adegan

Dengan mengandaikan anda tidak melangkau mana-mana bahagian Bahagian Geseran, dilakukan dengan baik! Anda telah menyelesaikan bahagian paling sukar dalam keseluruhan siri ini (pada pandangan saya).

Kelas Scene bertindak sebagai wadah untuk semua yang melibatkan senario simulasi fizik. Ia memanggil dan menggunakan keputusan mana-mana fasa yang luas, mengandungi semua badan yang tegar, menjalankan pemeriksaan perlanggaran dan resolusi panggilan. Ia juga mengintegrasikan semua objek hidup. Adegan ini juga antara muka dengan pengguna (seperti dalam programmer menggunakan enjin fizik).

Berikut adalah contoh struktur bayangan seperti mana:

Tidak ada apa-apa yang rumit tentang kelas Scene. Idea ini adalah untuk membolehkan pengguna menambah dan membuang badan yang tegar dengan mudah. BodyDef adalah struktur yang memegang semua maklumat tentang badan yang tegar, dan boleh digunakan untuk membolehkan pengguna menyisipkan nilai sebagai sejenis struktur konfigurasi.

Fungsi penting lain ialah Langkah(). Fungsi ini melakukan pemeriksaan, resolusi dan integrasi pusingan tunggal. Ini harus dipanggil dari dalam gelung timestepping yang digariskan dalam artikel kedua siri ini.

Meminta titik atau AABB melibatkan pemeriksaan untuk melihat objek mana yang sebenarnya bertabrakan dengan sama ada penunjuk atau AABB di tempat kejadian. Ini menjadikannya mudah untuk logik berkaitan permainan untuk melihat bagaimana sesuatu diletakkan di dalam dunia.


Lompat Jadual

Kita memerlukan cara yang mudah untuk memilih fungsi tabrakan yang harus dipanggil, berdasarkan jenis dua objek yang berbeza.

Di C ++ terdapat dua cara utama yang saya ketahui: penghantaran dua kali dan jadual melompat 2D. Dalam ujian peribadi saya, saya dapati jadual lompat 2D untuk unggul, jadi saya akan terperinci mengenai cara untuk melaksanakannya. Jika anda bercadang untuk menggunakan bahasa selain C atau C ++ saya pasti pelbagai fungsi atau objek functor boleh dibina sama seperti jadual fungsi fungsi (yang merupakan sebab lain saya memilih untuk bercakap tentang melompat jadual bukan pilihan lain yang lebih khusus untuk C ++).

Jadual lompat dalam C atau C ++ ialah jadual fungsi fungsi. Indeks yang mewakili nama atau pemalar sewenang-wenang digunakan untuk mengindeks ke dalam jadual dan memanggil fungsi tertentu. Penggunaannya boleh kelihatan seperti ini untuk jadual lompat 1D:

Kod di atas sebenarnya meniru apa bahasa C ++ sendiri melaksanakan dengan panggilan fungsi dan warisan maya. Walau bagaimanapun, C ++ hanya melaksanakan panggilan maya dimensi tunggal. Jadual 2D boleh dibina dengan tangan.

Berikut adalah beberapa psuedocode untuk jadual melompat 2D untuk memanggil rutin perlanggaran:

Dan di sana kita memilikinya! Jenis sebenar setiap collider boleh digunakan untuk indeks ke dalam array 2D dan memilih fungsi untuk menyelesaikan perlanggaran.

Walau bagaimanapun, perhatikan bahawa AABBvsCircle dan CirclevsAABB adalah hampir pendua. Ini perlu! Yang normal perlu dibalikkan untuk salah satu daripada kedua-dua fungsi ini, dan itulah satu-satunya perbezaan di antara mereka. Ini membolehkan resolusi perlanggaran yang konsisten, tidak kira kombinasi objek untuk diselesaikan.


Kesimpulan

Kini, kami telah membincangkan topik yang banyak dalam menubuhkan sebuah enjin fizik badan yang tegar sepenuhnya dari awal! Resolusi perlanggaran, geseran, dan seni bina enjin adalah semua tajuk yang telah dilindungi setakat ini. Enjin fizik yang berjaya sepenuhnya sesuai untuk banyak permainan dimensi dua dimensi boleh dibina dengan pengetahuan yang dibentangkan dalam siri ini setakat ini.

Looking ahead ke masa depan, saya merancang untuk menulis satu lagi artikel yang dikhaskan sepenuhnya kepada ciri yang sangat diingini: putaran dan orientasi. Objek berorientasikan adalah sangat menarik untuk menonton berinteraksi antara satu sama lain, dan merupakan bahagian terakhir yang memerlukan enjin fizik khusus kami.

Resolusi putaran ternyata agak mudah, walaupun pengesanan perlanggaran mengambil hit dalam kerumitan. Nasib baik sehingga masa depan, dan sila tanya soalan atau hantar komen di bawah!

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.