我正在做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
当我测试我的应用程序时,当我从侧面击打一个方块时,球会执行不同的动作。它通过整个集团,因此它具有无限的命中率,所以我认为这就是集团立即消失的原因,所以我的问题是:当我从侧面击打集团时为什么我没有得到反弹?
答案 0 :(得分:1)
嗯,我又看了一下您的代码,可能发现了这个错误(调试应该确认这一点):您的情况似乎正在检查球是否在块的之外。
假设Ball
和Bloc
是摆动分量,则坐标0/0表示左上角,因此正y向下。
因此,块的边缘可以部分定义为
现在让我们可视化您的条件,该条件仅在球和块的边界相交时适用:
为简单起见,我们假设球只是一个点,即with和height为1。因此,我们将忽略球的大小,而仅使用其位置(始终代表球的像素)并简化方程式(可能会关闭1 btw):
现在让我们用一些箭头来可视化那些箭头,以指示它们在哪里正确:
+----------+ ---
| | | (2)
| Block | V ^
| | | (1)
+----------+ ---
<--| |-->
(3) (4)
现在的主要问题是要按顺序检查这些条件。如果球从侧面击中障碍物会怎样?条件1很可能已经为真,您只需更改y条件。如果它仍在块内,则条件1或2仍然为真,并且您将y条件改回。
但是,条件3和4也存在问题:
由于检查了交叉点,因此,只有当球在左边缘处正确时,原始条件3才成立,这可能根本不会命中。如果再正确一些,条件将不再成立。
我们以一个宽度为5的球和一个x位置为10的块为例。您的条件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时,这才是正确的,但这并不意味着相交。
答案 1 :(得分:0)
在检查@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
}
}