首页 > 代码库 > 瘸腿蛤蟆笔记37-cocos2d-x-3.2 Box2dTestBed架构详解

瘸腿蛤蟆笔记37-cocos2d-x-3.2 Box2dTestBed架构详解

瘸腿蛤蟆原创笔记,欢迎转载,转载请标明出处:

上篇回顾

本篇名言:凡是内心能够想到、相信的,都是可以达到的。 [Napoleon Hill]

在最早的时候,蛤蟆学习过cocos2d-x示例架构。这次在这个基础上,蛤蟆要学习Box2dTestBed这个物理引擎的DEMO架构。这样大家可以自己深入研究之了。

 

架构详解

第一步基本类介绍

         首先从我们点到controller.cpp文件中。找到第43行如下:

         { "Box2d - TestBed", []() {return new Box2dTestBedScene(); } },

通过这行,我们跟踪 Box2dTestBedSceneBox2dView.h头文件中。这个文件是在

\cocos2d-x-3.2\tests\cpp-tests\Classes\Box2DTestBed\目录中的。

         该头文件中,定义了3个类,1个结构体,1个结构体。

         三个类是:

Box2dTestBedScene: 这个类继承于TestScene类,这个类大家可以看蛤蟆之前的cpptests框架的笔记,不过这个我们现在不用去管它,主要记住是继承于CCScene类的即可,不会对我们理解有任何影响。这个类只有一个runThisTest()函数。

MenuLayer:

这个类也继承于Layer,定义了事件监听变量,定义了restartCallback,nextCallback,nextCallback这3个函数用于实现Box2d测试用例的切换。不过我们主要理解函数menuWithEntryID和initWithEntryID。menuWithEntryID这个函数会调用initWithEntryID,并返回MenuLayer类指针。而initWithEntryID函数用来初始化Layer,添加菜单图片,注册菜单等事件,最后调用Box2DView。

Box2DView: 这个类继承于Layer类。定义并实现了触摸函数,按键函数。还定义了一个变量CustomCommand该类继承于RenderCommand来自文件\cocos2d-x-3.2\cocos\renderer。是源码自带的,该类的主要作用是 渲染物理(正如它的类名字,在此先不过多展开,展开多了就收不回来了哈)。此外就是其初始化函数了initWithEntryID 和 viewWithEntryID 。viewWithEntryID 调用initWithEntryID 并返回Box2DView 类指针。initWithEntryID实现 初始化Layer层,定义了监听函数,注册监听函数,不过最主要的还是调用Box2dTestBed中的具体用例,例如RayCast::Create。

         OK,接着我们讲下那个结构体和类:TestEntry; 这个结构体定义在Test.h文件中,如下:

struct TestEntry

{

         constchar*name;

         TestCreateFcn *createFcn;

};这个结构体很明显一个是测试用例的名字,另一个是一个类指针,指向test类。Test类也定义在Test.h文件中。         这个是Box2DView测试用例的基类。我们来看下这个test类。

Test类

这个类是所有测试用例的基类,继承于b2ContactListener类,这个类由源码实现,主要是用于实现后获取碰撞信息。由4个虚函数组成,virtualvoidBeginContact(b2Contact*contact),virtualvoidEndContact(b2Contact*contact),virtualvoidPreSolve(b2Contact*contact, const b2Manifold* oldManifold),virtual void PostSolve(b2Contact*contact, const b2ContactImpulse*impulse)。

Test类中继承了这个4个虚函数,但是本身并没有去全部实现它(只实现了PreSolve 函数)其他的通过具体的测试示例来实现的。此外test类还定义了几个虚函数,需要具体的测试示例自己实现它。其他的函数和变量时所有测试示例都通用的类。这个Test的构造函数,会创建一个物理的世界。析构函数会摧毁这个物理的世界。

 

第二步调用步骤

         OK,接下去我们梳理下整体的调用步骤如下:

首先从controller.cpp文件中的第43行

         { "Box2d - TestBed", []() {return new Box2dTestBedScene(); } },

跳跃到Box2dTestBedScene类(这个类在Box2dView.h文件中),该类只有一个函数runThisTest();

函数如下:

void Box2dTestBedScene::runThisTest()

{

    addChild(MenuLayer::menuWithEntryID(0));

    Director::getInstance()->replaceScene(this);

}

这个函数会调用MenuLayer::menuWithEntryID() ,创建一个MenuLayer类,并初始化它。

MenuLayer::menuWithEntryID 函数中,还会调用initWithEntryID 函数。

函数如下:

MenuLayer* MenuLayer::menuWithEntryID(intentryId)

{

    auto layer =new MenuLayer();

    layer->initWithEntryID(entryId);

    layer->autorelease();

    return layer;

}

 

initWithEntryID 函数会创建Box2dView类。函数如下:

bool MenuLayer::initWithEntryID(intentryId)

{

    auto director =Director::getInstance();

         Vec2 visibleOrigin = director->getVisibleOrigin();

         Size visibleSize = director->getVisibleSize();

    m_entryID = entryId;   

    Box2DView* view =Box2DView::viewWithEntryID(entryId );

    addChild(view, 0, kTagBox2DNode);

 ………………….//此处省略

    return true;

}

 

         创建Box2DView这个类的时候,首先是运行Box2DView::viewWithEntryID ,该函数调用initWithEntryID 函数。如下图

Box2DView* Box2DView::viewWithEntryID(intentryId)

{

    Box2DView* pView =new Box2DView();

    pView->initWithEntryID(entryId);

    pView->autorelease();

    return pView;

}

 

在initWithEntryID

中最终指向具体的测试类,如RayCast类。

bool Box2DView::initWithEntryID(intentryId)

{

    m_entry = g_testEntries + entryId;

m_test = m_entry->createFcn();//就是此处实现跳转

…..

    return true;

}

 

 

总结

         OK,终于完成了。洗洗睡去了。

瘸腿蛤蟆笔记37-cocos2d-x-3.2 Box2dTestBed架构详解