C# 2D碰撞检测问题

发布于 2024-08-02 10:57:47 字数 1859 浏览 1 评论 0原文

我一直在试图弄清楚如何改变碰撞检测以使其正常工作,我将所有墙壁对象堆叠在一个列表中,然后当玩家移动时,我循环遍历每个墙壁对象并调用 DetectCollision 方法,这会返回 true 或 false取决于物体是否在墙内。

墙壁检测碰撞(X 和 Y 坐标是墙壁的位置)

public bool DetectCollision(float x, float y)
    {
        if ((x >= this.XCoordinate && x <= (this.XCoordinate + this.BlockWidth)) && (y >= this.YCoordinate && y <= (this.YCoordinate + this.BlockHeight)))
            return true;            
        else
            return false;
    }

因此,在我的播放器功能中,当玩家尝试移动时,我将移动添加到临时 X,Y 坐标并检查这些是否与墙壁碰撞,如果他们什么也不做,否则我会移动玩家。

但我注意到它不能正常工作,如果我在游戏场内添加一块墙,它只会检查右下角的碰撞检测?

玩家移动方法:

        float x, y;
        if (direction == Direction.E)
        {
            x = LiveObjects.player.XCoordinate - MovementSpeed;
            y = LiveObjects.player.YCoordinate;
        }
        else if (direction == Direction.W)
        {
            x = LiveObjects.player.XCoordinate + MovementSpeed;
            y = LiveObjects.player.YCoordinate;
        }
        else if (direction == Direction.N)
        {
            x = LiveObjects.player.XCoordinate;
            y = LiveObjects.player.YCoordinate - MovementSpeed;
        }
        else
        {
            x = LiveObjects.player.XCoordinate;
            y = LiveObjects.player.YCoordinate + MovementSpeed;
        }

        if (GameMechanics.DetectWallCollision(x, y) || GameMechanics.DetectWallCollision((x + LiveObjects.player.BlockWidth), (y + LiveObjects.player.BlockHeight))
        {
            OnPlayerInvalidMove(null, new PlayerEventArgs());
            return;
        }

DetectWallCollision 的循环就是:

foreach (Wall wall in LiveObjects.walls)
        {
            if (wall.DetectCollision(x, y))
                return true;
        }
        return false;

有什么想法吗?

I am stuck trying to figure out how to alter my collision detection to work correctly, i got all my wall objects stacked inside a List and then when the player moves i loop thru each wall object and call the DetectCollision method, this returns true or false depending on if the object is inside the wall or not.

Wall detect collision (X- and Y-coordinate is the position of the wall)

public bool DetectCollision(float x, float y)
    {
        if ((x >= this.XCoordinate && x <= (this.XCoordinate + this.BlockWidth)) && (y >= this.YCoordinate && y <= (this.YCoordinate + this.BlockHeight)))
            return true;            
        else
            return false;
    }

So in my player function when the player tries to move, i add the movement to a temporary X,Y coordinate and check if those Collide against the wall, if they do nothing happens, otherwise i move the player.

But i have noticed that it doesn't work as it should be, if i add a piece of wall inside of the gamefield it only checks the bottom right corner for collision detection?

Player movement method:

        float x, y;
        if (direction == Direction.E)
        {
            x = LiveObjects.player.XCoordinate - MovementSpeed;
            y = LiveObjects.player.YCoordinate;
        }
        else if (direction == Direction.W)
        {
            x = LiveObjects.player.XCoordinate + MovementSpeed;
            y = LiveObjects.player.YCoordinate;
        }
        else if (direction == Direction.N)
        {
            x = LiveObjects.player.XCoordinate;
            y = LiveObjects.player.YCoordinate - MovementSpeed;
        }
        else
        {
            x = LiveObjects.player.XCoordinate;
            y = LiveObjects.player.YCoordinate + MovementSpeed;
        }

        if (GameMechanics.DetectWallCollision(x, y) || GameMechanics.DetectWallCollision((x + LiveObjects.player.BlockWidth), (y + LiveObjects.player.BlockHeight))
        {
            OnPlayerInvalidMove(null, new PlayerEventArgs());
            return;
        }

and the loop for DetectWallCollision is just:

foreach (Wall wall in LiveObjects.walls)
        {
            if (wall.DetectCollision(x, y))
                return true;
        }
        return false;

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

二手情话 2024-08-09 10:57:48

你的东方和西方是错误的。如果坐标系为左上角的 0,0,向下或向右移动时正值增加,那么向西移动通常意味着向左移动,这意味着 X 值减小,向东则相反。你正在做相反的事情。

Your east and west are the wrong way around. With a coordinate system of 0,0 at the top left, increasing positively as you move down or to the right, then a movement West would normally mean a movement left, which means decreasing values of X, and the reverse for East. You are doing the opposite.

霓裳挽歌倾城醉 2024-08-09 10:57:47

我假设你的世界中没有任何东西是无限小的(即像素的大小)。要实现真正的边界框碰撞,您必须考虑两个对象的大小,而不仅仅是一个对象。

boolean intersectsEntity(Entity e)
{
    return (e.position.x <= position.x + size.x) &&
           (e.position.y <= position.y + size.y) &&
           (e.position.x + e.size.x >= position.x) &&
           (e.position.y + e.size.y >= position.y);
}

当然,这是假设一个实体具有其位置和大小的向量。所以 size.x == 宽度,size.y == 高度。

I'm assuming there isn't anything in your world that is infinitely small (i.e. is the size of a pixel). To have true bounding box collision, you've got to consider the size of both objects, not just one.

boolean intersectsEntity(Entity e)
{
    return (e.position.x <= position.x + size.x) &&
           (e.position.y <= position.y + size.y) &&
           (e.position.x + e.size.x >= position.x) &&
           (e.position.y + e.size.y >= position.y);
}

That's of course assuming an Entity has a vector for its position and for its size. So size.x == width, and size.y == height.

最近可好 2024-08-09 10:57:47

有件事让我感到不安,你说 DetectCollision 方法获取墙壁的位置 - 但如果我正确解释你的代码,你会将 x 和 y 参数交给 DetectWallCollision,即玩家和手的位置(移动后)该位置一直到 DetectCollision 方法...

您是否调试过代码以查看哪些坐标传递给了碰撞方法并跟踪了 if 语句的路线?

如果由于某种原因无法调试您的代码 - 编写跟踪文件 - 我认为解决方案将落入您的手中;)

There is something that disturbs me, you said that the DetectCollision method gets the position of the wall - but if I interpret your code correctly you hand to the DetectWallCollision the x and y parameter which is the position (after movement) of the player and hand that position down to the DetectCollision method...

have you debugged your code to see what coordinates are passed to the collision methods and traced the routes your if-statements are going?

if it is not possible to debug your code for whatever reason - write a trace file - I think the solution will fall into your lap ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文