Merge pull request #5467 from boyu0/bug4144_node_setphysicsbody

closed #4144: fix bug: Can not use Node::setPhysicsBody to reset a physics body.
This commit is contained in:
James Chen 2014-02-26 11:43:19 +08:00
commit 5e315273f9
5 changed files with 36 additions and 10 deletions

View File

@ -1463,15 +1463,23 @@ void Node::removeAllComponents()
#if CC_USE_PHYSICS #if CC_USE_PHYSICS
void Node::setPhysicsBody(PhysicsBody* body) void Node::setPhysicsBody(PhysicsBody* body)
{ {
body->_node = this;
body->retain();
if (_physicsBody != nullptr) if (_physicsBody != nullptr)
{ {
PhysicsWorld* world = _physicsBody->getWorld();
_physicsBody->removeFromWorld();
_physicsBody->_node = nullptr; _physicsBody->_node = nullptr;
_physicsBody->release(); _physicsBody->release();
if (world != nullptr)
{
world->addBody(body);
}
} }
_physicsBody = body; _physicsBody = body;
_physicsBody->_node = this;
_physicsBody->retain();
_physicsBody->setPosition(getPosition()); _physicsBody->setPosition(getPosition());
_physicsBody->setRotation(getRotation()); _physicsBody->setRotation(getRotation());
} }

View File

@ -692,11 +692,11 @@ void PhysicsWorld::removeBody(PhysicsBody* body)
// set destroy param to false to keep the iterator available // set destroy param to false to keep the iterator available
removeJoint(joint, false); removeJoint(joint, false);
PhysicsBody* other = (joint->getBodyA() == body ? joint->getBodyB() : body); PhysicsBody* other = (joint->getBodyA() == body ? joint->getBodyB() : joint->getBodyA());
other->removeJoint(joint); other->removeJoint(joint);
// test the distraction is delaied or not // test the distraction is delaied or not
if (_delayRemoveJoints.size() > 0 && _delayRemoveJoints.back() == joint) if (std::find(_delayRemoveJoints.rbegin(), _delayRemoveJoints.rend(), joint) != _delayRemoveJoints.rend())
{ {
joint->_destoryMark = true; joint->_destoryMark = true;
} }
@ -775,7 +775,7 @@ void PhysicsWorld::removeJoint(PhysicsJoint* joint, bool destroy)
} }
// test the distraction is delaied or not // test the distraction is delaied or not
if (_delayRemoveJoints.size() > 0 && _delayRemoveJoints.back() == joint) if (std::find(_delayRemoveJoints.rbegin(), _delayRemoveJoints.rend(), joint) != _delayRemoveJoints.rend())
{ {
joint->_destoryMark = true; joint->_destoryMark = true;
} }
@ -853,7 +853,7 @@ void PhysicsWorld::removeJointOrDelay(PhysicsJoint* joint)
if (_info->isLocked()) if (_info->isLocked())
{ {
if (std::find(_delayRemoveJoints.begin(), _delayRemoveJoints.end(), joint) == _delayRemoveJoints.end()) if (std::find(_delayRemoveJoints.rbegin(), _delayRemoveJoints.rend(), joint) == _delayRemoveJoints.rend())
{ {
_delayRemoveJoints.push_back(joint); _delayRemoveJoints.push_back(joint);
_delayDirty = true; _delayDirty = true;
@ -897,7 +897,7 @@ void PhysicsWorld::removeAllJoints(bool destroy)
} }
// test the distraction is delaied or not // test the distraction is delaied or not
if (_delayRemoveJoints.size() > 0 && _delayRemoveJoints.back() == joint) if (std::find(_delayRemoveJoints.rbegin(), _delayRemoveJoints.rend(), joint) != _delayRemoveJoints.rend())
{ {
joint->_destoryMark = true; joint->_destoryMark = true;
} }

View File

@ -44,6 +44,7 @@ class PhysicsContact;
typedef Point Vect; typedef Point Vect;
class Node;
class Sprite; class Sprite;
class Scene; class Scene;
class DrawNode; class DrawNode;
@ -92,9 +93,9 @@ public:
/** Adds a joint to the physics world.*/ /** Adds a joint to the physics world.*/
virtual void addJoint(PhysicsJoint* joint); virtual void addJoint(PhysicsJoint* joint);
/** Remove a joint from physics world.*/ /** Remove a joint from physics world.*/
virtual void removeJoint(PhysicsJoint* joint, bool destroy); virtual void removeJoint(PhysicsJoint* joint, bool destroy = true);
/** Remove all joints from physics world.*/ /** Remove all joints from physics world.*/
virtual void removeAllJoints(bool destroy); virtual void removeAllJoints(bool destroy = true);
/** Remove a body from physics world. */ /** Remove a body from physics world. */
virtual void removeBody(PhysicsBody* body); virtual void removeBody(PhysicsBody* body);
@ -195,6 +196,7 @@ protected:
PhysicsWorld(); PhysicsWorld();
virtual ~PhysicsWorld(); virtual ~PhysicsWorld();
friend class Node;
friend class Sprite; friend class Sprite;
friend class Scene; friend class Scene;
friend class PhysicsBody; friend class PhysicsBody;

View File

@ -475,7 +475,18 @@ void PhysicsDemoLogoSmash::onEnter()
std::string PhysicsDemoLogoSmash::title() const std::string PhysicsDemoLogoSmash::title() const
{ {
return "Logo Smash"; return "Logo Smash";
}void PhysicsDemoPyramidStack::onEnter() }
void PhysicsDemoPyramidStack::updateOnce(float delta)
{
auto ball = getChildByTag(100);
ball->setScale(ball->getScale() * 3);
ball->setPhysicsBody(PhysicsBody::createCircle(30));
ball->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
}
void PhysicsDemoPyramidStack::onEnter()
{ {
PhysicsDemo::onEnter(); PhysicsDemo::onEnter();
@ -491,9 +502,13 @@ std::string PhysicsDemoLogoSmash::title() const
auto ball = Sprite::create("Images/ball.png"); auto ball = Sprite::create("Images/ball.png");
ball->setScale(1); ball->setScale(1);
ball->setTag(100);
ball->setPhysicsBody(PhysicsBody::createCircle(10)); ball->setPhysicsBody(PhysicsBody::createCircle(10));
ball->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
ball->setPosition(VisibleRect::bottom() + Point(0, 60)); ball->setPosition(VisibleRect::bottom() + Point(0, 60));
this->addChild(ball); this->addChild(ball);
scheduleOnce(schedule_selector(PhysicsDemoPyramidStack::updateOnce), 3.0);
for(int i=0; i<14; i++) for(int i=0; i<14; i++)
{ {

View File

@ -93,6 +93,7 @@ public:
CREATE_FUNC(PhysicsDemoPyramidStack); CREATE_FUNC(PhysicsDemoPyramidStack);
void onEnter() override; void onEnter() override;
void updateOnce(float delta);
virtual std::string title() const override; virtual std::string title() const override;
}; };