issue #2771: move _physicsBody from sprite to node

This commit is contained in:
boyu0 2013-09-30 13:02:17 +08:00
parent 3dbe74db1a
commit 18a4b18368
9 changed files with 115 additions and 90 deletions

View File

@ -44,6 +44,10 @@ THE SOFTWARE.
#include "event_dispatcher/CCEvent.h" #include "event_dispatcher/CCEvent.h"
#include "event_dispatcher/CCEventTouch.h" #include "event_dispatcher/CCEventTouch.h"
#ifdef CC_USE_PHYSICS
#include "physics/CCPhysicsBody.h"
#endif
// externals // externals
#include "kazmath/GL/matrix.h" #include "kazmath/GL/matrix.h"
#include "support/component/CCComponent.h" #include "support/component/CCComponent.h"
@ -128,6 +132,11 @@ Node::Node(void)
, _componentContainer(NULL) , _componentContainer(NULL)
, _eventPriority(0) , _eventPriority(0)
, _oldEventPriority(0) , _oldEventPriority(0)
#ifdef CC_USE_PHYSICS
, _physicsBody(nullptr)
, _physicsPositionMark(true)
, _physicsRotationMark(true)
#endif
{ {
// set default scheduler and actionManager // set default scheduler and actionManager
Director *director = Director::getInstance(); Director *director = Director::getInstance();
@ -179,6 +188,10 @@ Node::~Node()
CC_SAFE_DELETE(_componentContainer); CC_SAFE_DELETE(_componentContainer);
removeAllEventListeners(); removeAllEventListeners();
#ifdef CC_USE_PHYSICS
CC_SAFE_RELEASE(_physicsBody);
#endif
} }
bool Node::init() bool Node::init()
@ -257,6 +270,15 @@ void Node::setRotation(float newRotation)
{ {
_rotationX = _rotationY = newRotation; _rotationX = _rotationY = newRotation;
_transformDirty = _inverseDirty = true; _transformDirty = _inverseDirty = true;
#ifdef CC_USE_PHYSICS
if (_physicsBody && _physicsRotationMark)
{
_physicsBody->setRotation(newRotation);
}
_physicsRotationMark = true;
#endif
} }
float Node::getRotationX() const float Node::getRotationX() const
@ -332,6 +354,15 @@ void Node::setPosition(const Point& newPosition)
{ {
_position = newPosition; _position = newPosition;
_transformDirty = _inverseDirty = true; _transformDirty = _inverseDirty = true;
#ifdef CC_USE_PHYSICS
if (_physicsBody && _physicsPositionMark)
{
_physicsBody->setPosition(newPosition);
}
_physicsPositionMark = true;
#endif
} }
void Node::getPosition(float* x, float* y) const void Node::getPosition(float* x, float* y) const
@ -800,6 +831,17 @@ void Node::visit()
{ {
return; return;
} }
#ifdef CC_USE_PHYSICS
if (_physicsBody)
{
_physicsPositionMark = false;
_physicsRotationMark = false;
setPosition(_physicsBody->getPosition());
setRotation(_physicsBody->getRotation());
}
#endif
kmGLPushMatrix(); kmGLPushMatrix();
if (_grid && _grid->isActive()) 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::NodeRGBA() NodeRGBA::NodeRGBA()
: _displayedOpacity(255) : _displayedOpacity(255)

View File

