LINQ的新功能:这是使用LINQ的正确位置吗?

Lyi*_*ise 5 c# linq xna

首先,我是LINQ的新手,所以我真的不知道它的来龙去脉.我试着在一些代码中使用它,根据我的诊断,它似乎与以相同方式使用for循环一样快.但是,我不确定这会如何扩展,因为我正在使用的列表可能会非常显着地增加.

我使用LINQ的碰撞检测功能的一部分(这仍然是在作品),我用它来剔除名单仅是相关的检查的.

这是LINQ版本:

partial class Actor {
    public virtual bool checkActorsForCollision(Vector2 toCheck) {
        Vector2 floored=new Vector2((int)toCheck.X, (int)toCheck.Y);

        if(!causingCollision) // skip if this actor doesn't collide
            return false;

        foreach(
            Actor actor in
            from a in GamePlay.actors
            where a.causingCollision==true&&a.isAlive
            select a
            )
            if( // ignore offscreen collisions, we don't care about them
                (actor.location.X>GamePlay.onScreenMinimum.X)
                &&
                (actor.location.Y>GamePlay.onScreenMinimum.Y)
                &&
                (actor.location.X<GamePlay.onScreenMaximum.X)
                &&
                (actor.location.Y<GamePlay.onScreenMaximum.Y)
                )
                if(actor!=this) { // ignore collisions with self
                    Vector2 actorfloor=new Vector2((int)actor.location.X, (int)actor.location.Y);

                    if((floored.X==actorfloor.X)&&(floored.Y==actorfloor.Y))
                        return true;
                }

        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我以前的方法:

partial class Actor {
    public virtual bool checkActorsForCollision(Vector2 toCheck) {
        Vector2 floored=new Vector2((int)toCheck.X, (int)toCheck.Y);

        if(!causingCollision) // skip if this actor doesn't collide
            return false;

        for(int i=0; i<GamePlay.actors.Count; i++)
            if( // ignore offscreen collisions, we don't care about them
                (GamePlay.actors[i].location.X>GamePlay.onScreenMinimum.X)
                &&
                (GamePlay.actors[i].location.Y>GamePlay.onScreenMinimum.Y)
                &&
                (GamePlay.actors[i].location.X<GamePlay.onScreenMaximum.X)
                &&
                (GamePlay.actors[i].location.Y<GamePlay.onScreenMaximum.Y)
                )
                if( // ignore collisions with self
                    (GamePlay.actors[i].isAlive)
                    &&
                    (GamePlay.actors[i]!=this)
                    &&
                    (GamePlay.actors[i].causingCollision)
                    ) {
                    Vector2 actorfloor=
                        new Vector2(
                            (int)GamePlay.actors[i].location.X,
                            (int)GamePlay.actors[i].location.Y
                            );

                    if((floored.X==actorfloor.X)&&(floored.Y==actorfloor.Y))
                        return true;
                }

        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

在那一刻,要么几乎没有时间运行(但每秒运行多次),但随着项目的构建和更复杂,这将同时处理更多的对象,检查碰撞的代码将更加详细.

Eri*_*ert 11

你的代码看起来很不错; 我不是改变工作代码的忠实粉丝,但是如果你确实想要重写它以便更容易阅读,那么我会做的是:

首先,抽象出谓词"离屏幕".也许让它成为GamePlay的一种方法.这种每次检查坐标是否在边界内的业务是(1)实现细节,以及(2)使您的代码难以阅读.将来您可能会有一些更复杂的机制来决定对象是否在屏幕上.

其次,抽象出矢量地板操作.也许让它成为Vector的一种方法.请注意,此方法应返回一个新向量,而不是改变现有向量.

第三,在向量上建立一个等于运算符.

第四,更好地命名方法.谓词的格式应为"IsFoo"或"HasFoo".你把它称为命令,而不是问题.

第五,你根本不需要循环.

第六,这很奇怪somebool == true.说吧somebool.前者意味着"如果真的是这个布尔是真的",这是不必要的复杂.

让我们看看这是如何摆脱的:

public virtual bool HasCollisionWithAnyActor(Vector2 toCheck)
{
    // "Easy out": if this actor does not cause collisions then
    // we know that it is not colliding with any actor.
    if (!causingCollision)
      return false;

    Vector2 floored = toCheck.Floor();

    var collidingActors = 
      from actor in GamePlay.actors
      where actor != this
      where actor.causingCollision
      where actor.isAlive
      where GamePlay.IsOnScreen(actor.location)
      where actor.location.Floor() == floored
      select actor;

    return collidingActors.Any();
}
Run Code Online (Sandbox Code Playgroud)

看一下读取比你的方法版本容易多少!没有一个乱七八糟的X和Y坐标.帮助方法做所有scutwork.代码现在清楚地表达了语义:告诉我屏幕上是否与其他生活的,引起碰撞的演员发生任何冲突.

  • @Lyise:如果您无法访问vector类,则可以随时编写扩展方法. (2认同)