C# 碰撞检测弹跳问题

发布于 2024-10-12 05:49:25 字数 2270 浏览 6 评论 0原文

所以我的碰撞检测工作正常,但由于某种原因,玩家似乎进入地面一帧,然后在下一帧中跳出地面,然后按预期跌倒。

我用于碰撞检测的代码

        void DoCollisions()
    {
        onGround = false;
        Position.Y += Velocity.Y;
        Vector2 tileCollision = GetTileCollision();
        if (tileCollision.X != -1 || tileCollision.Y != -1)
        {
            onGround = true;
            Vector2 collisionDepth = CollisionRectangle.DepthIntersection(
                new Rectangle(
                    tileCollision.X * World.tileEngine.TileWidth,
                    tileCollision.Y * World.tileEngine.TileHeight,
                    World.tileEngine.TileWidth,
                    World.tileEngine.TileHeight
                )
            );
            Position.Y -= Velocity.Y;
            Velocity.Y = 0;
            Position.Y += collisionDepth.Y;

        }

        Position.X += Velocity.X;
        tileCollision = GetTileCollision();
        if (tileCollision.X != -1 || tileCollision.Y != -1)
        {
            Vector2 collisionDepth = CollisionRectangle.DepthIntersection(
                new Rectangle(
                    tileCollision.X * World.tileEngine.TileWidth,
                    tileCollision.Y * World.tileEngine.TileHeight,
                    World.tileEngine.TileWidth,
                    World.tileEngine.TileHeight
                )
            );
            Position.X -= Velocity.X;
            Velocity.X = 0;
            Position.X += collisionDepth.X;

        }
    }

    Vector2 GetTileCollision()
    {
        int topLeftTileX = (int)(CollisionRectangle.TopLeft.X / World.tileEngine.TileWidth);
        int topLeftTileY = (int)(CollisionRectangle.TopLeft.Y / World.tileEngine.TileHeight);
        int BottomRightTileX = (int)(CollisionRectangle.DownRight.X / World.tileEngine.TileWidth);
        int BottomRightTileY = (int)(CollisionRectangle.DownRight.Y / World.tileEngine.TileHeight);

        for (int i = topLeftTileX; i <= BottomRightTileX; i++)
        {
            for (int j = topLeftTileY; j <= BottomRightTileY; j++)
            {
                if (World.tileEngine.TileIsSolid(i, j))
                {
                    return new Vector2(i,j);
                }
            }
        }

        return new Vector2(-1,-1);
    }

So I got my collision detection working, but for some reason the player seems to go intro the ground 1 frame then jump out of it in the next frame and then fall down as its supposed to.

Code I use for the collision detection

        void DoCollisions()
    {
        onGround = false;
        Position.Y += Velocity.Y;
        Vector2 tileCollision = GetTileCollision();
        if (tileCollision.X != -1 || tileCollision.Y != -1)
        {
            onGround = true;
            Vector2 collisionDepth = CollisionRectangle.DepthIntersection(
                new Rectangle(
                    tileCollision.X * World.tileEngine.TileWidth,
                    tileCollision.Y * World.tileEngine.TileHeight,
                    World.tileEngine.TileWidth,
                    World.tileEngine.TileHeight
                )
            );
            Position.Y -= Velocity.Y;
            Velocity.Y = 0;
            Position.Y += collisionDepth.Y;

        }

        Position.X += Velocity.X;
        tileCollision = GetTileCollision();
        if (tileCollision.X != -1 || tileCollision.Y != -1)
        {
            Vector2 collisionDepth = CollisionRectangle.DepthIntersection(
                new Rectangle(
                    tileCollision.X * World.tileEngine.TileWidth,
                    tileCollision.Y * World.tileEngine.TileHeight,
                    World.tileEngine.TileWidth,
                    World.tileEngine.TileHeight
                )
            );
            Position.X -= Velocity.X;
            Velocity.X = 0;
            Position.X += collisionDepth.X;

        }
    }

    Vector2 GetTileCollision()
    {
        int topLeftTileX = (int)(CollisionRectangle.TopLeft.X / World.tileEngine.TileWidth);
        int topLeftTileY = (int)(CollisionRectangle.TopLeft.Y / World.tileEngine.TileHeight);
        int BottomRightTileX = (int)(CollisionRectangle.DownRight.X / World.tileEngine.TileWidth);
        int BottomRightTileY = (int)(CollisionRectangle.DownRight.Y / World.tileEngine.TileHeight);

        for (int i = topLeftTileX; i <= BottomRightTileX; i++)
        {
            for (int j = topLeftTileY; j <= BottomRightTileY; j++)
            {
                if (World.tileEngine.TileIsSolid(i, j))
                {
                    return new Vector2(i,j);
                }
            }
        }

        return new Vector2(-1,-1);
    }

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

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

发布评论

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

评论(1

孤千羽 2024-10-19 05:49:25

仅以 Y 方向为例,乍一看,您似乎调整了 Y 两次,一次是在碰撞检查之前,然后当您发生碰撞时,您将恢复Y 并将对象推出 collisionDepth

如果碰撞深度.Y 表明您正在与地面相交,您可能不应该恢复 Y您应该将物体向后推一定的深度,这将使您与地面齐平。

        if (tileCollision.X != -1 || tileCollision.Y != -1)
        {
            onGround = true;
            Vector2 collisionDepth = CollisionRectangle.DepthIntersection(
                new Rectangle(
                    tileCollision.X * World.tileEngine.TileWidth,
                    tileCollision.Y * World.tileEngine.TileHeight,
                    World.tileEngine.TileWidth,
                    World.tileEngine.TileHeight
                )
            );
            Velocity.Y = 0;
            // Depending on your coordinate system this should
            // be either + or - collisionDepth.Y
            Position.Y += collisionDepth.Y;
        }

Using just the Y direction as an example, at first glance it seems that you are adjusting Y twice, once before the collision check, then when you get a collision you revert the Y and push the object out by collisionDepth

You should probably not be reverting the Y, if the collisionDepth.Y indicates that you are intersecting the ground you should just push your object back by the depth amount, which would put you flush against the ground.

        if (tileCollision.X != -1 || tileCollision.Y != -1)
        {
            onGround = true;
            Vector2 collisionDepth = CollisionRectangle.DepthIntersection(
                new Rectangle(
                    tileCollision.X * World.tileEngine.TileWidth,
                    tileCollision.Y * World.tileEngine.TileHeight,
                    World.tileEngine.TileWidth,
                    World.tileEngine.TileHeight
                )
            );
            Velocity.Y = 0;
            // Depending on your coordinate system this should
            // be either + or - collisionDepth.Y
            Position.Y += collisionDepth.Y;
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文