@ -38,6 +38,7 @@
#include "script_support/CCScriptSupport.h" #include "script_support/CCScriptSupport.h"
#include "CCProtocols.h" #include "CCProtocols.h"
#include "event_dispatcher/CCEventDispatcher.h" #include "event_dispatcher/CCEventDispatcher.h"
#include "physics/CCPhysicsSetting.h"
#include <vector> #include <vector>
@ -56,6 +57,9 @@ class Component;
class Dictionary; class Dictionary;
class ComponentContainer; class ComponentContainer;
class EventDispatcher; class EventDispatcher;
#ifdef CC_USE_PHYSICS
class PhysicsBody;
#endif
/** /**
* @addtogroup base_nodes * @addtogroup base_nodes
@ -1367,6 +1371,19 @@ public:
/// @} end of component functions /// @} 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: private:
friend class Director; friend class Director;
friend class EventDispatcher; friend class EventDispatcher;
@ -1477,6 +1494,12 @@ protected:
int _eventPriority; ///< The scene graph based priority of event listener. int _eventPriority; ///< The scene graph based priority of event listener.
int _oldEventPriority; ///< The old 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. 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 //#pragma mark - NodeRGBA

View File

@ -129,15 +129,15 @@ void Scene::addChildToPhysicsWorld(Node* child)
{ {
if (_physicsWorld) if (_physicsWorld)
{ {
auto addToPhysicsWorldFunc = [this](Object* node) -> void auto addToPhysicsWorldFunc = [this](Object* child) -> void
{ {
if (dynamic_cast<Sprite*>(node) != nullptr) if (dynamic_cast<Node*>(child) != nullptr)
{ {
Sprite* sp = dynamic_cast<Sprite*>(node); Node* node = dynamic_cast<Node*>(child);
if (sp->getPhysicsBody()) if (node->getPhysicsBody())
{ {
_physicsWorld->addBody(sp->getPhysicsBody()); _physicsWorld->addBody(node->getPhysicsBody());
} }
} }
}; };

View File

@ -273,16 +273,19 @@ bool PhysicsBody::init()
void PhysicsBody::setDynamic(bool dynamic) void PhysicsBody::setDynamic(bool dynamic)
{ {
_dynamic = dynamic; if (dynamic != _dynamic)
if (_world != nullptr && cpBodyIsStatic(_info->body) == (cpBool)_dynamic)
{ {
if (dynamic) if (dynamic)
{ {
cpSpaceConvertBodyToDynamic(_world->_info->space, _info->body, _mass, _angularDamping); cpBodySetMass(_info->body, PhysicsHelper::float2cpfloat(_mass));
cpBodySetMoment(_info->body, PhysicsHelper::float2cpfloat(_angularDamping));
}else }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(); _info = new PhysicsBodyInfo();
CC_BREAK_IF(_info == nullptr); CC_BREAK_IF(_info == nullptr);
_info->body = cpBodyNewStatic(); _info->body = cpBodyNew(INFINITY, INFINITY);
CC_BREAK_IF(_info->body == nullptr); CC_BREAK_IF(_info->body == nullptr);
_dynamic = false; _dynamic = false;

View File

@ -259,7 +259,7 @@ protected:
friend class PhysicsWorld; friend class PhysicsWorld;
friend class PhysicsShape; friend class PhysicsShape;
friend class PhysicsJoint; friend class PhysicsJoint;
friend class Sprite; friend class Node;
}; };
NS_CC_END NS_CC_END

View File

@ -186,6 +186,8 @@ void PhysicsWorld::addBody(PhysicsBody* body)
{ {
_bodys->addObject(body); _bodys->addObject(body);
} }
body->retain();
} }
void PhysicsWorld::removeBody(PhysicsBody* body) void PhysicsWorld::removeBody(PhysicsBody* body)
@ -210,6 +212,8 @@ void PhysicsWorld::removeBody(PhysicsBody* body)
{ {
_bodys->removeObject(body); _bodys->removeObject(body);
} }
body->release();
} }
void PhysicsWorld::removeBodyByTag(int tag) void PhysicsWorld::removeBodyByTag(int tag)

View File

@ -296,18 +296,12 @@ Sprite* Sprite::initWithCGImage(CGImageRef pImage, const char *pszKey)
Sprite::Sprite(void) Sprite::Sprite(void)
: _shouldBeHidden(false) : _shouldBeHidden(false)
, _texture(nullptr) , _texture(nullptr)
#ifdef CC_USE_PHYSICS
, _physicsBody(nullptr)
#endif
{ {
} }
Sprite::~Sprite(void) Sprite::~Sprite(void)
{ {
CC_SAFE_RELEASE(_texture); CC_SAFE_RELEASE(_texture);
#ifdef CC_USE_PHYSICS
CC_SAFE_RELEASE(_physicsBody);
#endif
} }
void Sprite::setTextureRect(const Rect& rect) void Sprite::setTextureRect(const Rect& rect)
@ -790,13 +784,6 @@ void Sprite::setPosition(const Point& pos)
{ {
Node::setPosition(pos); Node::setPosition(pos);
SET_DIRTY_RECURSIVELY(); SET_DIRTY_RECURSIVELY();
#ifdef CC_USE_PHYSICS
if (_physicsBody)
{
_physicsBody->setPosition(pos);
}
#endif
} }
void Sprite::setRotation(float rotation) void Sprite::setRotation(float rotation)
@ -804,13 +791,6 @@ void Sprite::setRotation(float rotation)
Node::setRotation(rotation); Node::setRotation(rotation);
SET_DIRTY_RECURSIVELY(); SET_DIRTY_RECURSIVELY();
#ifdef CC_USE_PHYSICS
if (_physicsBody)
{
_physicsBody->setRotation(rotation);
}
#endif
} }
void Sprite::setRotationX(float fRotationX) void Sprite::setRotationX(float fRotationX)
@ -907,33 +887,6 @@ bool Sprite::isFlippedY(void) const
return _flippedY; 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 // RGBA protocol
// //

View File

@ -461,20 +461,6 @@ public:
*/ */
void setFlippedY(bool flippedY); 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 /// @} End of Sprite properties getter/setters
/** @deprecated Use isFlippedY() instead */ /** @deprecated Use isFlippedY() instead */
@ -590,10 +576,6 @@ protected:
// image is flipped // image is flipped
bool _flippedX; /// Whether the sprite is flipped horizaontally or not. bool _flippedX; /// Whether the sprite is flipped horizaontally or not.
bool _flippedY; /// Whether the sprite is flipped vertically or not. bool _flippedY; /// Whether the sprite is flipped vertically or not.
#ifdef CC_USE_PHYSICS
PhysicsBody* _physicsBody; ///< the physicsBody the node have
#endif
}; };

