【问题标题】:C# and SFML game intersectionC# 与 SFML 游戏交集
【发布时间】:2015-08-13 23:12:51
【问题描述】:

我在 2D 平台游戏(如 PacMan)中的 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 2d-games sfml.net


    【解决方案1】:

    == 运算符,带有浮点数,检查是否完全相等。通常即使经过非常相似的操作的浮点数仍然不相等。当您比较浮点数的相等性时,最佳做法是执行以下操作:

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

    此处的 someSmallFloat 通常设置为 float.Epsilon,但在您的情况下,您可能希望使用更大的数字来允许错误余量,让玩家即使稍微偏离也能移动更有趣,而不是惩罚玩家非常小的误差。

    【讨论】:

      【解决方案2】:

      e.Xe.Y 的浮点加法不太可能恰好达到目标值。您应该检查实体是否越过相应的线:

      例如向右运动是这样的:

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

      您也可以根据需要更正位置。

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

      您还可以沿 y 坐标移动它以补偿沿 x 坐标的向后移动。

      【讨论】:

        【解决方案3】:

        这是我编辑的工作代码:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-01-07
          • 2018-06-12
          • 2016-02-26
          • 2019-06-14
          • 1970-01-01
          • 2010-09-11
          • 2018-07-08
          • 1970-01-01
          相关资源
          最近更新 更多