[英]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.