2017-03-26 8 views
0

나는 스프라이트가 Player입니다.XNA/Monogame : Platformer Jumping Physics and Collider 문제

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

경우 _position, _direction_velocityVector2들입니다 : 나는 Player의 위치를 ​​다음과 같은 방법을 업데이트합니다.

나는 콜 리더의 위치와 크기가 주어진 단순한 사각형 (BoundingBox)을 생성하는 간단한 충돌기 (BoxCollider)를 가지고 있습니다.

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이 너무 높은 값에서 떨어지면 이 Player에서 너무 멀리 떨어져서 공중에 갇혀있게됩니다.

가로 충돌 문제도 비슷합니다. 문제는 비슷합니다. Player이 너무 빨리 멈추고 사이에 공백이 있습니다. 때로는 Player이 충돌 자의 측면에 붙어 있습니다.

내가 알고 싶은 것입니다 :

가 어떻게 제대로 _position, _direction_velocity 점프 중력 &을 구현합니까? 충돌을 수평 및 수직으로 올바르게 처리하는 방법은 무엇입니까? 당신이 _position를 업데이트하기 직전에

+0

아마도 도움이 될 것입니다. http://gamedev.stackexchange.com/questions/104954/2d-collision-detection-xna-c – vyrp

답변

1

중력은이를 추가 gravitynew Vector2(0, 10) 같은 것이

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

입니다.


는 점프를 들어, 플레이어가 점프 버튼을 누를 때 속도의 수직 성분을 설정해야합니다

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

을 그리고 당신은 플레이어가 바닥에 닿을 때 jumpAvailable를 재설정해야합니다.


충돌은 매우 복잡합니다. 그러나 인터넷에서 "XNA implement collision"을 찾으면 많은 답변을 찾을 수 있습니다.

다양한 방법이 있습니다. 그 중 하나는 코드에서했던 것처럼 움직이지 않게하는 대신 boxcollider 경계로 플레이어를 뒤로 밀고 있습니다.코드는 다음과 같습니다

Top collision and left collision

그 사진에서 : 그 코드 뒤에 rationnale이 그림으로 설명 할 수있다

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... 

:

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은 자주색 교차로에 해당합니다.