Masalah deteksi tabrakan 2D berbasis ubin


8

Saya mencoba mengikuti tutorial ini http://www.tonypa.pri.ee/tbw/tut05.html untuk mengimplementasikan tabrakan real-time di dunia berbasis ubin.

Saya menemukan koordinat pusat entitas saya berkat properti ini:

public float CenterX
{
    get { return X + Width / 2f; }
    set { X = value - Width / 2f; }
}
public float CenterY
{
    get { return Y + Height / 2f; }
    set { Y = value - Height / 2f; }
}

Kemudian dalam metode pembaruan saya, di kelas pemain, yang disebut setiap frame, saya memiliki kode ini:

public override void Update()
{
    base.Update();

    int downY = (int)Math.Floor((CenterY + Height / 2f - 1) / 16f);
    int upY = (int)Math.Floor((CenterY - Height / 2f) / 16f);
    int leftX =     (int)Math.Floor((CenterX + Speed * NextX - Width / 2f) / 16f);
    int rightX = (int)Math.Floor((CenterX + Speed * NextX + Width / 2f - 1) / 16f);

    bool upleft = Game.CurrentMap[leftX, upY] != 1;
    bool downleft = Game.CurrentMap[leftX, downY] != 1;
    bool upright = Game.CurrentMap[rightX, upY] != 1;
    bool downright = Game.CurrentMap[rightX, downY] != 1;

    if(NextX == 1)
    {
        if (upright && downright)
           CenterX += Speed;
        else
           CenterX = (Game.GetCellX(CenterX) + 1)*16 - Width / 2f;
    }
 }

downY, upY, leftX dan rightX masing-masing harus menemukan posisi Y terendah, posisi Y tertinggi, posisi X paling kiri dan posisi X paling kanan. Saya menambahkan + Kecepatan * NextX karena dalam tutorial fungsi getMyCorners dipanggil dengan parameter ini:

getMyCorners (ob.x+ob.speed*dirx, ob.y, ob);

Metode GetCellX dan GetCellY:

public int GetCellX(float mX)
{
    return (int)Math.Floor(mX / SGame.Camera.TileSize); 
}
public int GetCellY(float mY)
{
    return (int)Math.Floor(mY / SGame.Camera.TileSize); 
}

Masalahnya adalah bahwa pemain "berkedip" saat mengenai dinding, dan deteksi sudut bahkan tidak berfungsi dengan benar karena dapat tumpang tindih dengan dinding yang hanya mengenai salah satu sudut. Saya tidak mengerti apa yang salah. Dalam tutorial, bidang ob.x dan ob.y harus sama dengan properti CenterX dan CenterY saya, dan ob.width dan ob.height harus sama dengan Lebar / 2f dan Tinggi / 2f. Namun itu masih tidak berhasil.

Terima kasih atas bantuan Anda.


Apakah Anda menguji tabrakan setelah pemain berada di tempat itu dan mengembalikannya jika itu bertabrakan atau Anda menguji apakah langkah selanjutnya adalah tabrakan?
kyndigs

Saya akan merekomendasikan menambahkan cek tekan tombol di fungsi pembaruan yang akan merusak proses saat ini ketika Anda menekan tombol. Kemudian tekan tombol ketika pemain "berkedip" dan berjalan melalui debugger. (perhatikan apa yang terjadi pada angka-angka) Cobalah untuk mencari tahu apa yang terjadi pada angka-angka itu ketika berkedip-kedip.
Michael Coleman

Jawaban:


1

Beberapa saran, walaupun saya tidak yakin mereka akan memperbaiki masalah karena saya tidak memiliki kode lengkap untuk dijalankan dan debug.

Dalam kode ini:

if(NextX == 1)
{
    if (upright && downright)
       CenterX += Speed;
    else
       CenterX = (Game.GetCellX(CenterX) + 1)*16 - Width / 2f;
}

pernyataan lain adalah memindahkan objek meskipun objek tidak boleh bergerak.
Saya kira Anda mencoba untuk membuat objek rata dengan tembok tapi mungkin perhitungannya salah.
Jika Anda mengomentari pernyataan lain, apakah objek tersebut masih berkedip-kedip?

Perhitungan memang terlihat sedikit mencurigakan karena mengurangi (Lebar / 2f) dan kemudian operator set CenterX melakukan pengurangan yang sama lagi.

Hal lain yang ingin saya tunjukkan, hanya untuk membantu kejelasan kode, adalah bahwa Anda membuat properti untuk CenterX menghitung nilai bolak-balik, tetapi kode tersebut masih dikotori dengan perhitungan yang sama berulang-ulang.
Ini mungkin menjadi bagian dari masalah. Either way, saya sarankan membuat beberapa properti lagi dan menetapkan satu standar untuk semuanya. Misalnya, jadikan Center sebagai properti yang disimpan dan hitung yang lain dari itu:

public float CenterX
{
    get { return X; }
    set { X; }
}

public float LeftX
{
    get { return CenterX - Width / 2f; }
    set { CenterX = value + Width / 2f; }
}

public float RightX
{
    get { return CenterX + Width / 2f; }
    set { CenterX = value - Width / 2f; }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.