2011-02-10 68 views
0

我試圖按照本教程http://www.tonypa.pri.ee/tbw/tut05.html在基於圖塊的世界中實現實時碰撞。基於圖塊的2D碰撞檢測問題

我覺得感謝我的實體的中心座標這些屬性:

public float CenterX 
{ 
    get { return X + Width/2f; } 
    set { X = value - Width/2f; } 
} 
public float CenterY 
{ 
    get { return Y + Height/2f; } 
    set { Y = value - Height/2f; } 
} 

然後在我的更新方法,在播放器類,它被稱爲每一幀,我有這樣的代碼:

public override void Update() 
{ 
    base.Update(); 

    int downY = (int)Math.Floor((CenterY + Height/2f - 1)/16f); 
    int upY = (int)Math.Floor((CenterY - Height/2f)/16f); 
    int leftX =  (int)Math.Floor((CenterX + Speed * NextX - Width/2f)/16f); 
    int rightX = (int)Math.Floor((CenterX + Speed * NextX + Width/2f - 1)/16f); 

    bool upleft = Game.CurrentMap[leftX, upY] != 1; 
    bool downleft = Game.CurrentMap[leftX, downY] != 1; 
    bool upright = Game.CurrentMap[rightX, upY] != 1; 
    bool downright = Game.CurrentMap[rightX, downY] != 1; 

    if(NextX == 1) 
    { 
     if (upright && downright) 
      CenterX += Speed; 
     else 
      CenterX = (Game.GetCellX(CenterX) + 1)*16 - Width/2f; 
    } 
} 

downY,upY,leftX和rightX應該分別找到最低的Y位置,最高的Y位置,最左邊的X位置和最右邊的X位置。我想補充+速度* NextX因爲在本教程中了getMyCorners函數被調用,這些參數:

getMyCorners (ob.x+ob.speed*dirx, ob.y, ob); 

的GetCellX和GetCellY方法:

public int GetCellX(float mX) 
{ 
    return (int)Math.Floor(mX/SGame.Camera.TileSize); 
} 
public int GetCellY(float mY) 
{ 
    return (int)Math.Floor(mY/SGame.Camera.TileSize); 
} 

的問題是球員「閃爍」,同時擊中一個牆壁,角落檢測甚至不能正常工作,因爲它可以重疊僅撞擊其中一個角落的牆壁。我不明白什麼是錯的。在教程中,ob.x和ob.y字段應該與我的CenterX和CenterY屬性相同,ob.width和ob.height應該與Width/2f和Height/2f相同。但它仍然不起作用。

感謝您的幫助。

+4

如果你沒有得到堆棧溢出的迴應,你可能想嘗試http://gamedev.stackexchange.com/ - 這是一個遊戲開發者專用的網站。也就是說,我會花一些時間,看看你首先得到什麼樣的迴應。 :-) – 2011-02-10 22:18:13

+0

你的實體的維度是什麼?只有在實體的尺寸小於或等於瓦片尺寸時,此方法纔有效。 – Weeble 2011-02-10 23:04:06

回答

1

編輯 - 糟糕,你是對的。 CenterX是一個像素座標,GetCellX將其轉換爲平鋪座標,因此代碼是等效的。這確實特別難以遵循。

在這一點上,我開始認爲我們沒有足夠的信息來回答你的問題。這裏有一些想法:

速度是一個整數?你的座標是整數嗎?看起來像是可以將0.5個像素傳遞到牆上而不會發生碰撞,但是當您傳入1.0像素時,您會被折回。如果速度和座標都是不會發生的整數,這就是我假設該教程的工作方式,但是如果有任何分數進入,那麼您可能會看到一些抖動。

在base.Update()中發生了什麼重大事件?渲染何時發生?還有其他什麼可以在調用Update()之間移動播放器嗎?

地圖和播放器如何渲染?他們是否有可能被意外地錯誤地放在相對的地方?我不認爲這會導致你的閃爍問題,但它可能有助於你的碰撞檢測有時讓你通過的問題。

老答案:

本教程不是特別清楚自己:這是相當困難的理解它應該做的事情。如果您有(Game.GetCellX(CenterX) + 1)*16 - Width/2f本教程有(ob.xtile+1)*game.tileW-ob.width。這些不同。該教程需要一個瓦片索引,添加一個以獲取下一個瓦片,然後轉換爲x座標。您的代碼需要瓦片索引,轉換爲x座標,然後添加一個像素。這可能至少是你的閃爍的部分原因。

1

很難說出這裏發生了什麼。如果可能的話,你可以試着縮小這個問題的範圍,告訴我們你的一些幻數和變量是什麼意思。但是從我自己的碰撞檢測經驗來看,你的玩家可能會閃爍,因爲代碼正在將他的位置移動到牆上,並且由於不允許將其重置。碰撞檢查需要在獲得輸入後完成,並在之前更新位置。
是這樣的:(pseudocodish ..)

if(input == "right" && !(Tile.right.collidable)) 
    { 
     //vector.speed = {1, 0, 0}; 
    } 
else 
{ 
//vector.speed = {0, 0, 0}; 
} 


也許不完全是這樣,但我希望它能幫助。乾杯〜