prismatic joint는 여닫이 문이나 피스톤같은 제한적 직선운동을 만들때 필요한 joint type입니다. 슬라이더라고도 하죠. revolute joint 처럼 limit을 설정할 수 있어서 일정 바운더리 안에서의 직선 이동을 하도록 제한할 수 있습니다. 또한 motor를 활성화 할 수도 있구요. 이를 이용해서 아래 침대 스프링 형태의 joint를 만들어봤습니다.
마우스로 클릭하면 클릭한 위치에 원이 생기고 자유낙를 하죠. 떨어지는 힘을 받아서 바닥의 스프링들이 출렁거리게 만들어졌습니다.

각 스프링들은 위로 향하는 motor가 돌고 있구요. 하지만 limit이 제한되어 있기 때문에 계속 올라가진 않고 한계점에 서 있게 됩니다. 원과 부딛힌 스프링은 충돌받은 힘만큼 반동으로 아래로 밀려나게 했습니다만 restitution(반발력)이 0 이기 때문에 서로 밀쳐내서 얌채공처럼 튀어오르는 느낌을 없앴습니다. 얌채공같이 반발력이 좋은 물체를 만들려면 restitution값을 1로 설정하면 될것입니다.

joint나 body의 많은 속성들을 바꿔가면서 속성을 이해하는것이 중요한것 같습니다. 말로는 이해하기 힘들어도 속성값 바꿔가면서 느끼니 훨씬 다루기 쉬워지네요.

아래는 예제를 만들기 위해 기본적으로 필요했던 함수 두개 입니다. 상자를 만드는 함수와 원을 만드는 함수죠. 설명 생략하고 함수 구현은 첨부된 .as 파일을 참조하시길.

function createBox(x:Number, y:Number, w:Number, h:Number, angle:Number, isDynamic:Boolean):b2Body;


function createCircle(x:Number, y:Number, r:Number, isDynamic:Boolean):b2Body;


그리고 덤으로 클릭시 원을 생성해주는 핸들러 입니다. 위의 함수를 이용하구요.

function onClick(event:MouseEvent):void {

createCircle(mouseX, mouseY, Math.random()*20+15, true);

}


이제 prismatic joint를 만드는 부분을 보겠습니다.

function createPrismaticJoint(body1:b2Body, body2:b2Body, anchor:b2Vec2, axis:b2Vec2, thick:Number):void

{

var jointDef:b2PrismaticJointDef = new b2PrismaticJointDef();

jointDef.Initialize(body1, body2, anchor, axis);

jointDef.collideConnected = false;

jointDef.enableLimit = true;

jointDef.enableMotor = true;

jointDef.lowerTranslation = -(thick/2)/scale;

jointDef.upperTranslation = (thick/2)/scale;

jointDef.motorSpeed = 3;

jointDef.maxMotorForce = 2900;

world.CreateJoint(jointDef);

}


이는 이 예제에서 사용하기 위한 전용 함수라고 봐도 되겠네요. 모든 prismatic joint가 항상 위와같은 설정값을 가질 필요는 없으니까요. 함수 인자들은 joint definition의 인자와 거의 동일합니다. 단지 limit을 설정하기 위한 변수가 하나 더 추가 되었습니다.

prismatic joint에서 주의깊게 봐야할 부분은 axis 같네요. body가 움질일 축의 방향 벡터 입니다. 단위벡터일 필요는 없습니다. axis의 값이 x="1.0" y="0.0" 이면 x축의 우측 방향을 양의 방향으로 하는 prismatic joint를 생성한다는 의미이고, x="0.0" y="-1.0" 이면 y축의 위쪽을 양의 방향으로 하는 prismatic joint가 됩니다.

신경써야 할 또하나는, 두 body가 처음 joint로 엮이는 그 시점 두 위치가 prismatic joint의 translation값이 0인 지점으로 설정 된다는 것입니다. 그래서 joint를 생성할 당시의 body 위치가 중요합니다.

function createSpring(px:Number, py:Number, w:Number, h:Number):void

{

var b1:b2Body = createBox(px, py-h/2, 5, h, 0, false);

var b2:b2Body = createBox(px, py-h, w, h-10, 0, true);

var anchor:b2Vec2 = new b2Vec2(px/scale,py/scale);

var axis:b2Vec2 = new b2Vec2(0,-1);

createPrismaticJoint(b1,b2,anchor,axis,h-10);

}


이 함수는 위에서 살펴본 createPrismaticJoint를 이용해서 스프링 형태의 물체를 만들어 내는 함수 입니다.  아래에는 static body를 만들고 그 위에 dynamic body를 올리는 형태입니다. axis는 y축 위 방향으로 설정하였습니다.

이 함수에서 매개변수 w는 스프링의 상단 dynamic body의 가로 길이가 되고, h는 static body의 세로 길이가 됩니다.

그렇게 해서 위의 함수를 이용해서 화면의 바닥을 가득 채우는 스프링을 만들어줍니다. 아래 코드는 생성자 함수의 마지막 부분에 들어가면 되겠죠?

for (var i:int = 0 ; i < 10 ; i++) {

createSpring(25+50*i, 400, 48, 30);

}


스프링들이 딱 맞닿아 있으면 마찰때문에 다같이 영향을 받기 때문에 간격은 50으로 하되, 스프링의 가로 길이는 48로 설정했습니다. 최종 소스를 첨부하겠습니다.

'programming > box2d docs' 카테고리의 다른 글

b2PulleyJoint 예제  (0) 2011.02.01
b2Revolute Joint 예제  (0) 2011.01.30
b2DistanceJoint 예제  (0) 2011.01.28
b2Body 예제 - Box2DFlash  (4) 2011.01.17
Box2DFlash v2.1a Update Notes 비공식 한글문서  (0) 2011.01.16

WRITTEN BY
buzzler

,