java 你如何确保两个球在碰撞后被移走?

o2gm4chl  于 2023-01-07  发布在  Java
关注(0)|答案(1)|浏览(185)

我是一个初学者,我正在用Netbeans做一个太空射击游戏。我想如果飞船的子弹击中敌人的子弹,那两颗子弹就被移除。我创建了一个子弹和bulletsEnemy的数组列表。然后我创建了一个hitByBullet方法,它应该确保我可以搜索到碰撞的子弹。然后在bulletsHit()方法中,子弹应该被移除。
我的敌人都是打圈,一动不动,我的问题是子弹互相穿过去,子弹的半径是5。

这是我编写的两个方法

'''

public int hitByBullet(){
   for(int i=0; i<bullets.size(); i++){
       for(int j= 0;j< bulletsEnemy.size(); j++){
          if( bullets.get(i).getY() - bulletsEnemy.get(j).getY()<= 5)
           if(bullets.get(i).getX() -bulletsEnemy.get(j).getX()<= 5){ 
           return i;
           }
       }
        
   }
   return -1;
}

'''

public boolean bulletsHit(){
     if (hitByBullet()!= -1){               
         bullets.remove(this);  //with 'this' I refer too 'i'
         bulletsEnemy.remove(this);
         return true;
     }
     return false;
}

'''

[This is how it looks like] (https://i.stack.imgur.com/4XsCR.png)
vc9ivgsu

vc9ivgsu1#

我会尝试用一种方式来回答,让你找到你想要的实现方式。有几个框架可以帮助你,因为你是编程新手,有很多事情你可以改变/做得更好。但我会忽略这些事情。
我想你是想检查一颗5 × 5的子弹是否和另一颗5 × 5的子弹相交。
为了简单起见我们假设你的子弹是正方形
在你的hitByBullet中,你应该检查你的正方形中心(假设是你的子弹的x,y)在两个维度上的距离:
像这样的Sth.应该检查碰撞:

if(Math.abs(bullets.get(i).getY() - bulletsEnemy.get(j).getY()) < 5 && 
    Math.abs(bullets.get(i).getX() - bulletsEnemy.get(j).getX()) < 5) { 
       return i;
}

根据你的子弹大小你需要改变距离检查(〈=5)。如果你的子弹大小为5像素,它应该〈10。如果你的子弹大小为10 x10,你应该检查〈20...
关于一个更现实的场景,你的项目符号是圆(例如,5x 5正方形px或半径r=5的结果):
您需要检查两个子弹中心之间的距离是否小于子弹半径 * 2。
这将使你使用毕达哥拉斯定理:

https://en.wikipedia.org/wiki/Pythagorean_theorem
子弹中心之间的距离是c,a是x维的距离,b是y维的距离,你不需要关心负的维值,因为你需要把它们乘以2,这总是会给予你一个正值。
要检查碰撞,应按如下方式计算距离c:
c =(a^2+b^2)的平方根

Math.sqrt(Math.pow(bullets.get(i).getX() - bulletsEnemy.get(j).getX()),2) + Math.pow(bullets.get(i).getY() - bulletsEnemy.get(j).getY(),2)) < 10

我认为你应该阅读碰撞检测和几何学的基础知识。只有两个可能的信息点:
一个简单的代码示例:
https://zetcode.com/javagames/collision/
圆形交叉点:
https://www.geeksforgeeks.org/check-two-given-circles-touch-intersect/
关于子弹的移除,我想你有某种游戏循环,在其中频繁地绘制子弹并计算碰撞(调用bulletsHit方法):
我将做一个假设,使事情变得简单:子弹的移动速度不能超过一个像素。否则我认为你需要注意你的循环时间,计算所有元素的位置,还要注意那些不会在一个循环中相交的子弹,因为它们可能已经从一个循环到下一个循环了。我对游戏开发不熟悉,所以可能有更多的事情需要讨论。
关于这一点,你应该改变的东西:
1.方法hitByBullet()每次调用只返回一个碰撞。你可以将你的collidedBullet存储在两个集合中,然后在从你的bullets和bulletsEnemy列表中删除它们之后清除这些临时集合。
1.我不明白你在用“这个”和你的hitByBullet结果做什么。
我会这样做

public void hitByBullet(){
  for(int i=0; i<bullets.size(); i++){
   for(int j= 0;j< bulletsEnemy.size(); j++){
      if( Math.sqrt(Math.pow(bullets.get(i).getX() - bulletsEnemy.get(j).getX()),2) + Math.pow(bullets.get(i).getY() - bulletsEnemy.get(j).getY(),2)) < 10){ 
         bulletsToDelete.add(bullets.get(i));
         bulletsEnemyToDelete.add(bulletsEnemy.get(j));
       }
     }
   }
}

public boolean bulletsHit(){
   hitByBullet();
   bulletsToDelete.forEach(bullet -> bullets.remove(bullet);
   bulletsEnemyToDelete.forEach(bullet -> bulletsEnemy.remove(bullet);
   boolean bulletsHit = !bulletsToDelete.isEmpty();
   bulletsToDelete.clear();
   bulletsEnemyToDelete.clear();
   return bulletsHit;
}

正如我之前提到的,有很多事情你应该改进:

  • 代码的一般结构
  • 方法的命名(例如,bulletsHit听起来像是只检查是否命中了项目符号,但同时也删除了它们)
  • 复查子弹

问候

相关问题