Oke, jadi ini adalah masalah yang saya coba cari beberapa waktu. Mine adalah gim platformer 2D dengan dunia yang terdiri dari (biasanya) ubin bergerak dan sprite seluler, keduanya menggunakan AABBs untuk mewakili hitbox mereka. Game ini BUKAN berbasis grid karena beberapa komplikasi dengan memindahkan lapisan ubin.
Saya dapat mendeteksi tabrakan dan dengan mudah mengetahui kedalaman tabrakan. Saya menggunakan "metode poros dangkal" untuk menentukan cara untuk menyelesaikan tabrakan antara sprite dan ubin. Jika sprite lebih dalam secara horizontal daripada vertikal, arah penyelesaiannya adalah naik atau turun. Jika sprite lebih dalam secara vertikal daripada horizontal, arah penyelesaiannya adalah kiri atau kanan.
Ini cukup sederhana, dan itu bekerja dengan cukup baik. Yaitu, sampai Anda memiliki sprite bertabrakan dengan lebih dari satu ubin. Karena, menurut sifatnya, setiap tabrakan harus diperiksa secara terpisah, tabrakan yang berbeda mungkin memiliki arah yang berbeda untuk diselesaikan. Sebagai contoh, jika sprite mencoba berjalan melintasi deretan ubin, untuk satu bingkai mereka akan memotong ubin berikutnya seperti bahwa kedalaman horizontal lebih pendek daripada kedalaman vertikal. Ketika tabrakan mengatakan "tekad ke kiri", itu akan didorong kembali dan akan macet di sudut.
Saya telah merenungkan masalah ini berulang-ulang, untuk beberapa waktu, dan beberapa solusi telah datang kepada saya, tetapi semua memiliki kekurangan. Saya bisa menandai sisi-sisi tertentu sebagai tidak terjangkau, tetapi tanpa mesin berbasis grid, menentukan "tidak terjangkau" sangat rumit, terutama dengan memindahkan lapisan ubin selalu menjadi suatu kemungkinan.
Metode lain yang mungkin adalah memprediksi tumbukan sebelum terjadi dan "mengembalikan" gerakan ke titik tumbukan, saya kira, tapi saya tidak yakin bagaimana perhitungannya.
Saya merasa bahwa saya kehilangan sesuatu yang sangat jelas, terutama karena permainan dari tahun 80an telah menyelesaikan masalah ini.
Jawaban:
Masalah
Masalahnya terletak pada metode resolusi tabrakan Anda. Metode Anda berjalan sebagai berikut:
Masalah dengan ini, adalah bahwa ia dapat dengan mudah menggerakkan pemain ke arah yang salah. Anda dapat melihat bagaimana ini dapat terjadi pada gambar di bawah:
Karena pemain bergerak ke kanan, dan berada di atas tanah, Anda akan mengharapkan pemain untuk mendarat di atas tanah (dengan kotak hijau). Tetapi sebaliknya, ia didorong keluar dari tanah ke kiri (diwakili oleh kotak merah). Ini bisa menjadi masalah jika pemain mencoba untuk melompat dari satu platform ke platform lain, karena pemain mungkin akhirnya jatuh ke kematiannya karena kode tabrakan yang buruk.
Solusinya
Solusi untuk masalah ini sebenarnya cukup sederhana. Alih-alih menggunakan metode di atas, Anda menyelesaikan tabrakan seperti:
Sekarang saya harap Anda tidak membuang kode cek kedalaman Anda, karena Anda masih akan membutuhkannya untuk langkah 3 dan 6.
Untuk menyelesaikan tabrakan antar ubin pada salah satu dari dua sumbu (setelah memindahkan pemain), Anda harus terlebih dahulu mendapatkan kedalaman tabrakan. Anda kemudian mengambil kedalaman tabrakan, dan kurangi itu dari sumbu yang saat ini Anda periksa untuk tabrakan. Perhatikan bahwa kedalamannya harus negatif jika Anda bergerak ke kiri, sehingga pemain bergerak ke arah yang benar.
Dengan menggunakan metode ini, Anda tidak hanya tidak perlu khawatir tentang bug tabrakan seperti yang ada dalam skenario pada gambar di atas, tetapi metode ini juga dapat menangani tabrakan dengan beberapa ubin.
Kode contoh:
sumber
float
s untuk menyimpan koordinat saya. Jadi itu menyebabkan getaran. Solusinya adalah memutari coord ketika saya selesai menyelesaikan tabrakan.Anda terlalu memikirkan masalah dan menggabungkan beberapa masalah. Tapi tidak apa-apa karena, seperti yang Anda katakan, ini adalah masalah yang sangat terselesaikan dengan banyak jawaban hebat di luar sana.
Mari kita jabarkan:
Tilemaps . Contoh pertama Anda adalah sprite yang berjalan melintasi sekelompok ubin yang diletakkan secara horizontal (atau meluncur ke bawah dinding ubin yang diletakkan secara vertikal, itu isomorfik). Salah satu solusi yang sangat elegan untuk ini adalah tidak memeriksa tepi ubin di mana kita tahu sprite tidak bisa, seperti tepi yang "bawah tanah" atau tepi yang membatasi ubin lain yang benar-benar padat.
Anda benar bahwa sprite akan turun karena gravitasi, lalu bergerak ke samping, lalu tersangkut ... tetapi jawabannya adalah tidak peduli dengan tepi kiri atau kanan ubin yang berada di bawah tanah . Dengan begitu, rutin resolusi tabrakan Anda hanya menggerakkan sprite secara vertikal - dan sprite Anda dapat berjalan dengan cara yang menyenangkan.
Lihatlah tutorial ubin Metanet untuk penjelasan langkah demi langkah tentang ini. Anda mengatakan dalam pertanyaan Anda bahwa Anda tidak menggunakan tilemap tradisional, tetapi tidak apa-apa juga: ubin statis ada di tilemap dan memperbarui seperti di atas, sambil memindahkan platform dan pembaruan seperti # 2 di bawah ini.
AABB lainnya . Anda hanya akan mengalami masalah jika, dalam satu frame, sprite Anda dapat memindahkan jarak yang lebih besar dari lebar / tinggi sebagian besar AABB di game Anda. Jika tidak bisa, berarti Anda emas: selesaikan tabrakan satu-persatu dan itu akan bekerja dengan baik.
Jika AABB dapat bergerak sangat cepat dalam satu bingkai maka Anda harus "menyapu" gerakan saat memeriksa tabrakan: potong gerakan menjadi fraksi yang lebih kecil dan periksa tabrakan pada setiap langkah.
sumber