인디 게임 강좌

전체보기

모바일 상단 메뉴

본문 페이지

[코코스2D] [Box2D] #13 - 기어 조인트

아이콘 내폰젤무거워
조회: 2096
2017-07-12 19:08:27

Document Version : V1.3 - 2017.07.12 with cocos2d-x 3.15.1

Document Version : V1.2 - 2015.06.08 with cocos2d-x 3.6

Document Version : V1.1 - 2014.03.14 with cocos2d-x 3.0beta2

Document Version : V1.0 - 2013.07.10 with cocos2d-x 2.1.4


제 책인 "시작하세요! Cocos2d-x 3.0 프로그래밍" 내용을  3.15.1 버전에 맞게 수정하여 올리고 있습니다.

이 글은 네이버카페 "Cocos2d-x 사용자 모임"에 동시에 게재되고 있습니다.


개발환경 : 

  • Windows7
  • Visual Studio Community 2017
  • Cocos2d-x 3.15.1
  • 사용 프로젝트 : proj.win32


기어 조인트

커맨드창을 열어 원하는 디렉터리로 이동한 후에, 다음과 같이 cocos 명령어를 이용하여 새로운 프로젝트를 생성합니다.


c:> cocos new Box2dEx12 -p com.study.box12 -l cpp  ↵


Box2dEx04의 모든 코드를 방금 만든 Box2dEx12에 적용시킵니다.

Box2dEx04의 Classes 폴더의 다음 파일들을 Box2dEx12의 Classes 폴더에 덮어 쓰면 됩니다.


■ HelloWorldScene.h

■ HelloWorldScene.cpp

■ GLES-Render.h

■ GLES-Render.cpp



그러고 나서 다음의 디렉터리에서 

{Cocos2d-x가 설치된 디렉터리} / tests / cpp-tests / Resources / Images

아래의 파일을 찾아 리소스 폴더에 추가합니다.


■  blocks.png


Box2dEx12는 Box2dEx04 - 마우스 조인트까지 적용된 상태에서 시작합니다.



헤더 부분은 변경된 점이 없습니다.

[ HelloWorldScene.h  박스2D 기어 조인트 ]

     생략 : Box2dEx04의 코드와 같음 




다음은 기어 조인트 프로젝트에서 Box2dEx04와 달라진 코드 부분입니다.
setBox2dWorld 메서드에서 기어 조인트를 생성하는 부분만이 추가되고 다른 것은 변한 것이 없습니다.

[ HelloWorldScene.cpp – 박스2D 기어 조인트 ]

     생략 : Box2dEx04의 코드와 같음 


void HelloWorld::setBox2dWorld()

{

    // 마우스 조인트 바디를 생성해서 월드에 추가한다.

    bDrag = false;

    gbody = this->addNewSprite(Vec2(00), Size(00), b2_staticBodynullptr0);


    // *****************************************************************************


    b2GearJointDef gearJointDef;

    b2RevoluteJointDef jointDef1;

    b2RevoluteJointDef jointDef2;

    b2RevoluteJoint* joint1;

    b2RevoluteJoint* joint2;


    b2Body* body0 = this->addNewSprite(Vec2(240160), Size(16060),

                                                                 b2_staticBody, nullptr0);

    b2Body* body1 = this->addNewSprite(Vec2(240 - 40160), Size(4040),

                                                                 b2_dynamicBody, nullptr1);

    b2Body* body2 = this->addNewSprite(Vec2(240 + 20160), Size(8080),

                                                                 b2_dynamicBody, nullptr1);


    jointDef1.Initialize(body0, body1, body1->GetPosition());

    jointDef2.Initialize(body0, body2, body2->GetPosition());


    jointDef1.enableMotor = true;

    jointDef1.motorSpeed = 1;

    jointDef1.maxMotorTorque = 10;


    // joint1 생성전에 위 모터의 속성들이 정의되어야 한다.

    joint1 = (b2RevoluteJoint *)_world->CreateJoint(&jointDef1);

    joint2 = (b2RevoluteJoint *)_world->CreateJoint(&jointDef2);


    gearJointDef.bodyA = body1;

    gearJointDef.bodyB = body2;

    gearJointDef.joint1 = (b2Joint *)joint1;

    gearJointDef.joint2 = (b2Joint *)joint2;

    gearJointDef.ratio = 2.0;


    _world->CreateJoint(&gearJointDef);

}


     생략 : Box2dEx04의 코드와 같음 




기어 조인트는 톱니바퀴가 서로 연결되어 있는 것처럼 동작을 한다고 설명했습니다. 시계 부품의 톱니바퀴를 생각하면 될 것입니다. 두 바디의 크기가 서로 같을 필요는 없습니다. 하지만 바디데프의 유저데이타에 넣을 스프라이트의 크기를 생각해서 상식적으로 맞추어 줄 필요는 있습니다.

위 코드는 일단 정적인 바디인 body0을 만들어 화면에 고정시키고 그 정적인 바디에 동적인 바디 둘을 붙여서 기어 구성을 하였습니다.

body1을 body0에 리볼류트 조인트로 연결하고, body2도 body0에 리볼류트 조인트로 연결했습니다.

    b2RevoluteJoint* joint1;

    b2RevoluteJoint* joint2;


    b2Body* body0 = this->addNewSprite(Vec2(240160), Size(16060),

                                                                 b2_staticBody, nullptr0);

    b2Body* body1 = this->addNewSprite(Vec2(240 - 40160), Size(4040),

                                                                 b2_dynamicBody, nullptr1);

    b2Body* body2 = this->addNewSprite(Vec2(240 + 20160), Size(8080),

                                                                 b2_dynamicBody, nullptr1);


    jointDef1.Initialize(body0, body1, body1->GetPosition());

    jointDef2.Initialize(body0, body2, body2->GetPosition());


body1은 자동으로 회전이 되도록 모터를 켜고 힘을 주었습니다. body2는 별도의 설정을 하지 않았기 때문에 여기까지만 코드를 작성했다면 body1만 회전하게 됩니다.

    jointDef1.enableMotor = true;

    jointDef1.motorSpeed = 1;

    jointDef1.maxMotorTorque = 10;



여기서 body1 과 body2를 기어 조인트로 연결을 하고 body1이 body2보다 2배 빠른 비율로 회전하게 구성을 하였습니다.

    gearJointDef.bodyA = body1;

    gearJointDef.bodyB = body2;

    gearJointDef.joint1 = (b2Joint *)joint1;

    gearJointDef.joint2 = (b2Joint *)joint2;

    gearJointDef.ratio = 2.0;


    _world->CreateJoint(&gearJointDef);



이제 실행을 하면 다음과 같이 body1이 body2에 비해 2배로 빨리 도는 것을 확인할 수 있는데, 시작부터 바로 되는 것은 아니고 자세히 보면 한바퀴 돌고 나서부터 인 것을 알 수 있습니다. 자동차의 엑셀을 밟으면 바로 시속 100km가 나오지 않듯이 어느 정도 시간이 지나야 되는 것을 확인할 수 있습니다.








Lv28 내폰젤무거워

모바일 게시판 하단버튼

댓글

새로고침
새로고침

모바일 게시판 하단버튼

지금 뜨는 인벤

더보기+

모바일 게시판 리스트

모바일 게시판 하단버튼

글쓰기

모바일 게시판 페이징