我最近出于兴趣学习了 C,并且正在学习 C++。作为一个学习项目,我正在使用 ALLEGRO5 库用 C 语言制作一个游戏进行显示。我有一名球员在场上二维等轴测图的运动。我已经创建了 2 个平行四边形,并且已经完成了非旋转正方形碰撞。一个简单的例子: : 当然,玩家移动而房子不移动。我正在使用顶点检测碰撞,因此我发送了一些顶点:
fresh(house.vertices_x, house.vertices_y, player.vertices_x, player.vertices_y, 5);
玩家顶点都添加了位置,以便计算可以移动。
struct flipped_y { double y; double yp; };
struct flipped_y flip_y[10];
struct vectors { double x; double y; double xp; double yp; };
struct vectors vector[10];
struct Normals { double x; double y; double xp; double yp; };
struct Normals normvec[10];
struct Normalized { double x; double y; double xp; double yp; };
struct Normalized normalized[10];
struct projectpts { double pts; double ptsp; double ptspoly2rhom; double ptspoly2player; };
struct projectpts project[20];
struct maxmin { double max; double min; double maxp; double minp; double maxon2; double minon2; double maxpon2; double minpon2; };
struct maxmin mm[5];
double flipp_y_func(double verts[], double vertsp[], int numvert);
double createvector(double vert_x[], struct flipped_y flip_y[], double vert_xp[], int numvert);
double Normals(struct vectors vector[], int numvecs);
double Normalize(struct Normals normvec[], int numvec);
double ProjectPoints(double verts_x[], double verts_xp[], struct flipped_y flip[], struct Normalized normalized[], int numpts);
double Compareminandmax(double max[], double maxp[], double min[], double minp[], double maxon2[], double maxpon2[], double minon2[], double minpon2[], int nummaxmin);
int fresh(double vertices_x[], double vertices_y[], double pvertices_x[], double pvertices_y[],int numverts) {
int i = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0,i8=0; double max[5] = { -INFINITY,-INFINITY,-INFINITY,-INFINITY,-INFINITY }, min[5] = { INFINITY,INFINITY,INFINITY,INFINITY,INFINITY }, maxp[5] = { -INFINITY,-INFINITY,-INFINITY,-INFINITY,-INFINITY }, minp[5] = { INFINITY,INFINITY,INFINITY,INFINITY,INFINITY };
double maxon2[5] = { -INFINITY,-INFINITY,-INFINITY,-INFINITY,-INFINITY }, minon2[5] = { INFINITY,INFINITY,INFINITY,INFINITY,INFINITY }, maxpon2[5] = { -INFINITY,-INFINITY,-INFINITY,-INFINITY,-INFINITY }, minpon2[5] = { INFINITY,INFINITY,INFINITY,INFINITY,INFINITY };
double wishbone = 1;
这是快板左上角坐标,所以我们将 Y 翻转为笛卡尔坐标(vertices_y 和玩家 pvertices_y)
flipp_y_func(vertices_y, pvertices_y, 5);
现在我们创建一个向量
createvector(vertices_x, flip_y, pvertices_x, 5);
然后我们得到两者的法线
Normals(vector, 4);
将两者标准化
Normalize(normvec, 4);
现在我们将两者投影到它们自身和另一个形状上
ProjectPoints(vertices_x, pvertices_x, flip_y, normalized, 4);
这是获取归一化向量 1-4 上的房子和归一化向量 1-4 上的玩家的最大值和最小值
for (i6; i6 < 4; i6++) {
for (i7 = 0; i7 < 4; i7++) {
// polygon1
if (project[i6 * 4 + i7].pts > max[i6]) { max[i6] = project[i6 * 4 + i7].pts; }
if (project[i6 * 4 + i7].pts < min[i6]) { min[i6] = project[i6 * 4 + i7].pts; }
//player
if (project[i6 * 4 + i7].ptsp > maxp[i6]) { maxp[i6] = project[i6 * 4 + i7].ptsp; }
if (project[i6 * 4 + i7].ptsp < minp[i6]) { minp[i6] = project[i6 * 4 + i7].ptsp; }
//polygon2
if (project[i6 * 4 + i7].ptspoly2rhom > maxon2[i6]) { maxon2[i6] = project[i6 * 4 + i7].ptspoly2rhom; }
if (project[i6 * 4 + i7].ptspoly2rhom < minon2[i6]) { minon2[i6] = project[i6 * 4 + i7].ptspoly2rhom; }
//player
if (project[i6 * 4 + i7].ptspoly2player > maxpon2[i6]) { maxpon2[i6] = project[i6 * 4 + i7].ptspoly2player; }
if (project[i6 * 4 + i7].ptspoly2player < minpon2[i6]) { minpon2[i6] = project[i6 * 4 + i7].ptspoly2player; }
}
打印值
//1
/* printf("\nmax %f normvec%d", max[i6], i6);
printf("\nmin %f normvec%d\n", min[i6], i6);
printf("\nmaxPLAYER %f normvecPLAYER%d", maxp[i6], i6);
printf("\nminPLAYER %f normvecPLAYER%d\n", minp[i6], i6);
//on2
printf("\nmaxon2 %f normvecon2%d", maxon2[i6], i6);
printf("\nminon2 %f normvecon2%d\n", minon2[i6], i6);
printf("\nmaxPLAYERon2 %f normvecPLAYERon2%d", maxpon2[i6], i6);
printf("\nminPLAYERon2 %f normvecPLAYERon2%d\n", minpon2[i6], i6);*/
}
now we compare min and max of each shape on all the normalized vectors of both shaoes
wishbone = Compareminandmax(max, maxp, min, minp, maxon2, maxpon2, minon2, minpon2, 4);
我希望它能起作用,哈哈
printf("\nwishbone %f", wishbone);
参考
/aminbmin 或者 bmin amin/ 打印值以查看它们如何比较,并且它们在应该报告碰撞时没有报告碰撞,但通常仅在 1 个或两个轴上
/*while (i < 4) {
printf("\nmin%f < maxp%f and min%f > minp%f\n \t\t\t or \nminp%f < max%f and minp%f> min%f\n\n", min[i], maxp[i], min[i], minp[i], minp[i], max[i], minp[i], min[i]);
printf("\nminon2%f < maxpon2%f and minon2%f > minpon2%f\n \t\t\t or \nminpon2%f < maxon2%f and minpon2%f> minon2%f\n\n", minon2[i], maxpon2[i], minon2[i], minpon2[i], minpon2[i], maxon2[i], minpon2[i], minon2[i]); i++;
}*/
return 0;
}
//player and house flipped
double flipp_y_func(double verts[], double vertsp[], int numvert) {
int i; for (i = 0; i < numvert; i++) {
flip_y[i].y = verts[i] * -1;
flip_y[i].yp = vertsp[i] * -1;
}
return 0;
}
// 创建向量
double createvector(double vert_x[], struct flipped_y flip_y[], double vert_xp[], int numvert) {
int i = 0; double vector_x[10], vector_y[10], vector_xp[10], vector_yp[10];
for (i = 0; i < numvert; i++) {
vector_x[i] = vert_x[i + 1] - vert_x[i];
vector_y[i] = flip_y[i + 1].y - flip_y[i].y;
vector[i].x = vector_x[i];
vector[i].y = vector_y[i];
//player
vector_xp[i] = vert_xp[i + 1] - vert_xp[i];
vector_yp[i] = flip_y[i + 1].yp - flip_y[i].yp;
vector[i].xp = vector_xp[i];
vector[i].yp = vector_yp[i];
}
return 0;
}
//恢复正常
double Normals(struct vectors vector[], int numvecs) {
int i;
for (i = 0; i < numvecs; i++) {
normvec[i].y = vector[i].x;
normvec[i].x = vector[i].y * -1;
//player
normvec[i].yp = vector[i].xp;
normvec[i].xp = vector[i].yp * -1;
}
return 0;
}
//标准化任何添加 p 的内容意味着玩家
double Normalize(struct Normals normvec[], int numvec) {
int i; double Normalizedx[6], Normalizedy[6], Normalizedxp[6], Normalizedyp[6], lengthp[6], length[6];
for (i = 0; i < numvec; i++) {
length[i] = sqrt(pow(normvec[i].x, 2) + pow(normvec[i].y, 2));
Normalizedx[i] = normvec[i].x / length[i];
Normalizedy[i] = normvec[i].y / length[i];
normalized[i].x = Normalizedx[i];
normalized[i].y = Normalizedy[i];
lengthp[i] = sqrt(pow(normvec[i].xp, 2) + pow(normvec[i].yp, 2));
Normalizedxp[i] = normvec[i].xp / lengthp[i];
Normalizedyp[i] = normvec[i].yp / lengthp[i];
normalized[i].xp = Normalizedxp[i];
normalized[i].yp = Normalizedyp[i];
}
return 0;
}
double ProjectPoints(double verts_x[], double verts_xp[], struct flipped_y flip_y[], struct Normalized normalized[], int numpts) {
int i = 0, g = 0; double dot[20], dotp[20], dotrhomonpoly2norm[20], dotplayeronpoly2norm[20];
for (i = 0; i < numpts; i++) {
for (g = 0; g < numpts; g++) {
//polygon one projection of both polys verts
dot[i * numpts + g] = ((verts_x[g] * normalized[i].x) + (flip_y[g].y * normalized[i].y));
project[i * numpts + g].pts = dot[i * numpts + g];
//player
dotp[i * numpts + g] = ((verts_xp[g] * normalized[i].x) + (flip_y[g].yp * normalized[i].y));
project[i * numpts + g].ptsp = dotp[i * numpts + g];
//polygon two projection of both polys verts double ptspoly2rhom;double ptspoly2player;
dotrhomonpoly2norm[i * numpts + g] = ((verts_x[g] * normalized[i].xp) + (flip_y[g].y * normalized[i].yp));
project[i * numpts + g].ptspoly2rhom = dotrhomonpoly2norm[i * numpts + g];
//player
dotplayeronpoly2norm[i * numpts + g] = ((verts_xp[g] * normalized[i].xp) + (flip_y[g].yp * normalized[i].yp));
project[i * numpts + g].ptspoly2player = dotplayeronpoly2norm[i * numpts + g];
//dotplayeronpoly2norm[i * numpts + g] = ((verts_xp[g] * normalized[i].xp) + (flip_y[g].yp * normalized[i].yp));
//project[i * numpts + g].ptspoly2player = dotplayeronpoly2norm[i * numpts + g];
dotplayeronpoly2norm[16] = ((verts_xp[3] * normalized[3].xp) + (flip_y[3].yp * normalized[3].yp));
}
}
return 0;
}
double Compareminandmax(double max[], double maxp[], double min[], double minp[], double maxon2[], double maxpon2[], double minon2[], double minpon2[], int nummaxmin) {
int i=0;
/*amin<bmax and amin>bmin
or
bmin<amax and bmin> amin*/
for (i = 0; i < nummaxmin;i++) {
/* if ((min[i] < maxp[i] && min[i] > minp[i] || minp[i] < max[i] && minp[i] > min[i]) ||
(minon2[i] < maxpon2[i] && minon2[i] > minpon2[i] || minpon2[i] < maxon2[i] && minpon2[i] > minon2[i])) {
return 2;
}*/
if (((min[i]<maxp[i] && min[i]>minp[i]) || (minp[i]<max[i] && minp[i]>min[i])) ||
((minon2[i]<maxpon2[i] && minon2[i]>minpon2[i]) || (minpon2[i]<maxon2[i] && minpon2[i]>minon2[i]))) { return 22; }
}
return 4;}
现在我已经尝试使用不等式公式,但是出了点问题,我一直在检查并修复一些问题,并且通过 if 语句中的一些不等式,我可以在某种程度上接近正确的碰撞。像这样
到目前为止,我无法检测到我做错了什么,并且我已经使用图形计算器仔细检查了我的点积标准化。如果您有任何建议或更简单的方法,请告诉我。但一旦我做对了,我就会简化和组织很多事情。
好吧好吧,事实证明我可能已经正确了好几次了。但这是正确的条件
if ((minpon2[i]<minon2[i] && maxpon2[i]<minon2[i] || maxpon2[i]>maxon2[i] && minpon2[i]>maxon2[i]) ||
(min[i]>maxp[i] && min[i]>minp[i] || max[i]<minp[i] && max[i]<maxp[i])) { return 22; }
}
事实证明,问题是,当我的条件正确并且我注意到向下移动的碰撞时,我正在为我的玩家使用另一组顶点,这些顶点我曾用于其他目的。它在播放器上比我认为我正在使用的碰撞盒高出 100 像素。我认为我做得很好,因为这通常是我刚刚扫描过的一个简单问题。我肯定会简化我的代码并摆脱我一直在尝试的所有垃圾。