2013-02-04 10 views
0

사용자가 소켓을 통해 객체를 제어하는 ​​서버 측 물리 실험을하고 있습니다. 사용자가 세계 경계 밖으로 개체를 이동할 때 내가 실행중인 문제가 발생합니다.Box2Djs에서 몸체를 고정 해제하거나 나가는 것을 막으십시오.

npm을 통해 설치된 Box2Djs를 사용하고 있습니다.

나는 세계 500x500을 만든 다음 여기에 다음 리스너를 첨부 :

var boundaryListener = new b2d.b2BoundaryListener(); 
boundaryListener.Violation = function (body) { 
    //we will move this body to the opposite side 
    var position = body.GetWorldCenter(); 
    //snap to opposite side 
    if (position.x < 0) { 
     position.x = worldAABB.upperBound.x + position.x; 
    } 
    if (position.y < 0) { 
     position.y = worldAABB.upperBound.y + position.y; 
    } 
    if (position.x > worldAABB.upperBound.x) { 
     position.x -= worldAABB.upperBound.x; 
    } 
    if (position.y > worldAABB.upperBound.y) { 
     position.y -= worldAABB.upperBound.y; 
    } 

    body.m_flags = body.m_flags & (~b2d.b2Body.e_frozenFlag); //does nothing :(
} 
this.world.SetBoundaryListener(boundaryListener); 

worldAABB 세계가 경계로 사용하는 b2AABB입니다.

문제는 경계 수신기가 실행될 때 플래그가 allowSleep, 고정 및 아일랜드 플래그 인 22로 설정되었음을 알아 챘습니다. b2Body가 세계 경계를 넘어 가면 얼어 붙는 것처럼 보일 것입니다. 그 마지막 줄은 내부 깃발을 엉망으로하여 몸을 녹여 버리려는 시도이지만, 나는 그것을하는 잘못된 방법이라는 뚜렷한 느낌을 가지고 있습니다.

어떻게 몸을 녹여 줄 수 있습니까? 내가 볼 수있는 얼어 붙은 플래그를 지우는 함수는 없습니다 (Javascript는 10,000 줄이 넘기 때문에 솔직하게 모든 것을 읽지는 못했습니다). 벽이 아무런 영향을 미치지 않는 것처럼 보입니다. (사용자의 오브젝트가 오른쪽을 통과합니다. 그들).

내 벽과 같이 생성됩니다

//create walls 
var wallShape = new b2d.b2PolygonDef(); 
wallShape.SetAsBox(500, 10); 
wallShape.density = 0.0; 
wallShape.friction = 0.3; 

var bodyDef = new b2d.b2BodyDef(); 
bodyDef.position.Set(250, 20); 
var north = this.world.CreateBody(bodyDef); 
north.CreateShape(wallShape); 

bodyDef = new b2d.b2BodyDef(); 
bodyDef.position.Set(250, 499); 
var south = this.world.CreateBody(bodyDef); 
south.CreateShape(wallShape); 

bodyDef = new b2d.b2BodyDef(); 
bodyDef.position.Set(499,250); 
bodyDef.angle = Math.PI/2; 
var east = this.world.CreateBody(bodyDef); 
east.CreateShape(wallShape); 

bodyDef = new b2d.b2BodyDef(); 
bodyDef.position.Set(1, 250); 
bodyDef.angle = Math.PI/2; 
var west = this.world.CreateBody(bodyDef); 
west.CreateShape(wallShape); 

사람이이 문제를 해결하는 방법에 대한 통찰력을 가지고 있습니까? JavaScript가 Box2D를 사용하여 찾을 수있는 문서는 거의 없지만 웹 사이트가 가리키는 플래시 문서 (절반은 시간과 일치하지 않음)와 동결에 대해 말하지 않는 C++ 설명서가 있습니다.

세계에는 중력이없고 모든 물체에는 선형 및 각진 감쇠 (psuedo-in-space 느낌)가 있다고 언급하는 것이 도움이 될 것입니다.

+0

왜이 플래그에 관심이 있습니까? 잘못된 시뮬레이션 또는 스턴스가 있습니까? – Pavel

+0

그것은 시체가 움직이는 것을 멈추게하고 나는 다시 움직이는 것을 멈추게 할 수 없으며 그것이 의미있는 유일한 깃발입니다. 경계 청취자는 움직일 수 있도록 반대쪽으로 스냅하려고했습니다. –

답변

0

나는 Box2Dj 소스를 조사했고 다음 것을 발견했다. Box2Djs는 몸체가 월드 경계 안에 있는지 확인합니다. 시체가 범위를 벗어나면 "얼어 붙음"즉, 충돌 감지가 제외됩니다. 이 코드 (Body.js 라인 414)가 :

Freeze: function(){ 
    this.m_flags |= b2Body.e_frozenFlag; 
    this.m_linearVelocity.SetZero(); 
    this.m_angularVelocity = 0.0; 

    for (var s = this.m_shapeList; s != null; s = s.m_next) 
    { 
     s.DestroyProxy(); 
    } 
} 

에주의는,이 검사는 가 수행하는 모든 시간 단계 (b2Island.js 244). 따라서 e_frozenFlag를 boundary listener로 설정하면 아무 일도하지 않습니다 : flag는 다음 번 step에서 설정됩니다. Thats 더, 시체가 얼어 붙은 후에, 그것은 그것의 veolcity를 잃어 버렸고 모양은 넓은 단계에서 그들의 프록시를 잃어 버렸습니다 (위 코드에서 볼 수 있듯이). 프록시가 자동으로 다시 복원되지 않는 것처럼 보입니다. 따라서 재설정 플래그만으로는 충분하지 않습니다.

Box2Djs 인터페이스 또는 로직 해제 로직에 어딘가가 없습니다. 이 작업을 수동으로 수행하는 것은 더러운 속임수입니다. 왜냐하면 Box2Djs 내부의 BroadPhase에 액세스해야하기 때문입니다. 그게 더 체내 손실을 자사의 velociy 때문에, 당신에게 도움이되지 않습니다. 하지만 알다시피, 계속 몸을 움직여야합니다.

다음 솔루션입니다. 세계 경계를 벗어난 후 시체를 시뮬레이션 상태로 유지하려면 몸을 완전히 얼지 않도록해야합니다. 그것은 다음 트릭에 의해 수행 될 수 있습니다. 먼저, 큰 값으로 세계 경계를 설정하십시오. 그런 다음 접촉 청취자를 설정하고 몸이 벽에 닿으면 경계 위반 논리를 수행하십시오.

C에서 연락처 리스너를 설정하는 방법은 다음에서 볼 수 있습니다. https://www.iforce2d.net/b2dtut/collision-callbacks Sory, Java 스크립트를 모르며 Box2Djs에서이 작업을 수행 할 수 없습니다.

관련 문제