인디 게임 강좌

전체보기

모바일 상단 메뉴

본문 페이지

[코코스2D] [Box2D] #19 - 조인트 제거

아이콘 내폰젤무거워
조회: 3117
2017-07-19 22:26:54

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

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


제 책인 "시작하세요! 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 Box2dEx18 -p com.study.box18 -l cpp  ↵


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

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


■ HelloWorldScene.h

■ HelloWorldScene.cpp

■ GLES-Render.h

■ GLES-Render.cpp



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

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

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


■  blocks.png


Box2dEx18은 Box2dEx02 - 디버그 모드까지 적용된 상태에서 시작합니다.




헤더 부분에는 터치를 처리할 메서드의 선언을 추가합니다.

[ HelloWorldScene.h  박스2D 조인트 제거 ]

#ifndef __HELLOWORLD_SCENE_H__

#define __HELLOWORLD_SCENE_H__


#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)

#pragma execution_character_set("utf-8")

#endif


#include "cocos2d.h"

#include "Box2D/Box2D.h"

#include <GLES-Render.h>


#define PTM_RATIO 32


using namespace cocos2d;


class HelloWorld : public cocos2d::Scene

{

public:

    static cocos2d::Scene* createScene();

    virtual bool init();

    CREATE_FUNC(HelloWorld);


    Size winSize;

    Texture2D* texture;

    b2World* _world;


    // For debugging

    GLESDebugDraw* m_debugDraw;

    cocos2d::CustomCommand _customCmd;


    bool createBox2dWorld(bool debug);

    void setBox2dWorld();

    ~HelloWorld();

    virtual void draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform,

                               uint32_t flags) override;

    void onDraw(const cocos2d::Mat4& transform, uint32_t flags);


    void onEnter();

    void onExit();

    void tick(float dt);


    b2Body* addNewSprite(Vec2 point, Size size, b2BodyType bodytype,

                                          const char* spriteName, int type);

    b2Body* getBodyAtTab(Vec2 p);

    bool onTouchBegan(Touch* touch, Event* event);

};


#endif // __HELLOWORLD_SCENE_H__



다음은 조인트 제거 프로젝트에서 Box2dEx02와 달라진 코드 부분입니다.
터치 리스너를 등록하고 onTouchBegan 메서드에서 조인트를 제거하는 코드를 추가합니다.

[ HelloWorldScene.cpp  박스2D 조인트 제거 ]

#include "HelloWorldScene.h"


Scene* HelloWorld::createScene()

{

     생략 : Box2dEx02의 코드와 같음 

}


bool HelloWorld::init()

{

     생략 : Box2dEx02의 코드와 같음 

}


bool HelloWorld::createBox2dWorld(bool debug)

{

     생략 : Box2dEx02의 코드와 같음 

}


void HelloWorld::setBox2dWorld()

{

    b2RevoluteJointDef revJointDef1;

    b2RevoluteJointDef revJointDef2;

    b2RevoluteJointDef revJointDef3;

    b2RevoluteJointDef revJointDef4;


    b2Body* body1 = this->addNewSprite(Vec2(160260), Size(3434),

                                                                 b2_staticBody, "test"0);

    b2Body* body2 = this->addNewSprite(Vec2(200260), Size(3434),

                                                                 b2_dynamicBody, "test"0);

    b2Body* body3 = this->addNewSprite(Vec2(240260), Size(3434),

                                                                 b2_dynamicBody, "test"0);

    b2Body* body4 = this->addNewSprite(Vec2(280260), Size(3434),

                                                                 b2_dynamicBody, "test"0);

    b2Body* body5 = this->addNewSprite(Vec2(320260), Size(3434),

                                                                 b2_staticBody, "test"0);


    revJointDef1.Initialize(body1, body2, body1->GetPosition());

    revJointDef2.Initialize(body2, body3, body2->GetPosition());

    revJointDef3.Initialize(body4, body3, body4->GetPosition());

    revJointDef4.Initialize(body5, body4, body5->GetPosition());


    _world->CreateJoint(&revJointDef1);

    _world->CreateJoint(&revJointDef2);

    _world->CreateJoint(&revJointDef3);

    _world->CreateJoint(&revJointDef4);

}


HelloWorld::~HelloWorld()

{

     생략 : Box2dEx02의 코드와 같음 

}


void HelloWorld::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)

{

     생략 : Box2dEx02의 코드와 같음 

}


void HelloWorld::onDraw(const Mat4 &transform, uint32_t flags)

{

     생략 : Box2dEx02의 코드와 같음 

}


void HelloWorld::onEnter()

{

    Scene::onEnter();


    // 싱글터치모드로 터치리스너 등록

    auto listener = EventListenerTouchOneByOne::create();

    listener->setSwallowTouches(true);

    listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);


    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

}


void HelloWorld::onExit()

{

     생략 : Box2dEx02의 코드와 같음 

}


void HelloWorld::tick(float dt)

{

     생략 : Box2dEx02의 코드와 같음 

}


b2Body* HelloWorld::addNewSprite(Vec2 point, Size size, b2BodyType bodytype,

                             const char* spriteName, int type)

{

     생략 : Box2dEx02의 코드와 같음 

}


b2Body* HelloWorld::getBodyAtTab(Vec2 p)

{

     생략 : Box2dEx02의 코드와 같음 

}


bool HelloWorld::onTouchBegan(Touch* touch, Event* event)

{

    Vec2 touchPoint = touch->getLocation();


    if (b2Body* b = this->getBodyAtTab(touchPoint))

    {

        b2JointEdge* joints = b->GetJointList();

        while (joints)

        {

            b2Joint* joint = joints->joint;


            joints = joints->next;

            _world->DestroyJoint(joint);

        }

    }


    return true;

}





다음은 선택한 바디의 조인트를 모두 찾아내어 제거하는 코드입니다.

    if (b2Body* b = this->getBodyAtTab(touchPoint))

    {

        b2JointEdge* joints = b->GetJointList();

        while (joints)

        {

            b2Joint* joint = joints->joint;


            joints = joints->next;

            _world->DestroyJoint(joint);

        }

    }



코드를 완성했으면 실행시켜 봅니다.






이제 바디를 마우스로 클릭해 보면 조인트가 제거되는 것을 볼 수 있습니다. 조인트가 제거된 바디는 바닥으로 떨어지게 됩니다.











Lv28 내폰젤무거워

모바일 게시판 하단버튼

댓글

새로고침
새로고침

모바일 게시판 하단버튼

지금 뜨는 인벤

더보기+

모바일 게시판 리스트

모바일 게시판 하단버튼

글쓰기

모바일 게시판 페이징