首先,我是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.代码现在清楚地表达了语义:告诉我屏幕上是否与其他生活的,引起碰撞的演员发生任何冲突.
| 归档时间: |
|
| 查看次数: |
479 次 |
| 最近记录: |