C++ 碰撞检测系统中类结构的建议

C++ 碰撞检测系统中类结构的建议,c++,oop,visitor-pattern,double-dispatch,C++,Oop,Visitor Pattern,Double Dispatch,C++是我广泛使用的第一种使用面向对象的语言,所以我对这个想法还是有点陌生。我试图把我正在玩的游戏库从GO(使用接口而不是真正的OOP系统)移植到C++。 我有一个使用四种类型的碰撞系统:点、边界、线和多边形。我想做的是将所有这些抽象为一个“Collider”类,并具有一个函数,该函数能够获取两个Collider对象并测试碰撞。它看起来像这样: bool Collides(Collider obj1, Collider obj2); 最初,我认为我可以为每种碰撞类型提供方法,以测试给定另一种类

C++是我广泛使用的第一种使用面向对象的语言,所以我对这个想法还是有点陌生。我试图把我正在玩的游戏库从GO(使用接口而不是真正的OOP系统)移植到C++。 我有一个使用四种类型的碰撞系统:点、边界、线和多边形。我想做的是将所有这些抽象为一个“Collider”类,并具有一个函数,该函数能够获取两个Collider对象并测试碰撞。它看起来像这样:

bool Collides(Collider obj1, Collider obj2);
最初,我认为我可以为每种碰撞类型提供方法,以测试给定另一种类型的碰撞(即方法OnPoint、OnBounding、OnLine和OnPolygon),然后让“Collider”成为需要所有这些方法的虚拟类,但是后来我意识到C++中不可能,因为它会使类相互依赖而编译(对吗?)
我有点不知道我还能做些什么。我的设计思想是白日梦吗?

你想要的是一个函数,它不仅在第一个参数上分派,而且在第二个参数上分派,即双重分派。这在C++中不直接支持,但可以被仿真。
类点;
班级线;
类对撞机{
公众:
虚拟布尔碰撞(碰撞器常数&x)常数=0;
受保护的:
虚拟布尔碰撞(点常数&p)常数=0;
虚拟布尔碰撞(直线常数&l)常数=0;
朋友课点;
朋友班线;
};
类点:公共对撞机{
公众:
虚拟布尔碰撞(碰撞器常数和x)常数{
//在这里,这个类型现在是Point
//现在,找出x是什么,并调用此类型的重载
返回x.Collides(*this);
}
受保护的:
虚拟布尔碰撞(点常量和点常量){
返回false;
//我们现在知道,我们是一个点,检查与另一个点
}
虚拟布尔碰撞(直线常数和直线常数)常数{
返回false;
//我们现在知道,我们是一个点,检查与线
}
};
类行:公共对撞机{
公众:
虚拟布尔碰撞(碰撞器常数和x)常数{
//这里,这个类型现在是Line
返回x.Collides(*this);
}
受保护的:
虚拟布尔碰撞(点常量和点常量){
返回false;
//我们现在知道,我们是一条线,检查与点
}
虚拟布尔碰撞(直线常数和直线常数)常数{
返回false;
//我们现在知道,我们是一条线,检查与另一条线
}
};
现在,检查两个对象将执行两个运行时调度:

Collider*p=新点();
对撞机*l=新线();
p->碰撞(*l);
//首先在p上动态地分派到调用点::Collides
//在碰撞中,该点(即p)现在具有静态点。
//现在对l进行第二次分派,并使用*作为参数
//找到过载。

例如,这是在中使用的。如果您的对象集是固定的,但您希望对它们执行的操作将发生更改或扩展,那么Visitor是一个不错的选择。

为什么您认为类将相互依赖?如果它们都是抽象类碰撞器的子类,并且它们都只是覆盖该类中定义的方法,那么碰撞方法不应该担心参数的具体类型。不要让场景中的对象负责检测碰撞。要么有一个场景对象检测这些,要么有独立的函数,比如
bool碰撞(const Circle&,const%Rectangle&)
好的,我最好创建某种形式的
碰撞(碰撞器obj1,碰撞器obj2)
函数将重载
碰撞
以接受碰撞对象的任何组合?碰撞肯定是两个对象在空间和时间上共享同一点?还是我遗漏了什么?我无法反驳!如果你对我制作多种类型collison对象的推理感到困惑,我这样做是为了优化碰撞检测(即,在矩形上执行光线投射算法将浪费资源)。我不是说没有更好的方法,这正是我想到的。一个非常有趣的解决方案!非常感谢。