修复许多精灵碰撞时发生的错误

时间:2013-04-26 12:50:11

标签: java double game-physics collision

在我正在制作的游戏中,我已经做到了让僵尸无法相互通过。我用这段代码做了这个。

for(int i = 0; i < zombies.size(); i++){
                Zombie z = (Zombie) zombies.get(i);
                zombieMovement();
                for(int j = i + 1; j < zombies.size(); j++){
                    Zombie z2 = (Zombie) zombies.get(j);
                    Rectangle r1 = z.getBounds();
                    Rectangle r2 = z2.getBounds();
                    if(r1.intersects(r2)){
                        z.setX(z.getX() - 1);
                        z.setY(z.getY() - 1);
                        z2.setX(z2.getX() + 1);
                        z2.setY(z2.getY() + 1);
                    }
                }
            }

zombieMovement方法看起来像这样。

public void zombieMovement(){
        for(int i = 0; i < zombies.size(); i++){ 
            Zombie z = (Zombie) zombies.get(i);
            if(z.getY() > player.getY()){
                z.setY(z.getY() - .01);
            }
            if(z.getY() < player.getY()){
                z.setY(z.getY() + .01);
            }
            if(z.getX() > player.getX()){
                z.setX(z.getX() - .01);
            }
            if(z.getX() < player.getX()){
                z.setX(z.getX() + .01);
            }
            if(z.isAlive()){
                z.move();
            }else{ 
                zombies.remove(i);
            }
        }
    }

因为当他们彼此接触时僵尸的移动速度提高了10倍,所以前几个僵尸的移动速度比后来的移动速度快,因为他们与更多的僵尸接触(我无法确定它们的速度有多快)当他们彼此接触到任何更少时移动,因为他们仍然可以在彼此内部,我不希望僵尸比他们已经做的更快地移动。

有没有简单的方法来修复此错误?

2 个答案:

答案 0 :(得分:0)

当僵尸被四面包围并且你必须移动它时会发生什么?

对于一个非常强大的解决方案,我会做一个同时的约束求解器。从本质上讲,你可以把它想象成在每个碰撞的僵尸之间放一个弹簧并迭代直到每个人都不再相交。你可能想对位移设置上限,以确保你不会偶然让僵尸射入太空。

不幸的是,这种方法需要复杂的数学运算。我认为Box2d有一些在线幻灯片解释其算法的基础。或者您可以使用现有的物理引擎,如Box2d。

答案 1 :(得分:0)

而不是尝试修复重叠的僵尸,而不是首先在zombieMovement()方法中阻止问题。当僵尸移动到你的位置时,你应该测试它的新位置(+/- .01位)是否已被占用,如果是,那么就不要将僵尸移动到那个位置。

/**
* Returns true if the point x,y is already occupied by a zombie
*/
boolean isOccupied(double x, double y) {
  for (Zombie z : zombies) {
    if (z.getBounds().contains(new Point(x,y))) {
      return true;
    }
  }
  return false;
}

然后你可以像这样测试你的运动方法;

if (z.getY() > player.getY()) {
  double newY = z.getY() - .01;
  if (!isOccupied(z.getX(), newY) {
    z.setY(newY);
  {
}