繁体   English   中英

Java碰撞秋千从侧面无法正常工作

[英]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

当我测试我的应用程序时,当我从侧面击打集团时,球会执行不同的动作。 它通过整个集团,因此它的命中次数是无限的,所以我认为这就是为什么集团立即消失的原因,所以我的问题是:当我从侧面击打集团时,为什么我没有得到反弹?

嗯,我又看了一下您的代码,可能发现了错误(调试应确认这一点):您的情况似乎正在检查球是否在障碍物之外

假设BallBloc是摆动分量,则坐标0/0表示左上角,因此正y向下。

因此,块的边缘可以部分定义为

  • 顶部:block.y
  • 底部:block.y + block.height
  • 左:block.x
  • 右:block.x + block.width

现在,让我们可视化您的条件,该条件仅在球和块的边界相交时才适用:

  1. “以下”:ball.y <= block.y + bloc.height
  2. “上方”:ball.y + ball.height> = block.y
  3. “左”:ball.x + ball.width <= block.x
  4. “右”:ball.x> = block.x + block.width

为简单起见,我们假设球只是一个点,即with和height为1。因此,我们将忽略球的大小,仅使用其位置(无论如何代表球的像素)并简化方程式(可能是减少1 btw):

  1. “以下”:ball.y <= block.y + bloc.height
  2. “上方”:ball.y> = block.y
  3. “左”:ball.x <= block.x
  4. “右”:ball.x> = block.x + block.height

现在,让我们用一些箭头可视化它们,以指出它们将在哪里正确:

   +----------+  ---
   |          |   | (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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM