2016-07-28 2 views
0

Я пытался выяснить, как остановить моих врагов от перекрытия друг друга на прошлой неделе. Я использую связанный список врагов. Я прокручиваю список и устанавливаю позицию oldX и oldY, в которой я хочу, чтобы зомби возвращался обратно, если они перекрываются. Моя проблема заключается в том, что в начале обнаружение столкновения работает, но в конечном итоге они заканчиваются и слипающимися, и не движущимися, нижнее изображение показывает состояние, в котором они находятся. Они просто склеиваются и не двигаются. Если кто-нибудь может помочь мне с этим или объяснить, как управлять такого рода обнаружением столкновений, это было бы здорово, поскольку я не могу найти ничего, что бы четко объясняло, как это делается!Как остановить врагов, перекрывающих java

enter image description here

Это мой основной метод AI для перемещения зомби, он проверяет, чтобы увидеть, если нет столкновения со стеной, а затем проверяет, что зомби перекрывается с любой другой. Затем перемещает зомби на основе позиции игроков.

public void moveZombie(){ 
     for(Zombie zombie : c.z) 
     { 
      oldX = zombie.getX(); 
      oldY = zombie.getY(); 

      if(player.getX() > zombie.getX()){ 
       if(wallCollision(zombie.getX()+1, zombie.getY()) == false){ 
        if(zombiesCollision(zombie) == false){ 
         zombie.setX(zombie.getX() + 1); 
        } 

       } 
      } 

      if(player.getX() < zombie.getX()){ 
       if(wallCollision(zombie.getX()-1, zombie.getY()) == false){ 
        if(zombiesCollision(zombie) == false){ 
         zombie.setX(zombie.getX() - 1); 
        } 


       } 
      } 

      if(player.getY() > zombie.getY()){ 
       if(wallCollision(zombie.getX(), zombie.getY()+1) == false){ 
        if(zombiesCollision(zombie) == false){ 
         zombie.setY(zombie.getY() + 1); 
        } 

       } 
      } 

      if(player.getY() < zombie.getY()){ 
       if(wallCollision(zombie.getX(), zombie.getY()-1) == false){ 
        if(zombiesCollision(zombie) == false){ 
         zombie.setY(zombie.getY() - 1); 
        } 
       } 
      } 
     } 

} 

Это мой булевский метод, который проверяет, сталкиваются ли зомби. Он вызывается из моего метода move() выше и принимает в качестве параметра текущий зомби из цикла выше. Затем он проверяет, пересекаются ли они. Если они делают положение x и y зомби, установлено в положение oldX и oldY и возвращает true. Если было пересечение, я попробовал zombie.x -= 32; и zombie.y -=32. который работает, но он очень глючный, и они часто застревают в стенах, я хочу знать, как я могу в любой момент переместить зомби обратно в его прежнее положение.

public boolean zombiesCollision(Zombie zombie){ 

      for(Zombie zombie2 : c.z){ 
        if(zombie != zombie2){ 
         if(zombie2.getZombieBounds().intersects(zombie.getZombieBounds())){ 
          zombie.x = oldX; 
          zombie.y = oldY; 
          return true; 
         } 
        } 
      } 

     return false; 
} 
+0

Ваш «мир» установил границы, или это открытый мир? Например, ваш мир похож на 10x10? – RayfenWindspear

+0

это карта плитки размером 70x40. каждая плитка 32x32 пикселей. – Phill

ответ

0

Учитывая карту со статическими границами, я хотел бы предложить вам сохранить двухмерную булеву массив зомби позиций, наряду с текущими настройками. Тогда обнаружение столкновения может быть упрощено от цикла до простого поиска массива.

Кроме того, в вашем методе moveZombie на самом деле не выполняйте движение до конца функции. Что-то вроде этого псевдокода.

public void moveZombie(){ 
    for(Zombie zombie : c.z) 
    { 
     newX = zombie.getX(); 
     newY = zombie.getY(); 

     if(player.getX() > zombie.getX()){ 
      if(wallCollision(zombie.getX()+1, zombie.getY()) == false){ 
       if(zombiesCollision(zombie.getX()+1,zombie.getY()) == false){ 
        newX += 1; 
       } 

      } 
     } 

     if(player.getX() < zombie.getX()){ 
      if(wallCollision(zombie.getX()-1, zombie.getY()) == false){ 
       if(zombiesCollision(zombie.getX()-1,zombie.getY()) == false){ 
        newX -= 1; 
       } 


      } 
     } 
     // with newX finalized, we need to use it for checks instead of the "current" value 
     if(player.getY() > zombie.getY()){ 
      if(wallCollision(newX, zombie.getY()+1) == false){ 
       if(zombiesCollision(newX,zombie.getY()+1) == false){ 
        newY += 1; 
       } 

      } 
     } 

     if(player.getY() < zombie.getY()){ 
      if(wallCollision(newX, zombie.getY()-1) == false){ 
       if(zombiesCollision(newX,zombie.getY()-1) == false){ 
        newY -= 1; 
       } 
      } 
     } 
     // update position and location array 
     zombieArray[zombie.getX()][zombie.getY()] = false; 
     zombieArray[newX][newY] = true; 
     zombie.setX(newX); 
     zombie.setY(newY); 
    } 
} 

Тогда ваш zombiesCollision просто был бы.

public boolean zombiesCollision(int x, int y){ 
    return zombieArray[x][y]; 
} 
+0

Упс, поймал ошибку ... исправление. См. Новый комментарий. – RayfenWindspear

+0

Итак, это ответ на ваш вопрос или нет? Если да, примите это как ответ. – RayfenWindspear

Смежные вопросы