View File

@ -2,18 +2,16 @@
#include "../testResource.h" #include "../testResource.h"
USING_NS_CC; USING_NS_CC;
static std::function<Layer*()> createFunctions[] = {
CL(PhysicsDemoClickAdd),
};
static int sceneIdx=-1;
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
namespace namespace
{ {
static std::function<Layer*()> createFunctions[] = {
CL(PhysicsDemoClickAdd),
};
static int sceneIdx=-1;
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
static Layer* next() static Layer* next()
{ {
sceneIdx++; sceneIdx++;
@ -157,11 +155,11 @@ void PhysicsDemoClickAdd::onEnter()
setTouchEnabled(true); setTouchEnabled(true);
setAccelerometerEnabled(true); setAccelerometerEnabled(true);
auto sp = Sprite::create(); auto node = Node::create();
auto body = PhysicsBody::createEdgeBox(VisibleRect::getVisibleRect().size); auto body = PhysicsBody::createEdgeBox(VisibleRect::getVisibleRect().size);
sp->setPhysicsBody(body); node->setPhysicsBody(body);
sp->setPosition(VisibleRect::center()); node->setPosition(VisibleRect::center());
this->addChild(sp); this->addChild(node);
auto parent = SpriteBatchNode::create("Images/grossini_dance_atlas.png", 100); auto parent = SpriteBatchNode::create("Images/grossini_dance_atlas.png", 100);
_spriteTexture = parent->getTexture(); _spriteTexture = parent->getTexture();