cocos2d-x 3.2 + Box2D iOS에서 DebugDraw 실행까지

15081 단어 cocos2d-xBox2D
Cocoa부씨의 cocos2d-x로 BOX2D를 사용하는 입문편( h tp // 여기 아부. 코 m/보 x2d-00 )
하려고 하면 갑자기 빠져서 메모.

결론에서 쓰면 Box2D를 도입하여 DebugDraw를 실행하는 단계는

1) cocos2d/extensions/cocos-ext.h 내의 바로 가기

cocos-ext.h
#ifndef __COCOS2D_EXT_H__
#define __COCOS2D_EXT_H__

#include "ExtensionMacros.h"

#include "GUI/CCControlExtension/CCControlExtensions.h"
#include "GUI/CCScrollView/CCScrollView.h"
#include "GUI/CCScrollView/CCTableView.h"
#include "GUI/CCEditBox/CCEditBox.h"
#include "../external/Box2D/Box2D.h" // ←Add!!

// Physics integration
#include "physics-nodes/CCPhysicsDebugNode.h"
#include "physics-nodes/CCPhysicsSprite.h"

#include "assets-manager/AssetsManager.h"

#endif /* __COCOS2D_EXT_H__ */

에 Box2D에 경로 추가
(이것으로 extension의 헤더 파일을 임포트하면 Box2D도 호출할 수 있게 된다)

2) GL-ESRender.h, GL-ESRender.cpp 가져오기
테스트에 들어있는 것도 좋고, 나는
htp : // bg. csd 응. 네 t / 치안 2 곤 g / 아 rc c / 싶은 ls / 20386213
에서 빌렸습니다. 그대로 Classes 폴더 안에 넣는 것만으로 좋다.

3) 사용하고자하는 Scene 파일 내에서 호출

GameScene.h
#ifndef __GAMESCENE_SCENE_H__
#define __GAMESCENE_SCENE_H__

#include "cocos2d.h"
#include "extensions/cocos-ext.h"
#include "Box2D.h"
#include "GLES-Render.h"

#define PTM_RATIO 32.0 // 32px = 1m in Box2D

class GameScene : public cocos2d::Layer
{
public:
    // there's no 'id' in cpp, so we recommend returning the class instance pointer
    static cocos2d::Scene* createScene();

    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();
    virtual void draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t flags) override;

    // implement the "static create()" method manually
    CREATE_FUNC(GameScene);


private:
    b2World* world;
    GLESDebugDraw* debugDraw;
    ~GameScene();

    void initPhysics();

    void update(float dt);
};

#endif // __GAME_SCENE_H__

GameScene.cpp
#include "GameScene.h"
#include "Box2D/Box2D.h"
USING_NS_CC;

Scene* GameScene::createScene()
{
    auto scene = Scene::create();
    auto layer = GameScene::create();

    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool GameScene::init()
{
    //////////////////////////////
    // 1. super init first
    if (!Layer::init()){
        return false;
    }

    this->initPhysics();

   // Example box2d object to confirm debugDraw works
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(200/PTM_RATIO, 300/PTM_RATIO);
    b2Body *body = world->CreateBody(&bodyDef);

    b2PolygonShape dynamicBox;
    dynamicBox.SetAsBox(50/PTM_RATIO, 50/PTM_RATIO);

    b2FixtureDef fixtureDef;
    fixtureDef.shape = &dynamicBox;
    fixtureDef.density = 1.0f;
    body->CreateFixture(&fixtureDef);

    this->scheduleUpdate();
    return true;
}

void GameScene::update(float dt) {
    int velocityIterations = 10;
    int positionIterations = 10;

    this->world->Step(dt, velocityIterations, positionIterations);
}

void GameScene::initPhysics()
{
    b2Vec2 gravity;
    gravity.Set(0.0f, 1.0f);
    this->world = new b2World(gravity);

    this->debugDraw = new GLESDebugDraw( PTM_RATIO );
    this->world->SetDebugDraw(debugDraw);

    uint32 flags = 0;
    flags += b2Draw::e_shapeBit;
    //        flags += b2Draw::e_jointBit;
    //        flags += b2Draw::e_aabbBit;
    //        flags += b2Draw::e_pairBit;
    //        flags += b2Draw::e_centerOfMassBit;
    this->debugDraw->SetFlags(flags);
//    this->addChild(B2DebugDrawLayer::create(this->world, PTM_RATIO), 9999);

}

void GameScene::draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformUpdated) {
    Layer::draw(renderer, transform, transformUpdated);
    Director* director = Director::getInstance();

    GL::enableVertexAttribs( cocos2d::GL::VERTEX_ATTRIB_FLAG_POSITION );
    director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    world->DrawDebugData();
    director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}


GameScene::~GameScene() {
    delete this->debugDraw;
    this->debugDraw = NULL;

    delete this->world;
    this->world = NULL;
}

이상입니다.
DebugDraw를 표시하기 위해서 Scene의 draw 메소드를 오버라이드(override) 해 하는 곳이 미소입니다.
(오버라이드해야 할 draw 메소드의 사양이 상당히 빈번하게 되어 있어, 낡은 정보라면 잘 되지 않습니다…)



잘하면 생성된 Box2D 객체가 DebugDraw로 그려져야 합니다.
# 이미지는 iOS 시뮬레이터에 있습니다.

Box2D 자체의 사용법은 변하지 않았을 것이므로, 이것으로 디버그의 방법까지 정돈하면 나머지는 항에 있는 정보로 공부가 진행될까…

좋은 웹페이지 즐겨찾기