c#和SFML游戏的交集

本文关键字:游戏 SFML | 更新日期: 2023-09-27 17:51:13

我在2D平台游戏(如《吃豆人》)中使用MoveEntity()方法时遇到了问题。当玩家处于交叉路径时,我想设置:

e.IsAtIntersection = true;

,然后调用UpdateDirection()

但他没有停下来,相反,他穿过小路,不管有没有墙或空的路。程序永远不会到达上面的行。成员保持false。也许有可能用一种更简单的方式来写或者我犯了一个简单的错误。下面是完整的方法:

private void MoveEntity(Entity e)
{
    int angle = 0;
    if (e.currentDirection == Direction.RIGHT) angle = 0;
    else if (e.currentDirection == Direction.DOWN) angle = 90;
    else if (e.currentDirection == Direction.LEFT) angle = 180;
    else if (e.currentDirection == Direction.UP) angle = 270;
    var scalex = Math.Round(Math.Cos(angle * (Math.PI / 180.0)));
    var scaley = Math.Round(Math.Sin(angle * (Math.PI / 180.0)));
    var velocityx = (float)(e.Speed * scalex);
    var velocityy = (float)(e.Speed * scaley);
    Sprite sp = sprites[e.Name];
    Vector2f v = new Vector2f(sp.Position.X + velocityx, sp.Position.Y + velocityy);
    sp.Position = v;
    var eCenterX = sp.Position.X + sp.TextureRect.Width / 2;
    var eCenterY = sp.Position.Y + sp.TextureRect.Height / 2;
    var tileY = Math.Floor((eCenterY) / TILEHEIGHT);
    var tileX = Math.Floor((eCenterX) / TILEWIDTH);
    var tileXpos = TILEWIDTH * Math.Floor(tileX + 1);
    var tileYpos = TILEHEIGHT * Math.Floor(tileY + 1);
    e.X = (int)tileY;
    e.Y = (int)tileX;
    if (eCenterX == tileXpos && eCenterY == tileYpos)
        e.IsAtIntersection = true;
    else
        e.IsAtIntersection = false;
}

c#和SFML游戏的交集

带有浮点数的==运算符检查是否完全相等。通常,即使浮点数经历了非常相似的操作,也不会相等。当您比较浮点数的相等性时,最佳实践是执行以下操作:

if(Math.Abs(floatA-floatB) <= someSmallFloat)

someesmallfloat通常设置为float。但在你的情况下,你可能想要使用一个更高的数字来允许错误的余量,更有趣的是允许玩家移动,即使他们稍微偏离,而不是因为非常小的不准确而惩罚玩家。

e.Xe.Y的浮点相加不太可能正好达到目标值。您应该检查实体是否在相应的行上移动:

。像这样向右移动:

if(e.currentDirection == Direction.RIGHT 
   && eCenterX - velocityx< tileXpos && eCenterX >= eCenterX)
    e.IsAtIntersection = true;

如果你愿意,你也可以纠正位置。

...
    e.IsAtIntersection = true;
    e.X = tileXpos;

您也可以沿着y坐标移动它来补偿沿着x坐标的反向移动

这是我编辑的工作代码:

        private void MoveEntity(Entity e)
    {
        int angle = 0;
        if (e.currentDirection == Direction.RIGHT) angle = 0;
        else if (e.currentDirection == Direction.DOWN) angle = 90;
        else if (e.currentDirection == Direction.LEFT) angle = 180;
        else if (e.currentDirection == Direction.UP) angle = 270;
        var scalex = Math.Round(Math.Cos(angle * (Math.PI / 180.0)));
        var scaley = Math.Round(Math.Sin(angle * (Math.PI / 180.0)));
        var velocityx = (float)(e.Speed * scalex);
        var velocityy = (float)(e.Speed * scaley);
        Sprite sp = sprites[e.Name];
        Vector2f v = new Vector2f(sp.Position.X + velocityx, sp.Position.Y + velocityy);
        sp.Position = v;
        var tileY = (int)sp.Position.Y / 60;
        var tileX = (int)sp.Position.X / 60;
        var tileXpos = tileX * 60;
        var tileYpos = tileY * 60;
        e.X = (int)tileY;
        e.Y = (int)tileX;
        if (sp.Position.X == tileXpos && sp.Position.Y == tileYpos)
            e.IsAtIntersection = true;
        else
            e.IsAtIntersection = false;
    }