Các vấn đề phát hiện va chạm 2D dựa trên gạch


8

Tôi đang cố gắng làm theo hướng dẫn này http://www.tonypa.pri.ee/tbw/tut05.html để thực hiện các va chạm trong thời gian thực trong một thế giới dựa trên gạch.

Tôi tìm thấy tọa độ trung tâm của các thực thể của mình nhờ các thuộc tính này:

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; }
}

Sau đó, trong phương thức cập nhật của tôi, trong lớp trình phát, được gọi là mọi khung, tôi có mã này:

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 và rightX lần lượt sẽ tìm vị trí Y thấp nhất, vị trí Y cao nhất, vị trí X ngoài cùng bên trái và vị trí X ngoài cùng bên phải. Tôi thêm + Tốc độ * NextX vì trong hướng dẫn, hàm getMyCorners được gọi với các tham số sau:

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

Các phương thức GetCellX và 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); 
}

Vấn đề là người chơi "nhấp nháy" trong khi va vào tường và phát hiện góc thậm chí không hoạt động chính xác vì nó có thể chồng lên các bức tường chỉ va vào một trong các góc. Tôi không hiểu điều gì là sai. Trong hướng dẫn, các trường ob.x và ob.y phải giống như các thuộc tính CenterX và CenterY của tôi, và ob. Thong và ob.height phải giống như Width / 2f và height / 2f. Tuy nhiên nó vẫn không hoạt động.

Cảm ơn bạn đã giúp đỡ.


Bạn có đang kiểm tra va chạm một khi người chơi ở vị trí đó và quay lại nếu nó va chạm hoặc bạn đang kiểm tra nếu bước tiếp theo là va chạm?
kyndigs

Tôi khuyên bạn nên thêm một phím bấm kiểm tra trong chức năng cập nhật đó sẽ phá vỡ quy trình hiện tại khi bạn nhấn phím. Sau đó nhấn phím khi người chơi đang "nhấp nháy" và đi qua trình gỡ lỗi. (chú ý đến những gì đang xảy ra với các con số) Cố gắng tìm hiểu những gì đang xảy ra với các con số khi nó nhấp nháy.
Michael Coleman

Câu trả lời:


1

Một vài gợi ý, mặc dù tôi không chắc họ sẽ khắc phục vấn đề vì tôi không có mã đầy đủ để chạy và gỡ lỗi.

Trong mã này:

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

câu lệnh khác đang di chuyển đối tượng mặc dù đối tượng không nên di chuyển.
Tôi đoán bạn đang cố gắng làm cho vật thể dội vào tường nhưng có lẽ phép tính không chính xác.
Nếu bạn nhận xét các tuyên bố khác, đối tượng vẫn nhấp nháy?

Việc tính toán có vẻ hơi đáng ngờ khi nó trừ (Width / 2f) và sau đó toán tử tập CenterX thực hiện lại phép trừ tương tự.

Một điều nữa tôi muốn chỉ ra, chỉ để giúp cho sự rõ ràng của mã, là bạn đã tạo các thuộc tính cho CenterX tính toán giá trị qua lại, nhưng mã vẫn bị lặp đi lặp lại với cùng một phép tính.
Đây cũng có thể là một phần của vấn đề. Dù bằng cách nào, tôi khuyên bạn nên tạo thêm một vài thuộc tính và giải quyết theo một tiêu chuẩn cho tất cả chúng. Ví dụ: đặt Trung tâm là tài sản được lưu trữ và tính toán những thứ khác từ đó:

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; }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.