2014-02-24 2 views
4

그래서 플레이어 본체 + 고정물 등이 있습니다. 본질적으로 주위에서 튀는 공입니다.본문이 libgdx + box2d에서 거의 움직이지 않는지 확인하는 방법

'꽤 많이'움직이는 것을 감지하고 싶습니다.

이 대부분 작동
public Boolean isStopped() { 
    return body.getLinearVelocity().x <= 0.3f && body.getLinearVelocity().y <= 0.3f; 
} 

는, 플레이어가 뭔가를 칠 때 인 문제가 그 속도가 0 초 분할이, 그래서이 사실 반환 순간

나는이 작업을 수행. 제가 정말로 원했던 것은 그것이 기본적으로 끝났을 때 사실로 돌아 오는 것입니다. 가급적이면 내가 원하는대로 설정해도되는 범위 내에서 게임 세계의 물리 구조를 조정할 수 있습니다.

자고 있는지 아닌지에 대한 점검을 사용할 수 없습니다. 너무 늦었 기 때문에 힘을 갖지 않으면 멈추지 않습니다. 잠깐만 기다려주세요.

나는 얼마나 오래 멈추었는지/멈춘 걸음 수를 저장할 수 있었지만 나는 놓친 멋진 기존의 방법이 있었으면 좋겠다.

아이디어가 있으십니까?

답변

4

당신은 최근의 움직임을 추적하고 현재 속도의 약간의 각 시간 단계 혼합하여 업데이트 할 수 있습니다 :

float speedNow = body.getLinearVelocity().len(); 
recentSpeed = 0.1 * speedNow + 0.9 * recentSpeed; 
if (recentSpeed < someThreshold) 
    ... do something ... 

당신이 시작하기 위해 적절하게 높은 값 recentSpeed을 설정해야을, 그렇지 않으면 첫 번째 단계에서 임계 값보다 낮을 수 있습니다.

+0

그래, 나는이 라인들을 따라 뭔가를 알아 냈다. 나는 이미 신체 계급에 구워진 무언가를 찾고 있었는데, 그것은 내가 놓쳤거나 오해 한 것입니다. 내가 이런 종류의 길을 가려면 (그리고 현재 가지고있는) 시간 델타를 인수로 추가하여 얼마나 오랫동안 멈추었는지를 알아 내야합니다. 그게 효과가 있지만, 뭔가 더 좋아 져야하는 것처럼 느껴집니다. –

+0

안녕하세요. 결국 델타 방식을 사용했는데, 적어도 다른 옵션을 보여준 것처럼 답변을 수락했습니다. 당신의 코드를 보면서 _Math.abs (body.getLinearVelocity(). len())> = 0.25f_로 my isMoving 체크를 변경할 수 있다고 생각하는 것이 맞습니까? .lath()와 함께 Math.abs도 필요합니까? 답변 주셔서 대단히 감사드립니다! –

+0

오, 나는 어디에서 iforce2d를 알 수 있는지 깨달았습니다! 내 레벨 생성을 위해 RUBE 편집기를 사용합니다. 플러스 루벨 로더 덕분에 내 인생이 훨씬 쉬워졌습니다. 돈 가치가 있습니다. –

0

결국 각 렌더링 호출에서 델타를 isStopped() 메소드로 전달했습니다.

public Boolean isStopped(float delta) { 
    boolean isMoving = (
      Math.abs(body.getLinearVelocity().x) >= 0.25f || Math.abs(body.getLinearVelocity().y) >= 0.25f); 
    if(isMoving) { 
     timeStopped = 0f; 
     return false; 
    } else { 
     timeStopped += delta; 
     return timeStopped >= 0.3f; 
    } 
} 

timeStopped는 0으로 시작하는 클래스 속성입니다. 이것은 게임 시작 전 (사용자가 이동하기 전)에 true를 반환하지만 내 응용 프로그램에서는 절대적으로 괜찮습니다. 게다가 그 상황에서 멈추었다 고 말하는 것이 사실입니다.

제로 속도를 가진 몸체에 아무런 힘이 작용하지 않는다면 알아 내기 위해 box2d가이 정보를 어딘가에 가지고 있어야한다고 추측하고 있기 때문에 여분의 쓰레기를 저장하지 않고 이것을 수행하는 방법을보고 싶습니다. 그것은 충격을받은 후에 방향을 바꾸는 것입니다.

1

신체가 다른 사람과 접촉 할 때 오음 (false positive)이 발생했다고 판단한 경우 ContactListener의 beginContact 메소드에 몇 줄을 추가하여 신체의 현재 속도를 사용자 데이터에 저장하지 않을까요? 그런 다음 isStopped 메소드에서 해당 속도를 확인할 수 있습니다. 저장된 속도가 있고 현재 속도가 더 크지 않은 경우, 이는 시체가 무엇이든지 튕기는 과정에 있음을 의미합니다. 무시하십시오. 저장된 속도가 있고 현재 속도가 더 빠르면 공이 튀어 나와 새로운 방향으로 진행됩니다. 저장된 속도를 지우십시오. 저장된 속도가없고 현재 속도가 임계 값보다 낮 으면 원하는 상황을 감지했습니다. 당신의 ContactListener에서

:

public void beginContact(Contact contact) { 
    Body a = contact.getFixtureA().getBody(); 
    Body b = contact.getFixtureB().getBody(); 

    if (a == mBall) { 
     a.setUserData(a.getLinearVelocity().len()); 
    } else if (b == mBall) { 
     b.setUserData(b.getLinearVelocity().len()); 
    } 
} 

그리고 당신의 isStopped 검사에서 :

public Boolean isStopped() { 
    float storedSpd = (Float) body.getUserData(); 
    float currentSpd = body.getLinearVelocity().len(); 

    if ((storedSpd > Float.MIN_VALUE) && (currentSpd > storedSpd)) { 
     body.setUserData(Float.MIN_VALUE); 
     return false; 
    } else { 
     return (currentSpd < THRESHOLD); 
    } 
} 

이 검증되지 않은,하지만 당신은 아이디어를 얻을. 또한 처음에는 사용자 데이터를 Float.MIN_VALUE로 설정해야합니다.