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/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)

View File

@ -38,6 +38,7 @@
#include "script_support/CCScriptSupport.h"
#include "CCProtocols.h"
#include "event_dispatcher/CCEventDispatcher.h"
#include "physics/CCPhysicsSetting.h"
#include <vector>
@ -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

View File

@ -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<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)
{
_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;

View File

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

View File

@ -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)

View File

@ -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
//

View File

@ -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
};

View File

@ -2,18 +2,16 @@
#include "../testResource.h"
USING_NS_CC;
static std::function<Layer*()> createFunctions[] = {
CL(PhysicsDemoClickAdd),
};
static int sceneIdx=-1;
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
namespace
{
static std::function<Layer*()> 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();