From 912dad7a716986c53119e5f90b41af0928e5e393 Mon Sep 17 00:00:00 2001 From: boyu0 Date: Wed, 26 Feb 2014 10:53:41 +0800 Subject: [PATCH] closed #4144: fix bug: Node::setPhysicsBody doesn't work at the second time. --- cocos/2d/CCNode.cpp | 12 ++++++++++-- cocos/physics/CCPhysicsWorld.cpp | 10 +++++----- cocos/physics/CCPhysicsWorld.h | 6 ++++-- .../Classes/PhysicsTest/PhysicsTest.cpp | 17 ++++++++++++++++- .../test-cpp/Classes/PhysicsTest/PhysicsTest.h | 1 + 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index b2e0b56ca3..a580685976 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -1482,15 +1482,23 @@ void Node::removeAllComponents() #if CC_USE_PHYSICS void Node::setPhysicsBody(PhysicsBody* body) { + body->_node = this; + body->retain(); + if (_physicsBody != nullptr) { + PhysicsWorld* world = _physicsBody->getWorld(); + _physicsBody->removeFromWorld(); _physicsBody->_node = nullptr; _physicsBody->release(); + + if (world != nullptr) + { + world->addBody(body); + } } _physicsBody = body; - _physicsBody->_node = this; - _physicsBody->retain(); _physicsBody->setPosition(getPosition()); _physicsBody->setRotation(getRotation()); } diff --git a/cocos/physics/CCPhysicsWorld.cpp b/cocos/physics/CCPhysicsWorld.cpp index bb4b16eaef..ab5bc1cfb9 100644 --- a/cocos/physics/CCPhysicsWorld.cpp +++ b/cocos/physics/CCPhysicsWorld.cpp @@ -689,11 +689,11 @@ void PhysicsWorld::removeBody(PhysicsBody* body) // set destroy param to false to keep the iterator available removeJoint(joint, false); - PhysicsBody* other = (joint->getBodyA() == body ? joint->getBodyB() : body); + PhysicsBody* other = (joint->getBodyA() == body ? joint->getBodyB() : joint->getBodyA()); other->removeJoint(joint); // 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; } @@ -772,7 +772,7 @@ void PhysicsWorld::removeJoint(PhysicsJoint* joint, bool destroy) } // 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; } @@ -850,7 +850,7 @@ void PhysicsWorld::removeJointOrDelay(PhysicsJoint* joint) 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); _delayDirty = true; @@ -894,7 +894,7 @@ void PhysicsWorld::removeAllJoints(bool destroy) } // 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; } diff --git a/cocos/physics/CCPhysicsWorld.h b/cocos/physics/CCPhysicsWorld.h index ed09a521a2..e597531240 100644 --- a/cocos/physics/CCPhysicsWorld.h +++ b/cocos/physics/CCPhysicsWorld.h @@ -44,6 +44,7 @@ class PhysicsContact; typedef Point Vect; +class Node; class Sprite; class Scene; class DrawNode; @@ -92,9 +93,9 @@ public: /** Adds a joint to the physics world.*/ virtual void addJoint(PhysicsJoint* joint); /** 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.*/ - virtual void removeAllJoints(bool destroy); + virtual void removeAllJoints(bool destroy = true); /** Remove a body from physics world. */ virtual void removeBody(PhysicsBody* body); @@ -195,6 +196,7 @@ protected: PhysicsWorld(); virtual ~PhysicsWorld(); + friend class Node; friend class Sprite; friend class Scene; friend class PhysicsBody; diff --git a/tests/test-cpp/Classes/PhysicsTest/PhysicsTest.cpp b/tests/test-cpp/Classes/PhysicsTest/PhysicsTest.cpp index 5daa2d8273..dc158fba72 100644 --- a/tests/test-cpp/Classes/PhysicsTest/PhysicsTest.cpp +++ b/tests/test-cpp/Classes/PhysicsTest/PhysicsTest.cpp @@ -456,7 +456,18 @@ void PhysicsDemoLogoSmash::onEnter() std::string PhysicsDemoLogoSmash::title() const { 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(); @@ -472,9 +483,13 @@ std::string PhysicsDemoLogoSmash::title() const auto ball = Sprite::create("Images/ball.png"); ball->setScale(1); + ball->setTag(100); ball->setPhysicsBody(PhysicsBody::createCircle(10)); + ball->getPhysicsBody()->setTag(DRAG_BODYS_TAG); ball->setPosition(VisibleRect::bottom() + Point(0, 60)); this->addChild(ball); + + scheduleOnce(schedule_selector(PhysicsDemoPyramidStack::updateOnce), 3.0); for(int i=0; i<14; i++) { diff --git a/tests/test-cpp/Classes/PhysicsTest/PhysicsTest.h b/tests/test-cpp/Classes/PhysicsTest/PhysicsTest.h index 51e91510be..86b3f7d9c9 100644 --- a/tests/test-cpp/Classes/PhysicsTest/PhysicsTest.h +++ b/tests/test-cpp/Classes/PhysicsTest/PhysicsTest.h @@ -93,6 +93,7 @@ public: CREATE_FUNC(PhysicsDemoPyramidStack); void onEnter() override; + void updateOnce(float delta); virtual std::string title() const override; };