From 18a4b18368cd2977f875ead4e4548ebf960b9e5a Mon Sep 17 00:00:00 2001 From: boyu0 Date: Mon, 30 Sep 2013 13:02:17 +0800 Subject: [PATCH] issue #2771: move _physicsBody from sprite to node --- cocos2dx/base_nodes/CCNode.cpp | 62 +++++++++++++++++++ cocos2dx/base_nodes/CCNode.h | 23 +++++++ .../CCScene.cpp | 10 +-- cocos2dx/physics/CCPhysicsBody.cpp | 13 ++-- cocos2dx/physics/CCPhysicsBody.h | 2 +- cocos2dx/physics/CCPhysicsWorld.cpp | 4 ++ cocos2dx/sprite_nodes/CCSprite.cpp | 47 -------------- cocos2dx/sprite_nodes/CCSprite.h | 18 ------ .../Classes/PhysicsTest/PhysicsTest.cpp | 26 ++++---- 9 files changed, 115 insertions(+), 90 deletions(-) diff --git a/cocos2dx/base_nodes/CCNode.cpp b/cocos2dx/base_nodes/CCNode.cpp index f4547bb1fa..95f1a94987 100644 --- a/cocos2dx/base_nodes/CCNode.cpp +++ b/cocos2dx/base_nodes/CCNode.cpp @@ -44,6 +44,10 @@ THE SOFTWARE. #include "event_dispatcher/CCEvent.h" #include "event_dispatcher/CCEventTouch.h" +#ifdef CC_USE_PHYSICS +#include "physics/CCPhysicsBody.h" +#endif + // externals #include "kazmath/GL/matrix.h" #include "support/component/CCComponent.h" @@ -128,6 +132,11 @@ Node::Node(void) , _componentContainer(NULL) , _eventPriority(0) , _oldEventPriority(0) +#ifdef CC_USE_PHYSICS +, _physicsBody(nullptr) +, _physicsPositionMark(true) +, _physicsRotationMark(true) +#endif { // set default scheduler and actionManager Director *director = Director::getInstance(); @@ -179,6 +188,10 @@ Node::~Node() CC_SAFE_DELETE(_componentContainer); removeAllEventListeners(); + +#ifdef CC_USE_PHYSICS + CC_SAFE_RELEASE(_physicsBody); +#endif } bool Node::init() @@ -257,6 +270,15 @@ void Node::setRotation(float newRotation) { _rotationX = _rotationY = newRotation; _transformDirty = _inverseDirty = true; + +#ifdef CC_USE_PHYSICS + if (_physicsBody && _physicsRotationMark) + { + _physicsBody->setRotation(newRotation); + } + + _physicsRotationMark = true; +#endif } float Node::getRotationX() const @@ -332,6 +354,15 @@ void Node::setPosition(const Point& newPosition) { _position = newPosition; _transformDirty = _inverseDirty = true; + +#ifdef CC_USE_PHYSICS + if (_physicsBody && _physicsPositionMark) + { + _physicsBody->setPosition(newPosition); + } + + _physicsPositionMark = true; +#endif } void Node::getPosition(float* x, float* y) const @@ -800,6 +831,17 @@ void Node::visit() { return; } + +#ifdef CC_USE_PHYSICS + if (_physicsBody) + { + _physicsPositionMark = false; + _physicsRotationMark = false; + setPosition(_physicsBody->getPosition()); + setRotation(_physicsBody->getRotation()); + } +#endif + kmGLPushMatrix(); if (_grid && _grid->isActive()) @@ -1329,6 +1371,26 @@ void Node::setDirtyForAllEventListeners() } } +#ifdef CC_USE_PHYSICS +void Node::setPhysicsBody(PhysicsBody* body) +{ + if (_physicsBody != nullptr) + { + _physicsBody->release(); + } + + _physicsBody = body; + _physicsBody->retain(); + _physicsBody->setPosition(getPosition()); + _physicsBody->setRotation(getRotation()); +} + +PhysicsBody* Node::getPhysicsBody() const +{ + return _physicsBody; +} +#endif //CC_USE_PHYSICS + // NodeRGBA NodeRGBA::NodeRGBA() : _displayedOpacity(255) diff --git a/cocos2dx/base_nodes/CCNode.h b/cocos2dx/base_nodes/CCNode.h index e335ff11fd..41d16dbcf3 100644 --- a/cocos2dx/base_nodes/CCNode.h +++ b/cocos2dx/base_nodes/CCNode.h @@ -38,6 +38,7 @@ #include "script_support/CCScriptSupport.h" #include "CCProtocols.h" #include "event_dispatcher/CCEventDispatcher.h" +#include "physics/CCPhysicsSetting.h" #include @@ -56,6 +57,9 @@ class Component; class Dictionary; class ComponentContainer; class EventDispatcher; +#ifdef CC_USE_PHYSICS +class PhysicsBody; +#endif /** * @addtogroup base_nodes @@ -1365,6 +1369,19 @@ public: */ virtual void removeAllComponents(); /// @} end of component functions + + +#ifdef CC_USE_PHYSICS + /** + * set the PhysicsBody that let the sprite effect with physics + */ + virtual void setPhysicsBody(PhysicsBody* body); + + /** + * get the PhysicsBody the sprite have + */ + PhysicsBody* getPhysicsBody() const; +#endif private: @@ -1477,6 +1494,12 @@ protected: int _eventPriority; ///< The scene graph based priority of event listener. int _oldEventPriority; ///< The old scene graph based priority of event listener. static int _globalEventPriorityIndex; ///< The index of global event priority. + +#ifdef CC_USE_PHYSICS + PhysicsBody* _physicsBody; ///< the physicsBody the node have + bool _physicsPositionMark; ///< set this mark to false will skip the setRotation to physicsBody one time + bool _physicsRotationMark; ///< set this mark to false will skip the setPosition to physicsBody one time +#endif }; //#pragma mark - NodeRGBA diff --git a/cocos2dx/layers_scenes_transitions_nodes/CCScene.cpp b/cocos2dx/layers_scenes_transitions_nodes/CCScene.cpp index 0950fcd0a8..50b67e50e0 100644 --- a/cocos2dx/layers_scenes_transitions_nodes/CCScene.cpp +++ b/cocos2dx/layers_scenes_transitions_nodes/CCScene.cpp @@ -129,15 +129,15 @@ void Scene::addChildToPhysicsWorld(Node* child) { if (_physicsWorld) { - auto addToPhysicsWorldFunc = [this](Object* node) -> void + auto addToPhysicsWorldFunc = [this](Object* child) -> void { - if (dynamic_cast(node) != nullptr) + if (dynamic_cast(child) != nullptr) { - Sprite* sp = dynamic_cast(node); + Node* node = dynamic_cast(child); - if (sp->getPhysicsBody()) + if (node->getPhysicsBody()) { - _physicsWorld->addBody(sp->getPhysicsBody()); + _physicsWorld->addBody(node->getPhysicsBody()); } } }; diff --git a/cocos2dx/physics/CCPhysicsBody.cpp b/cocos2dx/physics/CCPhysicsBody.cpp index 2c190eefdd..32f41fd649 100644 --- a/cocos2dx/physics/CCPhysicsBody.cpp +++ b/cocos2dx/physics/CCPhysicsBody.cpp @@ -273,16 +273,19 @@ bool PhysicsBody::init() void PhysicsBody::setDynamic(bool dynamic) { - _dynamic = dynamic; - if (_world != nullptr && cpBodyIsStatic(_info->body) == (cpBool)_dynamic) + if (dynamic != _dynamic) { if (dynamic) { - cpSpaceConvertBodyToDynamic(_world->_info->space, _info->body, _mass, _angularDamping); + cpBodySetMass(_info->body, PhysicsHelper::float2cpfloat(_mass)); + cpBodySetMoment(_info->body, PhysicsHelper::float2cpfloat(_angularDamping)); }else { - cpSpaceConvertBodyToStatic(_world->_info->space, _info->body); + cpBodySetMass(_info->body, INFINITY); + cpBodySetMoment(_info->body, INFINITY); } + + _dynamic = dynamic; } } @@ -293,7 +296,7 @@ bool PhysicsBody::initStatic() _info = new PhysicsBodyInfo(); CC_BREAK_IF(_info == nullptr); - _info->body = cpBodyNewStatic(); + _info->body = cpBodyNew(INFINITY, INFINITY); CC_BREAK_IF(_info->body == nullptr); _dynamic = false; diff --git a/cocos2dx/physics/CCPhysicsBody.h b/cocos2dx/physics/CCPhysicsBody.h index 94d30f8b63..9bca83b3c0 100644 --- a/cocos2dx/physics/CCPhysicsBody.h +++ b/cocos2dx/physics/CCPhysicsBody.h @@ -259,7 +259,7 @@ protected: friend class PhysicsWorld; friend class PhysicsShape; friend class PhysicsJoint; - friend class Sprite; + friend class Node; }; NS_CC_END diff --git a/cocos2dx/physics/CCPhysicsWorld.cpp b/cocos2dx/physics/CCPhysicsWorld.cpp index b67ac5a65a..580fd5fe75 100644 --- a/cocos2dx/physics/CCPhysicsWorld.cpp +++ b/cocos2dx/physics/CCPhysicsWorld.cpp @@ -186,6 +186,8 @@ void PhysicsWorld::addBody(PhysicsBody* body) { _bodys->addObject(body); } + + body->retain(); } void PhysicsWorld::removeBody(PhysicsBody* body) @@ -210,6 +212,8 @@ void PhysicsWorld::removeBody(PhysicsBody* body) { _bodys->removeObject(body); } + + body->release(); } void PhysicsWorld::removeBodyByTag(int tag) diff --git a/cocos2dx/sprite_nodes/CCSprite.cpp b/cocos2dx/sprite_nodes/CCSprite.cpp index 741a1e1683..e1cfd9b5da 100644 --- a/cocos2dx/sprite_nodes/CCSprite.cpp +++ b/cocos2dx/sprite_nodes/CCSprite.cpp @@ -296,18 +296,12 @@ Sprite* Sprite::initWithCGImage(CGImageRef pImage, const char *pszKey) Sprite::Sprite(void) : _shouldBeHidden(false) , _texture(nullptr) -#ifdef CC_USE_PHYSICS -, _physicsBody(nullptr) -#endif { } Sprite::~Sprite(void) { CC_SAFE_RELEASE(_texture); -#ifdef CC_USE_PHYSICS - CC_SAFE_RELEASE(_physicsBody); -#endif } void Sprite::setTextureRect(const Rect& rect) @@ -790,13 +784,6 @@ void Sprite::setPosition(const Point& pos) { Node::setPosition(pos); SET_DIRTY_RECURSIVELY(); - -#ifdef CC_USE_PHYSICS - if (_physicsBody) - { - _physicsBody->setPosition(pos); - } -#endif } void Sprite::setRotation(float rotation) @@ -804,13 +791,6 @@ void Sprite::setRotation(float rotation) Node::setRotation(rotation); SET_DIRTY_RECURSIVELY(); - -#ifdef CC_USE_PHYSICS - if (_physicsBody) - { - _physicsBody->setRotation(rotation); - } -#endif } void Sprite::setRotationX(float fRotationX) @@ -907,33 +887,6 @@ bool Sprite::isFlippedY(void) const return _flippedY; } -#ifdef CC_USE_PHYSICS -void Sprite::setPhysicsBody(PhysicsBody* body) -{ - _physicsBody = body; - _physicsBody->retain(); - _physicsBody->setPosition(getPosition()); - _physicsBody->setRotation(getRotation()); -} - -PhysicsBody* Sprite::getPhysicsBody() const -{ - return _physicsBody; -} - -void Sprite::visit() -{ - if (_physicsBody) - { - Node::setPosition(_physicsBody->getPosition()); - Node::setRotation(_physicsBody->getRotation()); - SET_DIRTY_RECURSIVELY(); - } - - Node::visit(); -} -#endif //CC_USE_PHYSICS - // // RGBA protocol // diff --git a/cocos2dx/sprite_nodes/CCSprite.h b/cocos2dx/sprite_nodes/CCSprite.h index 815cd67614..d150c55213 100644 --- a/cocos2dx/sprite_nodes/CCSprite.h +++ b/cocos2dx/sprite_nodes/CCSprite.h @@ -461,20 +461,6 @@ public: */ void setFlippedY(bool flippedY); -#ifdef CC_USE_PHYSICS - /** - * set the PhysicsBody that let the sprite effect with physics - */ - virtual void setPhysicsBody(PhysicsBody* body); - - /** - * get the PhysicsBody the sprite have - */ - PhysicsBody* getPhysicsBody() const; - - virtual void visit() override; -#endif - /// @} End of Sprite properties getter/setters /** @deprecated Use isFlippedY() instead */ @@ -590,10 +576,6 @@ protected: // image is flipped bool _flippedX; /// Whether the sprite is flipped horizaontally or not. bool _flippedY; /// Whether the sprite is flipped vertically or not. - -#ifdef CC_USE_PHYSICS - PhysicsBody* _physicsBody; ///< the physicsBody the node have -#endif }; diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp index 00d81cbd0f..db4c3d46ab 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp @@ -2,18 +2,16 @@ #include "../testResource.h" USING_NS_CC; - - -static std::function createFunctions[] = { - - CL(PhysicsDemoClickAdd), -}; - -static int sceneIdx=-1; -#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) - namespace { + static std::function createFunctions[] = { + + CL(PhysicsDemoClickAdd), + }; + + static int sceneIdx=-1; +#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) + static Layer* next() { sceneIdx++; @@ -157,11 +155,11 @@ void PhysicsDemoClickAdd::onEnter() setTouchEnabled(true); setAccelerometerEnabled(true); - auto sp = Sprite::create(); + auto node = Node::create(); auto body = PhysicsBody::createEdgeBox(VisibleRect::getVisibleRect().size); - sp->setPhysicsBody(body); - sp->setPosition(VisibleRect::center()); - this->addChild(sp); + node->setPhysicsBody(body); + node->setPosition(VisibleRect::center()); + this->addChild(node); auto parent = SpriteBatchNode::create("Images/grossini_dance_atlas.png", 100); _spriteTexture = parent->getTexture();