如何访问物理世界中的图层(How to access Physics World in Layer)

2019-10-21 20:32发布

我需要在二层机构之间建立连接。 关节在物理世界中添加。 我如何才能获得物理世界中的层?

Answer 1:

我的JavaScript实现。 希望这将有助于。

var space;

function initPhysics() {
    space = new cp.Space();
    space.gravity = cp.v(0, -800);
    space.iterations = 30;
    space.sleepTimeThreshold = Infinity;
    space.collisionSlop = Infinity;
}

function addJoints() {
    chainTableJoint1 = new cp.PivotJoint(chainEnd1, tableBackBody, cp.v.add(cp.v(chainEnd1.getPos().x, tableBackNode.getPosition().y + (tableBackNode.getContentSize().height * 0.5)), boxOffset));
    chainTableJoint2 = new cp.PivotJoint(chainEnd2, tableBackBody, cp.v.add(cp.v(chainEnd2.getPos().x, tableBackNode.getPosition().y + (tableBackNode.getContentSize().height * 0.5)), boxOffset));

    space.addConstraint(chainTableJoint1);
    space.addConstraint(chainTableJoint2);
}


Answer 2:

您有四个选项:

1) -覆盖层::的OnEnter()或onEnterTransitionDidFinish()方法然后从这样的主题访问:

    Layer::onEnter(){
        Layer::onEnter();
        auto world = _director->getRunningScene()->getPhysicsWorld();
    }

2) -创建定制层:: createScene()方法然后从层::的init()这样的访问:

Scene* GameScene::createScene()
{
    auto layer = new (std::nothrow) GameScene;
    if (layer)
    {
        auto scene = Scene::createWithPhysics();
        layer->autorelease();
        scene->addChild(layer);
        if (layer->init()) return scene;
    }
    CC_SAFE_DELETE(layer);
    return nullptr;
}

// then in Layer::init() you do this:

Layer::init(){
    auto world = _director->getRunningScene()->getPhysicsWorld();
}

3) -增加一个PhysicsWorld getter方法给导演(包括一些库代码定制的):

第一次去CCDirector.h然后NS_CC_BEGIN下添加场景类的前向声明是这样的:

NS_CC_BEGIN
class cocos2d::Scene;

然后去导演类的私有部分,并添加以下两行是这样的:

private:
cocos2d::PhysicsWorld* _myPhysicsWorld;
friend class Scene;

然后去导演类的公共部分,并添加这个getter方法是这样的:

public:
cocos2d::PhysicsWorld* getWorld() const{
    return _myPhysicsWorld;
};

这是在CCDirector.h文件中所做的更改的概述:

// CCDirector.h
NS_CC_BEGIN

// 1
class cocos2d::Scene;

class Director : public Ref{

public:
    //2
    cocos2d::PhysicsWorld* getWorld() const{
        return _myPhysicsWorld;
    };
private:
    // 3
    cocos2d::PhysicsWorld* _myPhysicsWorld;
    friend class cocos2d::Scene;
};

NS_CC_END

所以以后我们去CCScene.cpp与此签名的方法(布尔场景:: initWithPhysics())在它你会发现PhysicsWorld调用::结构(这)是方法调用此行之后添加恰到好处:

_director->_myPhysicsWorld = _physicsWorld;

这应该是我们在CCScene.cpp做了概述:

// CCScene.cpp
class Scene : public Node{

    bool Scene::initWithPhysics(){

         _physicsWorld = PhysicsWorld::construct(this);
         // 4 since Director is a singleton class, we can access its instance from anywhere
        _director->_myPhysicsWorld = _physicsWorld;

    }
};  

现在只要场景:: createWithPhysics()获取任何地方叫导演将获得可随时随地使用我们的导演getWorld()方法来访问的PhysicsWorld指针的副本! (因为导演是一个单身的你知道)和多数民众赞成在不暴露_myPhysicsWorld用户这意味着他只能从外面看_myPhysicsWorld!

4) -让自己的自定义PhysicsWorld类和自PhysicsWorld ::结构()是受保护的,这意味着它可以很容易地继承。

// PhysicsManager.h

class PhysicsManager : public cocos2d::PhysicsWorld
{
public:

    static PhysicsManager* createWorld(cocos2d::Scene* scene) {
        _myPhysicsWorld = PhysicsWorld::construct(scene);
    }

    PhysicsWorld* getWorld() const { return _myPhysicsWorld; }

private:
    static cocos2d::PhysicsWorld* _myPhysicsWorld;
};

//PhysicsManager.cpp

PhysicsManager::PhysicsWorld* _myPhysicsWorld;

现在你可以使用它像这样:

Layer::init(){

    auto physicsManager = PhysicsManager::createWorld(this->getScene());

    auto world = physicsManager->getWorld();

}

请记住,你甚至可以把它单独的类,如果你想!

编辑:

我忘了提,还有在这里的另一个很好的解决方案:

http://discuss.cocos2d-x.org/t/physics-joint-distance-problem/17926/2



文章来源: How to access Physics World in Layer