Java 二维多边形 - 多边形碰撞检测
Java 2D Polygon - Polygon Collision Detection
最近我一直在使用 Polygon class 来创建小行星以及子弹和宇宙飞船。我目前正在尝试为程序创建碰撞检测,但是碰撞检测似乎只在大约 1/5 的时间内起作用(没有模式显示它为什么起作用)。
这是代码..
创建多边形:
void renderPoly() {
int j;
int s = sides;
double r, angle;
int x, y;
for (j = 0; j < s; j++) {
angle = 2 * Math.PI / s * j;
r = MIN_ROCK_SIZE + (int) (Math.random() * (MAX_ROCK_SIZE - MIN_ROCK_SIZE));
x = (int) (r * Math.cos(angle));
y = (int) (r * -Math.sin(angle));
cOM[0] += x;
cOM[1] += y;
pointData[j][0] = x;
pointData[j][1] = y;
}
cOM[0] /= asteroidShape.npoints;
cOM[1] /= asteroidShape.npoints;
for (int i = 0; i < asteroidShape.npoints; i++) {
pointData[i][0] += cOM[0];
pointData[i][1] += cOM[1];
}
}
旋转和移动多边形:
void move() {
int x, y, i;
//change rotation
theta += rotVel;
//change x
asteroidData[0] += deltaX;
//change y
asteroidData[1] += deltaY;
for (i = 0; i < asteroidShape.npoints; i++) {
x = (int) (pointData[i][0] * Math.cos(theta) - pointData[i][1] * Math.sin(theta) );
y = (int) (pointData[i][0] * Math.sin(theta) + pointData[i][1] * Math.cos(theta) );
asteroidShape.xpoints[i] = x + asteroidData[0];
asteroidShape.ypoints[i] = y + asteroidData[1];
asteroidShape.invalidate();
}
}
检查是否碰到子弹:
boolean hitBullet(Bullet b) {
this.asteroidShape.invalidate();
for (int i = 0; i < b.bulletShape.npoints; i++)
if (this.asteroidShape.contains(b.bulletShape.xpoints[i], b.bulletShape.ypoints[i]) )
return true;
for (int j = 0; j < this.asteroidShape.npoints; j++)
if (b.bulletShape.contains(this.asteroidShape.xpoints[j], this.asteroidShape.ypoints[j]) )
return true;
return false;
}
(除了构造函数需要一个ship对象外ship方法是一样的)
以及在 'game' class 中调用它的循环:
for (int i = 0; i < aArray.length-1; i++) {
if (aArray[i] != null) {
for (int j = 0; j < bArray.length-1; j++) {
if (bArray[j] != null) {
if (aArray[i].hitBullet(bArray[j])) {
aArray[i] = null;
bArray[j] = null;
i = aArray.length-1;
j = bArray.length-1;
}
}
else {
i = aArray.length-1;
j = bArray.length-1;
}
}
}
else {
i = aArray.length-1;
}
}
我一直在寻找替代解决方案,例如分离轴定理,但是我有时确实有凸多边形,并且由于此方法 (.contains()) 已经存在,所以我想使用它。
任何帮助将不胜感激,谢谢!
我发现解决此问题的简单方法是将 Shapes
(在您的情况下为多边形 (2D?))转换为 Areas。您可以使用 Area.intersect(Area) 查看两个区域是否发生碰撞
最近我一直在使用 Polygon class 来创建小行星以及子弹和宇宙飞船。我目前正在尝试为程序创建碰撞检测,但是碰撞检测似乎只在大约 1/5 的时间内起作用(没有模式显示它为什么起作用)。
这是代码.. 创建多边形:
void renderPoly() {
int j;
int s = sides;
double r, angle;
int x, y;
for (j = 0; j < s; j++) {
angle = 2 * Math.PI / s * j;
r = MIN_ROCK_SIZE + (int) (Math.random() * (MAX_ROCK_SIZE - MIN_ROCK_SIZE));
x = (int) (r * Math.cos(angle));
y = (int) (r * -Math.sin(angle));
cOM[0] += x;
cOM[1] += y;
pointData[j][0] = x;
pointData[j][1] = y;
}
cOM[0] /= asteroidShape.npoints;
cOM[1] /= asteroidShape.npoints;
for (int i = 0; i < asteroidShape.npoints; i++) {
pointData[i][0] += cOM[0];
pointData[i][1] += cOM[1];
}
}
旋转和移动多边形:
void move() {
int x, y, i;
//change rotation
theta += rotVel;
//change x
asteroidData[0] += deltaX;
//change y
asteroidData[1] += deltaY;
for (i = 0; i < asteroidShape.npoints; i++) {
x = (int) (pointData[i][0] * Math.cos(theta) - pointData[i][1] * Math.sin(theta) );
y = (int) (pointData[i][0] * Math.sin(theta) + pointData[i][1] * Math.cos(theta) );
asteroidShape.xpoints[i] = x + asteroidData[0];
asteroidShape.ypoints[i] = y + asteroidData[1];
asteroidShape.invalidate();
}
}
检查是否碰到子弹:
boolean hitBullet(Bullet b) {
this.asteroidShape.invalidate();
for (int i = 0; i < b.bulletShape.npoints; i++)
if (this.asteroidShape.contains(b.bulletShape.xpoints[i], b.bulletShape.ypoints[i]) )
return true;
for (int j = 0; j < this.asteroidShape.npoints; j++)
if (b.bulletShape.contains(this.asteroidShape.xpoints[j], this.asteroidShape.ypoints[j]) )
return true;
return false;
}
(除了构造函数需要一个ship对象外ship方法是一样的)
以及在 'game' class 中调用它的循环:
for (int i = 0; i < aArray.length-1; i++) {
if (aArray[i] != null) {
for (int j = 0; j < bArray.length-1; j++) {
if (bArray[j] != null) {
if (aArray[i].hitBullet(bArray[j])) {
aArray[i] = null;
bArray[j] = null;
i = aArray.length-1;
j = bArray.length-1;
}
}
else {
i = aArray.length-1;
j = bArray.length-1;
}
}
}
else {
i = aArray.length-1;
}
}
我一直在寻找替代解决方案,例如分离轴定理,但是我有时确实有凸多边形,并且由于此方法 (.contains()) 已经存在,所以我想使用它。
任何帮助将不胜感激,谢谢!
我发现解决此问题的简单方法是将 Shapes
(在您的情况下为多边形 (2D?))转换为 Areas。您可以使用 Area.intersect(Area) 查看两个区域是否发生碰撞