C#2D碰撞检测问题

时间:2009-08-19 10:29:59

标签: c# gdi+ 2d collision-detection

我试图弄清楚如何改变我的碰撞检测才能正常工作,我把所有的墙体对象堆放在一个List中,然后当玩家移动时我循环通过每个墙对象并调用DetectCollision方法,这将返回是真还是假,取决于对象是否在墙内。

墙面探测碰撞(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;

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

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

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

当然,假设Entity的位置和大小都有一个向量。所以size.x == width,size.y == height。

答案 1 :(得分:0)

有些东西让我感到不安,你说DetectCollision方法得到了墙的位置 - 但是如果我正确地解释你的代码,你可以把它传给DetectWallCollision x和y参数,这是参数的位置(移动后)位于DetectCollision方法的球员和手......

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

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

答案 2 :(得分:0)

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