45 ° Lereng dalam platformer 2D berbasis Tile

12

Saya ingin memiliki kemiringan 45 ° sederhana di platformer berbasis ubin saya, namun saya sepertinya tidak bisa menurunkan algoritme. Silakan lihat kode dan videonya, mungkin saya kehilangan yang jelas?

//collisionRectangle is the collision rectangle of the player with 
//origin at the top left and width and height
//wantedPosition is the new position the player will be set to.
//this is determined elsewhere by checking the bottom center point of the players rect
if(_leftSlope || _rightSlope)
{        
    //Test bottom center point
    var calculationPoint = new Vector2(collisionRectangle.Center.X, collisionRectangle.Bottom);
    //Get the collision rectangle of the tile, origin is top-left
    Rectangle cellRect =
        _tileMap.CellWorldRectangle(
            _tileMap.GetCellByPixel(calculationPoint));
    //Calculate the new Y coordinate depending on if its a left or right slope
    //CellSize = 8
    float newY = _leftSlope
                            ? (calculationPoint.X % CellSize) + cellRect.Y
                            : (-1 * (calculationPoint.X % CellSize) - CellSize) + cellRect.Y;
    //reset variables so we dont jump in here next frame
    _leftSlope = false;
    _rightSlope = false;
    //now change the players Y according to the difference of our calculation
    wantedPosition.Y += newY - calculationPoint.Y;
}

Video seperti apa: http://youtu.be/EKOWgD2muoc

xNidhogg
sumber
1
Bukankah Vektor hebat? : D
Gustavo Maciel

Jawaban:

10

Dari apa yang saya mengerti membaca pertanyaan Anda, Anda ingin menghitung Yposisi yang benar , diberi Xposisi pemain. Ini agak sepele. Lihatlah gambar ini:

lereng

Dengan anggapan slope-tile Anda berada pada posisi tertentu x,y(asal berada di kiri bawah seperti pada gambar). Anda memiliki posisi pemain x1dan lebar serta tinggi ubin yang miring ( u, v). x, ydan x1merupakan koordinat dunia.

Dengan parameter ini, posisi Y pemain Anda ( y1) adalah:

y1 = y + (x1 - x) * (v / u)

Jika Anda hanya berurusan dengan sudut 45 derajat, maka akan semakin mudah:

y1 = y + (x1 - x)

Jika kemiringan adalah sebaliknya, itu adalah:

y1 = y + (v - (x1 - x))
bummzack
sumber
setelah menerapkan perbaikan @SkimFlux plus formular baru Anda dan beberapa hal bodoh yang saya abaikan ternyata berhasil. Terima kasih.
xNidhogg
Tidak bisakah Anda menggunakan y = mx + b untuk perhitungan yang lebih sederhana?
ashes999
@ ashes999 Saya tidak berpikir itu menjadi lebih sederhana dari apa yang saya tulis. Apa yang ada mdan bdalam perhitungan Anda?
bummzack
@bummzack m adalah kemiringan Anda (1 untuk kemiringan 45 derajat ke bawah, -1 untuk ke atas) dan b akan menjadi intersep pada sumbu x. Aljabar kelas 9. Katakan saja.
ashes999
@ ashes999 Ya sudah lama. Jangan ragu untuk memposting persamaan ini sebagai jawaban.
bummzack
8

Meskipun ini sudah dijawab, izinkan saya untuk menawarkan persamaan lain:, di y = mx + bmana y adalah koordinat yang dihitung, m adalah kemiringan (-1 untuk turun pada 45 derajat, 1 untuk naik pada 45 derajat), dan b adalah penyadapan y - - koordinat y tempat x = 0.

Ini memungkinkan Anda sedikit lebih fleksibel; Anda dapat mengubah m untuk menghitung kemiringan berbeda selain 45 derajat. Misalnya, m pi / 3 memberi Anda kemiringan 30 derajat.

ashes999
sumber
4

Anda dapat menemukan banyak nilai di situs ini: http://info.sonicretro.org/Sonic_Physics_Guide

Khusus untuk apa yang Anda cari, lihat bagian Solid Tiles: Slopes and Curves. Ini pada dasarnya menunjukkan kepada Anda bagaimana hal ini diyakini dilakukan dalam permainan Sonic awal.

Spartan Donut
sumber
baca menarik, tapi terlalu rumit. Kemiringan seperti ini adalah satu-satunya yang saya inginkan, sehingga harus menyederhanakan solusinya. Sistem pemetaan / sensor / pemindai ketinggian akan terlalu banyak untuk ini. Terima kasih telah menggali tautannya.
xNidhogg
2

Anda mungkin ingin melihat ke dalam The Seperate Axis Theorm, Ini akan menyelesaikan masalah kemiringan Anda, tetapi itu membutuhkan cukup banyak matematika dan teorinya sendiri membutuhkan waktu untuk menyelesaikan masalah Anda. Saya telah menautkan Anda dengan tutorial dan buku yang menjelaskannya dengan lebih baik

Tutorial metanetsoftware

Real-Time-Collision-Detection

dbomb101
sumber
itu terlalu banyak, imo. Ini adalah kasus yang sangat disederhanakan dan tidak perlu menggunakan SAT lainnya. Terima kasih telah meluangkan waktu untuk membuka tautan.
xNidhogg
2

Saya pikir Anda memiliki kesalahan off-by-one di tempat lain, atau Anda tidak mengatur flag _leftSlope / _rightSlope pada waktu yang tepat. Kode ini tidak menyentuh gerakan X sama sekali, tetapi itu tampaknya menjadi masalah Anda dalam video.

Anda harus memeriksa apakah flag-flag itu dipicu sama sekali. Kemudian periksa deteksi tabrakan horizontal Anda: Anda tidak ingin itu memicu pada kemiringan.

SkimFlux
sumber
oh tuhan benar. Saya sebenarnya tidak ingin deteksi tabrakan horizontal atau vertikal ketika ini terjadi. Saya benar-benar lupa menonaktifkannya. Terlihat lebih baik sekarang, tapi belum selesai. Terima kasih.
xNidhogg