2014-09-06 1 views
1

У меня возникли проблемы с обнаружением столкновения в моей игре. Похоже, что обнаружение столкновения работает только часть времени только на некоторых стенах. Я использую slick2d для своей библиотеки. Если вам нужен еще какой-либо код или информация, я могу передать его вам. Мне нужно идти куда-то прямо сейчас, поэтому я просто набираю это быстро, но если вам нужно что-то еще, просто спросите.Обнаружение столкновения в 2D среде с помощью Slick

Код:

@Override 
public void manageWallCollision(Scene currScene) { 
    for(int i = 0; i < currScene.getMapManager().getWalls().size(); i++){ 
    MapTile currTile = currScene.getMapManager().getWalls().get(i); 

     if(currTile.isCollidable()){ 
      if(this.getBounds().intersects(currTile.getBounds())){ 
       //bottom 
       if(this.y2 < currTile.getY()){ 

       } 
       //right 
       else if(this.x2 < currTile.getX()){ 

       } 
       //left 
       else if(this.y > currTile.getY2()){ 

       } 
       //top 
       else if(this.x > currTile.getX()){ 

       } 
       break; 
      } 
     } 
    } 
} 

Любая помощь приветствуется. Благодарю.

Новый код:

for(int i = 0; i < currScene.getMapManager().getWalls().size(); i++){ 
     MapTile currTile = currScene.getMapManager().getWalls().get(i); 

     if(currTile.isCollidable()){ 
      if(this.getBounds().intersects(currTile.getBounds())){ 
       //down 
       if(this.y2 < currTile.getY() && this.y < currTile.getY2() && this.y2 < currTile.getY2()){ 
        this.setY(currTile.getY() - this.getHEIGHT()); 
       } 
       //up 
       if(this.y < currTile.getY2() && this.y2 > currTile.getY() && this.y2 > currTile.getY2()){ 
        this.setY(currTile.getY2()); 
       } 
       //right 
       if(this.x2 < currTile.getX() && this.x < currTile.getX2() && this.x2 < currTile.getX2()){ 
        this.setX(currTile.getX() - this.getWIDTH()); 
       } 
       //left 
       if(this.x < currTile.getX2() && this.x2 > currTile.getX() && this.x2 > currTile.getX2()){ 
        this.setX(currTile.getX2()); 
       } 

      } 
     } 
    } 

Я до сих пор возникают проблемы. Он обнаруживает мелкий столкновение, но везде, где он попадает на конкретную стену, он переходит в одно и то же место. Представьте себе 2-й номер. Поэтому, если он столкнулся с левой стеной, он автоматически переходит в положение на этой стене. И если вы попытаетесь скользить по стене, тогда она становится действительно глючной, и вы постоянно двигаетесь вперед, а затем назад. Я смущен, что происходит.

ответ

2

Обнаружение столкновений в Slick2d на самом деле намного сложнее, чем люди думают сначала. Прежде всего, стандартный метод для обращения к точкам X и Y в прямоугольнике выглядит следующим образом: X1 является наименьшим Значение X, содержащееся в пределах прямоугольника, и X2 является наибольшим. То же самое касается Y (помните, что наименьшее значение Y находится на top прямоугольника).

Ваш код не работает по нескольким причинам, как аннотированных на нем:

if(currTile.isCollidable()){ 
     if(this.getBounds().intersects(currTile.getBounds())){ 
      if(this.y2 < currTile.getY()){ 

       /*This will only return true as long as 
       the player intersects the tile and his greatest 
       Y value is less than the smallest Y value of the box. 

       This is not actually possible if you think about it as 
       the greatest Y value must in some way be contained by the 
       box for a bottom side collision.*/ 

      } else if(this.x2 < currTile.getX()){ 

       /*The same can be said for all of your other conditionals. 
       As in, all of your conditionals CANNOT be true if the boxes 
       intersect and therefore your collision code will not work.*/ 

      } else if(this.y > currTile.getY2()){ 

      } else if(this.x > currTile.getX()){ 

      } 
      break; 
     } 
    } 

Это все сказанное, пытаясь разработать систему совершенной столкновения быстро/эффективный пиксель практически невозможно (я пытался и не смог много раз). Вот рабочий пример; однако вам придется добавить дополнительный код, который я объясню. Кроме того, это проверка того, что бы добавить к классу MapTile и вызывается из вашего метода обновления:

public void checkCollision(Scene s) { 
    //Down 
    if (s.player.getMaxY() > this.getMinY() && 
       s.player.getMinY() < this.getMinY() && 
       s.player.x + s.player.width > this.x && s.player.x < this.getMaxX()) { 

      s.player.y = this.y - s.player.height; 

      /*Checks to see if the player intersects moving downwards. If the 
      player is colliding the code moves the player to look as if it stopped 
      perfectly rather than moving slightly inside of the wall*/ 

    //Up 
    } else if (s.player.getMinY() < this.getMaxY() && 
       s.player.getMaxY() > this.getMaxY() && 
       s.player.x + s.player.width > this.x && s.player.x < this.getMaxX()) { 

      s.player.y = this.y + this.height; 

    //Left 
    } else if (s.player.getMinX() < this.getMaxX() && 
       s.player.getMaxX() > this.getMaxX() && 
       s.player.intersects(this)) { 

      s.player.x = this.x + this.width; 

    //Right 
    } else if (s.player.getMaxX() < this.getMinX() && 
       s.player.getMinX() > this.getMinX() && 
       s.player.intersects(this)) { 

      s.player.x = this.x - s.player.width;    

    } 
} 

Я делал игры в течение нескольких лет с Slick2d и до сих пор это самый лучший способ, которым я нашли что-то делать. s.player, представляющий главного героя игры, и это представляет собой плитку. Надеюсь, это поможет :)

+0

Хорошо спасибо за ответ. Мне просто нужно взглянуть на это кратко, потому что я должен пойти куда-нибудь, но через несколько часов я посмотрю на это более подробно. Спасибо за помощь. – user2280906

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