【发布时间】:2017-08-07 08:42:17
【问题描述】:
我正在尝试重新创建突破,但块角和球之间的相互作用让我非常头疼。从窗户的边缘和积木弹起效果很好,从窗户的角落弹起也很完美。为简单起见,所有块都是轴对齐的。交换 x 和 y 运动仅适用于 8 个案例中的 2 个。对于其他 6 个,必须反转一个或两个向量才能使碰撞正确,但我无法找到一种简单的方法来做到这一点。写 8 个 if 语句是不正确的,容易引起 bug。
Ball 类是 Ellipse2D.Double 类的扩展。
Block 类是 Rectangle 类的扩展。
我查看的每个问题/答案/教程要么过于复杂(不是 AA 矩形,矩形不在固定位置上),要么是简化(就像两个矩形碰撞一样处理)或完全偏离主题(检测碰撞/重叠,球对球的处理)。
这是我得到的:
public void move(Paddle p, List<Block> b) {
//called every frame
this.x += dx;
this.y += dy;
checkCollisionsWalls();
// checkCollisionPaddle(p);
checkCollisionBlocks(b);
if (this.dir == 90 || this.dir == 270)
this.dir++;
// make sure ball wont get stuck between two walls of window
}
private void checkCollisionBlocks(List<Block> b) {
for (Block block : b) {
if (this.intersects(block)) {
if (this.x + this.width / 2 >= block.x && this.x + this.width / 2 <= block.x + block.width) {
System.out.println("Top / Bot reflect");
this.dy *= -1;
break;
}
if (this.y + this.height / 2 >= block.y && this.y + this.height / 2 <= block.y + block.height) {
System.out.println("Left / Right reflect");
this.dx *= -1;
break;
}
// if execution got here we must have hit a corner
reflectCorner();
}
}
}
private void reflectCorner() {
if (dx > dy) {
this.dy *= -1;
} else {
this.dx *= -1;
}
if (Math.abs(dx) == Math.abs(dy)) {
this.dy *= -1;
this.dx *= -1;
}
double temp = this.dx;
this.dx = this.dy;
this.dy = temp;
temp = 0;
}
dx 和 dy 是 Ball 类中的全局变量,实际上所有代码都(仍然)在 Ball 类中。
编辑:
很抱歉看到提出明确问题的部分,我对此有点激动...
当前代码发生了什么:
从任何方向击中右下角时,反射都能完美发挥作用。
击中左上角会导致球卡在矩形内。然后它沿着边缘游荡到右下角
在平行于 x 轴移动时触摸右上角以及在平行于 y 轴移动时触摸左下角时,球会反射两次,在正 y 或正 x 方向上微动,每次反弹一个像素(它移动到的正交轴)。
所有其他反射都可以正常工作。
应该发生什么:
reflectCorner() 方法应该适用于所有角落,就像它适用于右下角一样,并且不会产生上述结果。
问题: 如何在不使用过于复杂的 if 结构的情况下做到这一点?
如有必要,我可以提供我使用的测试设置。
【问题讨论】:
-
寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建 minimal reproducible example。使用“编辑”链接改进您的问题 - 不要通过 cmets 添加更多信息。谢谢!
-
换句话说:您的问题到底是什么?
标签: java collision game-physics