簡體   English   中英

Javascript Platformer沖突檢測

[英]Javascript platformer collision detection

因此,這個問題可能之前曾被問過幾次,但我似乎找不到找到使碰撞檢測正常工作的方法。

我正在嘗試制作HTML canvas / Javascript平台游戲。 如果您想查看它的功能,則在codepen上: https ://codepen.io/Arthurvanhoorebeke/pen/zpaZYM

我正在做的是檢查播放器的角在哪個圖塊/“框”中。 這意味着我可以對播放器上方和下方的塊進行檢測,但是橫向檢測非常糟糕。

我知道對底部碰撞的檢查是使橫向檢測混亂的原因,但是我似乎無法修復它。 這就是我現在得到的:

function tileCheck(world){
  var player_topy = Math.ceil(player1.pos[1] / world.squareHeight) || 0;
  var player_bottomy = Math.ceil((player1.pos[1]+player1.height)/world.squareHeight) || 0;
  var player_leftx = Math.floor(player1.pos[0]/world.squareWidth) || 0;
  var player_rightx = Math.floor((player1.pos[0]+player1.width)/world.squareWidth) || 0;

  var topRightBlock = getSquare(world1,player_rightx,player_topy-1); 
  var topLeftBlock = getSquare(world1,player_leftx,player_topy-1);
  var bottomRightBlock = getSquare(world1,player_rightx,player_bottomy-1);
  var bottomLeftBlock = getSquare(world1,player_leftx,player_bottomy-1);
  //checks if blocks are solid
  var topRightSol = world.legend[topRightBlock].solid;
  var topLeftSol = world.legend[topLeftBlock].solid;
  var bottomRightSol = world.legend[bottomRightBlock].solid;
  var bottomLeftSol = world.legend[bottomLeftBlock].solid;

  //This kinda messes up my 'sideways collision detection'.
  if((bottomRightSol && !topRightSol) || (bottomLeftSol && !topLeftSol)){
    player1.pos[1] -= (player1.pos[1]+player1.height) - (player_bottomy-1)*world.squareHeight;
    player1.vel[1] = 0;
    player1.grounded = true;
  }
  else{
    player1.grounded = false;
    }
  if((topLeftSol && !bottomLeftSol) || (topRightSol && !bottomRightSol)){
    player1.pos[1] += player_topy*world.squareHeight - player1.pos[1];
    player1.vel[1] = 0;
  }
  //This doesn't work properly.
  if(topLeftSol && bottomLeftSol){
    player1.vel[0] = 0;
    player1.wallLeft = true;
    player1.pos[0] += (player_leftx+1)*world.squareWidth - player1.pos[0];
  }
  else{player1.wallLeft = false}
  if(topRightSol && bottomRightSol){
    player1.vel[0] = 0;
    player1.wallRight = true;
    player1.pos[0] -= (player1.pos[0]+player1.width) - (player_rightx)*world.squareWidth;
  }
  else{player1.wallRight = false}
}

我知道只有當玩家方塊的一個角碰到其他東西時,才能進行橫向檢測。 問題是,當玩家擊中障礙物時,底部碰撞檢查器會更改其垂直位置(至少我認為是問題所在)。

如果您想查看確切的問題,請嘗試打開Codepen鏈接並跳一下...

是否有此修復程序,還是我需要重新考慮整個功能?

完全重新考慮。 借助碰撞檢測,其思想是預測一條路徑,該路徑既適用於2d又適用於3d,並且暗示了更多的完整模擬,然后,如果路徑被阻塞,您必須找到(最重要的是經常錯過)碰撞點。 因此,在2d中使用盒子時,它變得微不足道。 計算帶有XY分量的軌跡向量。 然后測試每個盒子是否發生碰撞,如果很多盒子都使用實例檢測球,則只需檢查它們之間的距離即可確定是否存在碰撞,並達到一個碰撞點。 然后,沖擊矢量將用作角色的下一個位置。 這樣可以在邊緣反彈並反彈。 希望我能幫上忙。 否則,請指定任何錯誤,您的代碼將簽出。

也許您想嘗試更改此設置:

if((bottomRightSol || !topRightSol) || (bottomLeftSol && !topLeftSol)){

對此:

if((bottomRightSol || bottomLeftSol) && (!topRightSol && !topLeftSol)){

所不同的是,如果我正確地理解了您的代碼,那么現在您將檢查以確保您至少在一個角上與地面相撞,然后確保不與角上的任何物相撞。 我認為這應該可以防止玩家在空中時被放倒。


編輯以下評論:

//This kinda messes up my 'sideways collision detection'.
  if((bottomRightSol && !topRightSol) || (bottomLeftSol && !topLeftSol)){
    player1.pos[1] -= (player1.pos[1]+player1.height) - (player_bottomy-1)*world.squareHeight;
    player1.vel[1] = 0;
    player1.grounded = true;
  }
  else{
    player1.grounded = false;
    }
  if((topLeftSol && !bottomLeftSol) || (topRightSol && !bottomRightSol)){
    player1.pos[1] += player_topy*world.squareHeight - player1.pos[1];
    player1.vel[1] = 0;
  }

我已經建議修復該if語句。 第二個較低的位置我將更改為以下內容:

if((topLeftSol || topRightSol) && (!bottomLeftSol && !bottomRightSol)){

基本上與上述相同,但現在檢查上限。 希望這可以幫助。

順便說一句,盡管我相信這些解決方案是正確的,但是按照建議,無論如何重寫該函數都沒有害處。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM