【问题标题】:Collision detection in a 2D maze with thick walls厚壁二维迷宫中的碰撞检测
【发布时间】:2014-01-02 17:02:50
【问题描述】:

我必须为学校制作一个带有 Windows 窗体的游戏。我的游戏包含一个必须通过迷宫的用户。我试图阻止我的用户使用碰撞检测直接穿过墙壁,但由于用于表示墙壁的矩形形状不同,我被卡住了。 Here's an image of the game. 这个问题可能和this one 类似,但是我的动作我相信它是完全不同的,因为我没有布置网格系统或图形地图。

如您所见,墙壁相当厚。每面墙都由 C# Rectangle, 表示,我的 Player 图像(小黄鬼)也是如此。我知道如何使用 C# 的 IntersectsWith(Rectangle r) 方法确定玩家是否穿过这些墙壁,但我不确定如何使用这些信息来处理碰撞并阻止玩家穿过墙壁。

这是我尝试过的:

这是我的实际移动代码。因为游戏是在WinForm中构建的,所以移动是由OnKeyPressedOnKeyUp等键盘事件触发的

    public void Move(Direction dir)
    {
        HandleCollision(); // Handle collision while player is trying to move.
        if (dir == Direction.NORTH)
        {                
            this.y -= moveSpeed;
        }
        if (dir == Direction.SOUTH)
        {                
            this.y += moveSpeed;
        }
        if (dir == Direction.EAST)
        {
            this.x += moveSpeed;
        }
        if (dir == Direction.WEST)
        {
            this.x -= moveSpeed;
        }
    }

这是我的碰撞方法,HandleCollision()

    private void HandleCollision()
    {
        // First, check to see if the player is hitting any of the boundaries of the game.
        if (this.x <= 0)
        {
            this.x = 0;
        }
        if (this.x >= 748)
        {
            this.x = 748;
        }
        if (this.y <= 0)
        {
            this.y = 0;
        }
        if (this.y >= 405)
        {
            this.y = 405;
        }           
        // Second, check for wall collision.

        foreach (Rectangle wall in mazeWalls)
        {
            if (playerRectangle.IntersectsWith(wall))
            {
                if (player.X > wall.X) { player.X += wall.Width; }
                else if (player.X < wall.X) { player.X -= wall.Width; }
                else if (player.Y > wall.Y) { player.Y += wall.Height; }
                else if (player.Y < wall.Y) { player.Y -= wall.Height; }                    
            }
        }
    }

现在上面的代码可以工作了。然而,由于玩家的坐标添加了墙的宽度/高度,这会在地图上产生一些奇怪的碰撞瞬移,玩家最终会四处弹跳。那么,实现一个可以替换if (playerRectangle.IntersectsWith(wall)) { 块中所有代码的碰撞检测系统的最有效方法是什么?

【问题讨论】:

    标签: c# winforms 2d collision-detection collision


    【解决方案1】:

    在移动中,保存当前位置,执行移动,检查碰撞,如果为真,恢复旧位置。

    为此,HandleCollision 将返回一个布尔值,每次成功测试时返回 true(成功 = 检测到碰撞),如果不满足任何条件,则返回 false。该方法根本不会修改任何 x 或 y 值。为了体现它的新功能,这个方法应该重命名为CheckCollision。


    从你其他帖子中的 gif 来看,你的比赛场地似乎被划分为正方形,而墙壁和精灵是由多个正方形组成的?然后你的移动应该以一个平方的增量进行,直到达到预期的增量。对于每个方格,都必须检查碰撞。

    对于更高级的方法,每次移动只有一次检查,您需要一些线性数学。碰撞检查将需要当前点 P 和移动的增量 d。您需要检查 P 和 P+d 之间的墙是否越过。这通常由线性条件下的符号变化来表示。对于 P 左侧的垂直墙 W,如果 d 指向墙,P.x+d.x-(W.x+W.width) 将为负数。用W.x+W.width&lt;=P.x+s*d.x 确定 s。对于水平墙壁,您必须在 y 坐标中进行相同的检查。取所有命中对象的最小 s 和P+s*d 作为新位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-30
      • 2012-03-27
      • 2022-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多