2014-09-06 24 views
1

我在檢測遊戲中的碰撞時遇到了一些麻煩。似乎碰撞檢測只在部分牆上進行。我正在使用slick2d作爲我的圖書館。如果你需要更多的代碼或信息,我可以給你。我現在必須去某個地方,所以我只是快速輸入,但如果你需要更多的東西,請問。使用Slick檢測2D環境中的碰撞

代碼:

@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()); 
       } 

      } 
     } 
    } 

我仍然有問題。它檢測到的碰撞很好,但是碰到特定牆壁的任何地方碰到相同的地方。想象一下2d的房間。因此,如果它與左側牆相撞,它會自動轉到該牆上的某個位置。如果你嘗試沿着牆壁滑動,那麼它會變得非常糟糕,你會不斷前進,然後向後移動。我對發生的事情感到困惑。

回答

2

Slick2d中的碰撞檢測實際上比人們首先想到的要困難得多。首先引用矩形中X和Y點的標準方法如下:X1是包含在矩形內的最小值的最小值,X2是最大的值。 Y也是一樣(記住最小的Y值在矩形的頂部)。

您的代碼不會對下注釋就可以了幾個原因有:

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 2014-09-06 13:22:25