简体   繁体   English

C#2D碰撞检测问题

[英]C# 2D collision detection problem

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. 我一直在试图弄清楚如何更改碰撞检测以使其正常工作,我将所有墙壁对象堆叠在一个List中,然后当玩家移动我循环通过每个墙壁对象并调用DetectCollision方法时,此方法返回true或false取决于物体是否在墙壁内。

Wall detect collision (X- and Y-coordinate is the position of the wall) 墙检测碰撞(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;
    }

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. 因此,在我的播放器功能中,当播放器尝试移动时,我将移动添加到临时的X,Y坐标中,并检查这些碰撞是否撞在墙上,如果它们什么也不做,否则我将移动播放器。

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: 而DetectWallCollision的循环就是:

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

Any ideas? 有任何想法吗?

I'm assuming there isn't anything in your world that is infinitely small (ie 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. 因此size.x ==宽度,size.y ==高度。

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... 有件事让我感到困扰,您说过DetectCollision方法可以获取墙的位置-但是,如果我正确解释了您的代码,则可以将x和y参数(即玩家和手的位置(移动后))传递给DetectWallCollision该位置下降到DetectCollision方法...

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语句的运行路线?

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 ;) 如果由于某种原因无法调试代码-编写跟踪文件-我认为解决方案将落在您的腿上;)

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. 在左上角的坐标系为0,0的情况下,当您向下或向右移动时,该坐标系会正向增加,那么,西移通常意味着向左移动,这意味着X的值减小,而东向则相反。 You are doing the opposite. 您正在相反。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM