2017-03-26 77 views
0

我有一個精靈,Player。我更新Player的位置通過以下方式:XNA/Monogame:平臺遊戲跳躍物理和對撞問題

_position += (_direction * _velocity) * (float)gameTime.ElapsedGameTime.TotalSeconds;

_position_direction_velocityVector2秒。

我有一個簡單的對撞機(BoxCollider),它只是生成一個矩形(BoundingBox)給定的對撞機的位置和尺寸。

Initialize()中,我創建了一個新的List<BoxCollider>並填充了關卡的碰撞體。

Update()上,我將該列表傳遞給Player以檢查衝突。

碰撞檢查方法:

public void CheckPlatformCollision(List<BoxCollider> colliders, GameTime gameTime) 
{ 
    var nextPosition = _position + (_direction * _velocity) * (float)gameTime.ElapsedGameTime.TotalSeconds; 
    Rectangle playerCollider = new Rectangle((int)nextPosition.X, (int)nextPosition.Y, BoundingBox.Width, BoundingBox.Height); 
    foreach(BoxCollider collider in colliders) 
    { 
     if(playerCollider.Intersects(collider.BoundingBox)) 
     { 
      nextPosition = _position; 
     } 
    } 
    Position = nextPosition; 
} 

現在,每次我試圖執行重力的方式失敗。如果Player從太高的位置下降,nextPositionPlayer太遠,並使其卡在空中。

我也遇到了水平碰撞的問題,問題相似:Player停止得太快,在它們之間留下一個空格。有時候我已經把Player貼在對撞機的一側。

我想知道的是:

如何正確執行重力&與_position_direction,並且_velocity跳?我如何正確處理水平和垂直碰撞?

+0

也許這會幫助你:http://gamedev.stackexchange.com/questions/104954/2d-collision-detection-xna-c – vyrp

回答

1

重力,添加此更新_position之前:

_velocity += gravity * (float)gameTime.ElapsedGameTime.TotalSeconds; 

哪裏gravity有點像new Vector2(0, 10)


跳躍,你需要當玩家按下跳躍鍵來設置速度的垂直分量:

if (jumpPressed && jumpAvailable) 
{ 
    _velocity.Y = -10; // Numbers are example. You need to adjust this 
    jumpAvailable = false; 
} 

而且你需要重置jumpAvailable當玩家接觸地板。


碰撞是一件非常複雜的事情。但是如果你在互聯網上尋找「XNA實施碰撞」,你會發現很多答案。

有很多方法。其中之一就是將玩家推回到boxcollider的邊界,而不是讓他移動,就像你在代碼中所做的那樣。該代碼將是:

private static bool IntersectsFromTop(Rectange player, Rectangle target) 
{ 
    var intersection = Rectangle.Intersect(player, target); 
    return player.Intersects(target) && intersection.Y == target.Y && intersection.Width >= intersection.Height; 
} 

private static bool IntersectsFromRight(Rectange player, Rectangle target) 
{ 
    var intersection = Rectangle.Intersect(player, target); 
    return player.Intersects(target) && intersection.X + intersection.Width == target.X + target.Width && intersection.Width <= intersection.Height; 
} 
// And so on... 

代碼背後的rationnale可以用圖片來說明:

Top collision and left collision

在那張照片

if (IntersectsFromTop(playerCollider, collider.BoundingBox)) 
{ 
    _position.Y = collider.BoundingBox.Y - BoundingBox.Height; 
} 
else if (IntersectsFromRight(playerCollider, collider.BoundingBox)) 
{ 
    _position.X = collider.BoundingBox.X + collider.BoundingBox.Width; 
} 
// And so on... 

的輔助方法可以像實施widthheight對應於紫色的交叉點。