[英]Java collision swing not working from the sides
我在做Java游戏,例如打砖块。 我已经有碰撞检测。 但是,现在我想销毁某些集团,如果它们的HP等于0。如果我触摸我的集团上下或以上,效果很好,每个球将1 HP提升到集团。 但是,如果我从左侧或右侧触摸该集团,则尽管HP离开,该集团也会被摧毁。
每次我碰到一个球团,我都会检查球与球团相比的位置。 但是对于左右,我不明白为什么它不起作用。
我也不确定销毁集团的方式。我的意思是,我将所有集团存储在地图中。 我得到了我的集团的当前浪潮(如此行)。 然后,我将参数中给出的块与该行的所有块进行比较。 那正确吗 ?
for (Ball ball : ballList) {
for (List<Bloc> wave : mapBlocs.values()) {
for (Bloc bloc : wave) {
if (ball.getBounds().intersects(bloc.getBounds())) {
if (ball.getPosY() <= bloc.getPosY() + bloc.getHeight()) {
ball.setVelocityY(-ball.getVelocityY());
ball.setPosY(ball.getPosY() + ball.getVelocityY());
bloc.setHardness(bloc.getHardness() - 1);
System.out.println("below");
} else if (ball.getPosY() + ball.getHeight() >= bloc.getPosY()) {
ball.setVelocityY(-ball.getVelocityY());
ball.setPosY(ball.getPosY() + ball.getVelocityY());
bloc.setHardness(bloc.getHardness() - 1);
System.out.println("above");
} else if (ball.getPosX() + ball.getWidth() <= bloc.getPosX()) {
ball.setVelocityX(-ball.getVelocityX());
ball.setPosX(ball.getPosX() + ball.getVelocityX());
bloc.setHardness(bloc.getHardness() - 1);
System.out.println(bloc.getHardness());
System.out.println("left");
} else if (ball.getPosX() >= bloc.getPosX() + bloc.getWidth()) {
ball.setVelocityX(-ball.getVelocityX());
ball.setPosX(ball.getPosX() + ball.getVelocityX());
bloc.setHardness(bloc.getHardness() - 1);
System.out.println(bloc.getHardness());
System.out.println("right");
}
if (bloc.getHardness() == 0) {
destroyBlocs(bloc);
}
}
}
而我的方法destroyBlocs:
private void destroyBlocs(Bloc bloc) {
List<Bloc> list = mapBlocs.get(bloc.getWaveNumber());
for (Bloc a : list) {
if (a.equals(bloc)) {
list.remove(bloc);
}
}
}
我该如何解决? 并预先感谢您!
@UPDATE
当我测试我的应用程序时,当我从侧面击打集团时,球会执行不同的动作。 它通过整个集团,因此它的命中次数是无限的,所以我认为这就是为什么集团立即消失的原因,所以我的问题是:当我从侧面击打集团时,为什么我没有得到反弹?
嗯,我又看了一下您的代码,可能发现了错误(调试应确认这一点):您的情况似乎正在检查球是否在障碍物之外 。
假设Ball
和Bloc
是摆动分量,则坐标0/0表示左上角,因此正y向下。
因此,块的边缘可以部分定义为
现在,让我们可视化您的条件,该条件仅在球和块的边界相交时才适用:
为简单起见,我们假设球只是一个点,即with和height为1。因此,我们将忽略球的大小,仅使用其位置(无论如何代表球的像素)并简化方程式(可能是减少1 btw):
现在,让我们用一些箭头可视化它们,以指出它们将在哪里正确:
+----------+ ---
| | | (2)
| Block | V ^
| | | (1)
+----------+ ---
<--| |-->
(3) (4)
现在的主要问题是,您正在按顺序检查这些条件。 如果球从侧面击中障碍物会怎样? 条件1很可能已经为真,您只需更改y条件。 如果它仍然在块内,则条件1或2仍然为真,并且您可以将y条件改回。
但是,条件3和4也存在问题:
由于检查了相交点,因此,如果球正确位于左边缘,则原始条件3可能为true,这可能根本不会命中。 如果再正确一些,条件将不再成立。
让我们以一个宽度为5的球和一个x位置为10的块ball.x + ball.width <= block.x
。您的条件ball.x + ball.width <= block.x
因此将是ball.x + 5 <= 10
。 这仅对ball.x <= 5成立。但是,对于任何ball.x <5,您将获得9或更小的右边界,这意味着它不与块相交。
条件4相似:假设块的宽度为20,x位置为10。因此ball.x >= block.x + block.width
变为ball.x >= 30
(10 + 20)。 这意味着只有当球的x位置正好为30时,这才是正确的,但这并不意味着相交。
在检查@Thomas解释后,我得到了以下解决方案:
if (ball.getVelocityX() > 0) {
if (ball.getPosX() < bloc.getPosX()) {
ball.setVelocityX(-ball.getVelocityX());
ball.setPosX(ball.getPosX() + ball.getVelocityX());
bloc.setHardness(bloc.getHardness() - 1);
// left hit
} else {
ball.setVelocityY(-ball.getVelocityY());
ball.setPosY(ball.getPosY() + ball.getVelocityY());
bloc.setHardness(bloc.getHardness() - 1);
// below hit
}
} else {
if (ball.getPosX() < bloc.getPosX() + bloc.getWidth()) {
ball.setVelocityY(-ball.getVelocityY());
ball.setPosY(ball.getPosY() + ball.getVelocityY());
bloc.setHardness(bloc.getHardness() - 1);
// above hit
} else {
ball.setVelocityX(-ball.getVelocityX());
ball.setPosX(ball.getPosX() + ball.getVelocityX());
bloc.setHardness(bloc.getHardness() - 1);
// right hit
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.