使用游戏"从SFML游戏开发",我正在优化碰撞。我的所有实体都在SceneNode
的树中组织。为了处理碰撞,我遍历所有场景节点,检查哪些是可碰撞的孩子,然后递归检查他们所有的孩子。我弄乱了一些东西,因为现在它在checkNodeCollision
和getCollidableChildren
之间循环。
这是代码:
void SceneNode::checkSceneCollision(SceneNode& sceneGraph, std::set<Pair>& collisionPairs)
{
checkNodeCollision(sceneGraph, collisionPairs);
for (SceneNode* child : sceneGraph.getCollidableChildren())
{
checkSceneCollision(*child, collisionPairs);
}
}
void SceneNode::checkNodeCollision(SceneNode& node, std::set<Pair>& collisionPairs)
{
if (this != &node && collision(*this, node) && !isDestroyed() && !node.isDestroyed())
collisionPairs.insert(std::minmax(this, &node));
for (SceneNode* child : node.getCollidableChildren())
{
child->checkNodeCollision(node, collisionPairs);
}
}
bool SceneNode::isCollidable(){
// a node is not collidable if outside the screen or destroyed
//return (!getBoundingRect().intersects(World::Instance()->getViewBounds()) && !isDestroyed());
return true;
}
std::vector<SceneNode*> SceneNode::getCollidableChildren(){
std::vector<SceneNode*> children;
for (auto& child : mChildren){
if (child->isCollidable()){
SceneNode* rawChild = child.get();
children.push_back(rawChild);
}
}
return children;
}
以下是本书中的代码
void SceneNode::checkSceneCollision(SceneNode& sceneGraph, std::set<Pair>& collisionPairs)
{
checkNodeCollision(sceneGraph, collisionPairs);
FOREACH(Ptr& child, sceneGraph.mChildren)
checkSceneCollision(*child, collisionPairs);
}
void SceneNode::checkNodeCollision(SceneNode& node, std::set<Pair>& collisionPairs)
{
if (this != &node && collision(*this, node) && !isDestroyed() && !node.isDestroyed())
collisionPairs.insert(std::minmax(this, &node));
FOREACH(Ptr& child, mChildren)
child->checkNodeCollision(node, collisionPairs);
}
此外,mChildren
是std::vector<Ptr>
,它存储SceneNode
的所有子项。我在isCollidable
中注释了逻辑,以确保代码独立于该函数
答案 0 :(得分:0)
我必须将checkNodeCollision更改为如下所示:
void SceneNode::checkNodeCollision(SceneNode& node, std::set<Pair>& collisionPairs)
{ if(this!=&amp; node&amp;&amp; collision(* this,node)&amp;&amp;!isDestroyed()&amp;&amp;!node.isDestroyed()) collisionPairs.insert(std :: minmax(this,&amp; node));
for (SceneNode* child : getCollidableChildren())
{
child->checkNodeCollision(node, collisionPairs);
}
}