所以,你有一条线段(AB),我收集到这条线段正在移动,你想知道这条线段会在什么点与另一条线段(你的船,无论如何)发生碰撞。
因此,从数学上讲,您想要检查两条线何时相交(两条线将始终相交,除非平行),然后检查它们相交的点是否在您的屏幕上。首先,您需要将线段转换为线方程,如下所示:
typedef struct {
GLfloat A;
GLfloat B;
GLfloat C;
} Line;
static inline Line LineMakeFromCoords(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) {
return (Line) {y2-y1, x1-x2, (y2-y1)*x1+(x1-x2)*y1};
}
static inline Line LineMakeFromSegment(Segment segment) {
return LineMakeFromCoords(segment.P1.x,segment.P1.y,segment.P2.x,segment.P2.y);
}
然后检查它们是否相交
static inline Point2D IntersectLines(Line line1, Line line2) {
GLfloat det = line1.A*line2.B - line2.A*line1.B;
if(det == 0){
//Lines are parallel
return (Point2D) {0.0, 0.0}; // FIXME should return nil
}else{
return (Point2D) {(line2.B*line1.C - line1.B*line2.C)/det, (line1.A*line2.C - line2.A*line1.C)/det};
}
}
Point2D 将为您提供相交点,当然您必须针对所有船的线段测试您的线段,这可能会有点耗时,例如碰撞框等进入图片。
数学都在维基百科中,如果您需要更多信息,请查看那里。
编辑:
附加组件以跟进评论:
与之前测试您的线段与矩形的所有四个线段的碰撞相同,您将得到以下三种情况之一:
- 屏幕上没有碰撞/碰撞点(请记住,碰撞测试是针对线,而不是线段,除非平行,否则线将始终相交),嘲讽玩家失踪:-)
- 一次碰撞,绘制/执行任何您想要的部分将是 AC(C 碰撞点)
两次碰撞,使用类似下面的代码检查每个结果段 (A-C1) 和 (A-C2) 的大小,并保留具有最短大小的段。
static inline float SegmentSizeFromPoints(Vertice3D P1, Vertice3D P2) {
return sqrtf(powf((P1.x - P2.x),2.0) + pow((P1.y - P2.y),2.0));
}
处理碰撞时的棘手之处在于找出最小化必须进行的测试数量的方法。