问题
I need to create joint between two bodies in layer. Joints are to be added in physics world. How can i access physics world in layer?
回答1:
My JavaScript implementation. Hope it will help.
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);
}
回答2:
you have four options:
1)- override Layer::onEnter() or onEnterTransitionDidFinish () methods then access from theme like this:
Layer::onEnter(){
Layer::onEnter();
auto world = _director->getRunningScene()->getPhysicsWorld();
}
2)- create a custom Layer::createScene() method then access from Layer::init() like this:
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)- add a PhysicsWorld getter method to the director (involves some library code customization's):
first go to CCDirector.h and then add a forward declaration of the scene class under NS_CC_BEGIN like this:
NS_CC_BEGIN
class cocos2d::Scene;
then go to the private section of the Director class and add these two lines like this:
private:
cocos2d::PhysicsWorld* _myPhysicsWorld;
friend class Scene;
then go to the public section of the Director class and add this getter method like this:
public:
cocos2d::PhysicsWorld* getWorld() const{
return _myPhysicsWorld;
};
this is an overview of the changes made in CCDirector.h file:
// 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
so after that we go to CCScene.cpp into a method with this signature (bool Scene::initWithPhysics()) in it you will find a call to PhysicsWorld::construct(this) add just right after that method call this line:
_director->_myPhysicsWorld = _physicsWorld;
and this should be the overview of what we did in 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;
}
};
now as soon as Scene::createWithPhysics() gets called anywhere the director will get a copy of the PhysicsWorld pointer which can be accessed using our director getWorld() method anywhere anytime!! (because the director is a singleton as you know) and thats all without exposing _myPhysicsWorld to the user meaning he can only read _myPhysicsWorld from the outside!!
4)- make your own Custom PhysicsWorld class and since PhysicsWorld::construct() is protected which means it can be easily inherited.
// 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;
now you can use it like this:
Layer::init(){
auto physicsManager = PhysicsManager::createWorld(this->getScene());
auto world = physicsManager->getWorld();
}
remember that you can even make it a singleton class if you want to!
Edit:
I forgot to mention that there is another good solution in here:
http://discuss.cocos2d-x.org/t/physics-joint-distance-problem/17926/2
来源:https://stackoverflow.com/questions/28486310/how-to-access-physics-world-in-layer