mirror of https://github.com/axmolengine/axmol.git
issue #2771: fix some retain/release bugs
This commit is contained in:
parent
fdcf019665
commit
d0d8694091
|
@ -749,6 +749,14 @@ void Node::detachChild(Node *child, int childIndex, bool doCleanup)
|
|||
child->onExitTransitionDidStart();
|
||||
child->onExit();
|
||||
}
|
||||
|
||||
#ifdef CC_USE_PHYSICS
|
||||
if (child->_physicsBody != nullptr)
|
||||
{
|
||||
child->_physicsBody->removeFromWorld();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// If you don't do cleanup, the child's actions will not get removed and the
|
||||
// its scheduledSelectors_ dict will not get released!
|
||||
|
|
|
@ -62,6 +62,7 @@ namespace
|
|||
|
||||
PhysicsBody::PhysicsBody()
|
||||
: _owner(nullptr)
|
||||
, _shapes(nullptr)
|
||||
, _world(nullptr)
|
||||
, _info(nullptr)
|
||||
, _dynamic(true)
|
||||
|
@ -85,18 +86,23 @@ PhysicsBody::PhysicsBody()
|
|||
|
||||
PhysicsBody::~PhysicsBody()
|
||||
{
|
||||
CC_SAFE_DELETE(_info);
|
||||
if (_world)
|
||||
{
|
||||
removeFromWorld();
|
||||
}
|
||||
|
||||
removeAllShapes();
|
||||
|
||||
for (auto it = _joints.begin(); it != _joints.end(); ++it)
|
||||
{
|
||||
PhysicsJoint* joint = *it;
|
||||
PhysicsBody* other = joint->getBodyA() == this ? joint->getBodyA() : joint->getBodyB();
|
||||
PhysicsBody* other = joint->getBodyA() == this ? joint->getBodyB() : joint->getBodyA();
|
||||
|
||||
other->_joints.erase(std::find(other->_joints.begin(), other->_joints.end(), joint));
|
||||
|
||||
delete joint;
|
||||
}
|
||||
CC_SAFE_DELETE(_info);
|
||||
}
|
||||
|
||||
PhysicsBody* PhysicsBody::create()
|
||||
|
@ -112,6 +118,45 @@ PhysicsBody* PhysicsBody::create()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
PhysicsBody* PhysicsBody::create(float mass)
|
||||
{
|
||||
PhysicsBody* body = new PhysicsBody();
|
||||
if (body)
|
||||
{
|
||||
body->_mass = mass;
|
||||
body->_massDefault = false;
|
||||
if (body->init())
|
||||
{
|
||||
body->autorelease();
|
||||
return body;
|
||||
}
|
||||
}
|
||||
|
||||
CC_SAFE_DELETE(body);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PhysicsBody* PhysicsBody::create(float mass, float moment)
|
||||
{
|
||||
PhysicsBody* body = new PhysicsBody();
|
||||
if (body)
|
||||
{
|
||||
body->_mass = mass;
|
||||
body->_massDefault = false;
|
||||
body->_moment = moment;
|
||||
body->_momentDefault = false;
|
||||
if (body->init())
|
||||
{
|
||||
body->autorelease();
|
||||
return body;
|
||||
}
|
||||
}
|
||||
|
||||
CC_SAFE_DELETE(body);
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
PhysicsBody* PhysicsBody::createCircle(float radius, PhysicsMaterial material)
|
||||
{
|
||||
PhysicsBody* body = new PhysicsBody();
|
||||
|
@ -223,6 +268,9 @@ bool PhysicsBody::init()
|
|||
{
|
||||
_info = new PhysicsBodyInfo();
|
||||
CC_BREAK_IF(_info == nullptr);
|
||||
_shapes = Array::create();
|
||||
CC_BREAK_IF(_shapes == nullptr);
|
||||
_shapes->retain();
|
||||
|
||||
_info->body = cpBodyNew(PhysicsHelper::float2cpfloat(_mass), PhysicsHelper::float2cpfloat(_moment));
|
||||
_info->group = ++GROUP_INDEX;
|
||||
|
@ -308,10 +356,9 @@ void PhysicsBody::addShape(PhysicsShape* shape)
|
|||
if (shape == nullptr) return;
|
||||
|
||||
// add shape to body
|
||||
if (std::find(_shapes.begin(), _shapes.end(), shape) == _shapes.end())
|
||||
if (_shapes->getIndexOfObject(shape) == UINT_MAX)
|
||||
{
|
||||
shape->setBody(this);
|
||||
_shapes.push_back(shape);
|
||||
|
||||
// calculate the area, mass, and desity
|
||||
// area must update before mass, because the density changes depend on it.
|
||||
|
@ -324,7 +371,7 @@ void PhysicsBody::addShape(PhysicsShape* shape)
|
|||
_world->addShape(shape);
|
||||
}
|
||||
|
||||
shape->retain();
|
||||
_shapes->addObject(shape);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -519,8 +566,9 @@ void PhysicsBody::setMoment(float moment)
|
|||
|
||||
PhysicsShape* PhysicsBody::getShapeByTag(int tag)
|
||||
{
|
||||
for (auto shape : _shapes)
|
||||
for (auto child : *_shapes)
|
||||
{
|
||||
PhysicsShape* shape = dynamic_cast<PhysicsShape*>(child);
|
||||
if (shape->getTag() == tag)
|
||||
{
|
||||
return shape;
|
||||
|
@ -532,8 +580,9 @@ PhysicsShape* PhysicsBody::getShapeByTag(int tag)
|
|||
|
||||
void PhysicsBody::removeShapeByTag(int tag)
|
||||
{
|
||||
for (auto shape : _shapes)
|
||||
for (auto child : *_shapes)
|
||||
{
|
||||
PhysicsShape* shape = dynamic_cast<PhysicsShape*>(child);
|
||||
if (shape->getTag() == tag)
|
||||
{
|
||||
removeShape(shape);
|
||||
|
@ -544,9 +593,7 @@ void PhysicsBody::removeShapeByTag(int tag)
|
|||
|
||||
void PhysicsBody::removeShape(PhysicsShape* shape)
|
||||
{
|
||||
auto it = std::find(_shapes.begin(), _shapes.end(), shape);
|
||||
|
||||
if (it != _shapes.end())
|
||||
if (_shapes->getIndexOfObject(shape) == UINT_MAX)
|
||||
{
|
||||
// deduce the area, mass and moment
|
||||
// area must update before mass, because the density changes depend on it.
|
||||
|
@ -559,25 +606,39 @@ void PhysicsBody::removeShape(PhysicsShape* shape)
|
|||
{
|
||||
_world->removeShape(shape);
|
||||
}
|
||||
_shapes.erase(it);
|
||||
shape->setBody(nullptr);
|
||||
shape->release();
|
||||
_shapes->removeObject(shape);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsBody::removeAllShapes()
|
||||
{
|
||||
for (auto shape : _shapes)
|
||||
for (auto child : *_shapes)
|
||||
{
|
||||
PhysicsShape* shape = dynamic_cast<PhysicsShape*>(child);
|
||||
|
||||
// deduce the area, mass and moment
|
||||
// area must update before mass, because the density changes depend on it.
|
||||
_area -= shape->getArea();
|
||||
addMass(-shape->getMass());
|
||||
addMoment(-shape->getMoment());
|
||||
|
||||
if (_world)
|
||||
{
|
||||
_world->removeShape(shape);
|
||||
}
|
||||
|
||||
delete shape;
|
||||
shape->setBody(nullptr);
|
||||
}
|
||||
|
||||
_shapes.clear();
|
||||
_shapes->removeAllObjects();
|
||||
}
|
||||
|
||||
void PhysicsBody::removeFromWorld()
|
||||
{
|
||||
if (_world)
|
||||
{
|
||||
_world->removeBody(this);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsBody::setEnable(bool enable)
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "CCObject.h"
|
||||
#include "CCGeometry.h"
|
||||
#include "CCArray.h"
|
||||
|
||||
#include "CCPhysicsShape.h"
|
||||
|
||||
|
@ -53,6 +54,8 @@ class PhysicsBody : public Object//, public Clonable
|
|||
{
|
||||
public:
|
||||
static PhysicsBody* create();
|
||||
static PhysicsBody* create(float mass);
|
||||
static PhysicsBody* create(float mass, float moment);
|
||||
/**
|
||||
* @brief Create a body contains a circle shape.
|
||||
*/
|
||||
|
@ -119,11 +122,11 @@ public:
|
|||
/*
|
||||
* @brief get the body shapes.
|
||||
*/
|
||||
inline std::vector<PhysicsShape*>& getShapes() { return _shapes; }
|
||||
inline Array* getShapes() { return _shapes; }
|
||||
/*
|
||||
* @brief get the first body shapes.
|
||||
*/
|
||||
inline PhysicsShape* getShape() { return _shapes.size() >= 1 ? _shapes.front() : nullptr; }
|
||||
inline PhysicsShape* getShape() { return _shapes->count() >= 1 ? dynamic_cast<PhysicsShape*>(_shapes->getObjectAtIndex(0)) : nullptr; }
|
||||
PhysicsShape* getShapeByTag(int tag);
|
||||
/*
|
||||
* @brief remove a shape from body
|
||||
|
@ -135,6 +138,8 @@ public:
|
|||
*/
|
||||
void removeAllShapes();
|
||||
|
||||
void removeFromWorld();
|
||||
|
||||
/*
|
||||
* @brief get the world body added to.
|
||||
*/
|
||||
|
@ -258,7 +263,7 @@ protected:
|
|||
protected:
|
||||
Sprite* _owner;
|
||||
std::vector<PhysicsJoint*> _joints;
|
||||
std::vector<PhysicsShape*> _shapes;
|
||||
Array* _shapes;
|
||||
PhysicsWorld* _world;
|
||||
PhysicsBodyInfo* _info;
|
||||
bool _dynamic;
|
||||
|
|
|
@ -61,9 +61,6 @@ PhysicsJoint::~PhysicsJoint()
|
|||
setCollisionEnable(true);
|
||||
|
||||
CC_SAFE_DELETE(_info);
|
||||
|
||||
CC_SAFE_RELEASE(_bodyA);
|
||||
CC_SAFE_RELEASE(_bodyB);
|
||||
}
|
||||
|
||||
bool PhysicsJoint::init(cocos2d::PhysicsBody *a, cocos2d::PhysicsBody *b)
|
||||
|
@ -75,14 +72,12 @@ bool PhysicsJoint::init(cocos2d::PhysicsBody *a, cocos2d::PhysicsBody *b)
|
|||
if (a != nullptr)
|
||||
{
|
||||
_bodyA = a;
|
||||
_bodyA->retain();
|
||||
_bodyA->_joints.push_back(this);
|
||||
}
|
||||
|
||||
if (b != nullptr)
|
||||
{
|
||||
_bodyB = b;
|
||||
_bodyB->retain();
|
||||
_bodyB->_joints.push_back(this);
|
||||
}
|
||||
|
||||
|
@ -174,7 +169,6 @@ PhysicsJointFixed* PhysicsJointFixed::create(PhysicsBody* a, PhysicsBody* b, con
|
|||
|
||||
if (joint && joint->init(a, b, anchr))
|
||||
{
|
||||
joint->autorelease();
|
||||
return joint;
|
||||
}
|
||||
|
||||
|
@ -191,12 +185,12 @@ bool PhysicsJointFixed::init(PhysicsBody* a, PhysicsBody* b, const Point& anchr)
|
|||
// add a pivot joint to fixed two body together
|
||||
cpConstraint* joint = cpPivotJointNew(bodyInfo(a)->body, bodyInfo(b)->body,
|
||||
PhysicsHelper::point2cpv(anchr));
|
||||
CC_BREAK_IF(joint);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
_info->add(joint);
|
||||
|
||||
// add a gear joint to make two body have the same rotation.
|
||||
joint = cpGearJointNew(bodyInfo(a)->body, bodyInfo(b)->body, 0, 1);
|
||||
CC_BREAK_IF(joint);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
_info->add(joint);
|
||||
|
||||
setCollisionEnable(false);
|
||||
|
@ -213,7 +207,6 @@ PhysicsJointPin* PhysicsJointPin::create(PhysicsBody* a, PhysicsBody* b, const P
|
|||
|
||||
if (joint && joint->init(a, b, anchr))
|
||||
{
|
||||
joint->autorelease();
|
||||
return joint;
|
||||
}
|
||||
|
||||
|
@ -230,7 +223,7 @@ bool PhysicsJointPin::init(PhysicsBody *a, PhysicsBody *b, const Point& anchr)
|
|||
cpConstraint* joint = cpPivotJointNew(bodyInfo(a)->body, bodyInfo(b)->body,
|
||||
PhysicsHelper::point2cpv(anchr));
|
||||
|
||||
CC_BREAK_IF(joint);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
|
||||
_info->add(joint);
|
||||
|
||||
|
@ -266,7 +259,7 @@ bool PhysicsJointSliding::init(PhysicsBody* a, PhysicsBody* b, const Point& groo
|
|||
PhysicsHelper::point2cpv(grooveB),
|
||||
PhysicsHelper::point2cpv(anchr));
|
||||
|
||||
CC_BREAK_IF(joint);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
|
||||
_info->add(joint);
|
||||
|
||||
|
@ -302,7 +295,7 @@ bool PhysicsJointLimit::init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1
|
|||
0,
|
||||
PhysicsHelper::float2cpfloat(anchr1.getDistance(anchr2)));
|
||||
|
||||
CC_BREAK_IF(joint);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
|
||||
_info->add(joint);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class PhysicsBodyInfo;
|
|||
/*
|
||||
* @brief An PhysicsJoint object connects two physics bodies together.
|
||||
*/
|
||||
class PhysicsJoint : public Object
|
||||
class PhysicsJoint
|
||||
{
|
||||
protected:
|
||||
PhysicsJoint();
|
||||
|
|
|
@ -177,18 +177,27 @@ void PhysicsWorldCallback::nearestPointQueryFunc(cpShape *shape, cpFloat distanc
|
|||
|
||||
bool PhysicsWorld::init()
|
||||
{
|
||||
_info = new PhysicsWorldInfo();
|
||||
do
|
||||
{
|
||||
_info = new PhysicsWorldInfo();
|
||||
CC_BREAK_IF(_info == nullptr);
|
||||
_bodys = Array::create();
|
||||
CC_BREAK_IF(_bodys == nullptr);
|
||||
_bodys->retain();
|
||||
|
||||
cpSpaceSetGravity(_info->space, PhysicsHelper::point2cpv(_gravity));
|
||||
|
||||
cpSpaceSetDefaultCollisionHandler(_info->space,
|
||||
(cpCollisionBeginFunc)PhysicsWorldCallback::collisionBeginCallbackFunc,
|
||||
(cpCollisionPreSolveFunc)PhysicsWorldCallback::collisionPreSolveCallbackFunc,
|
||||
(cpCollisionPostSolveFunc)PhysicsWorldCallback::collisionPostSolveCallbackFunc,
|
||||
(cpCollisionSeparateFunc)PhysicsWorldCallback::collisionSeparateCallbackFunc,
|
||||
this);
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
||||
cpSpaceSetGravity(_info->space, PhysicsHelper::point2cpv(_gravity));
|
||||
|
||||
cpSpaceSetDefaultCollisionHandler(_info->space,
|
||||
(cpCollisionBeginFunc)PhysicsWorldCallback::collisionBeginCallbackFunc,
|
||||
(cpCollisionPreSolveFunc)PhysicsWorldCallback::collisionPreSolveCallbackFunc,
|
||||
(cpCollisionPostSolveFunc)PhysicsWorldCallback::collisionPostSolveCallbackFunc,
|
||||
(cpCollisionSeparateFunc)PhysicsWorldCallback::collisionSeparateCallbackFunc,
|
||||
this);
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void PhysicsWorld::addJoint(PhysicsJoint* joint)
|
||||
|
@ -197,8 +206,6 @@ void PhysicsWorld::addJoint(PhysicsJoint* joint)
|
|||
|
||||
if (it == _joints.end())
|
||||
{
|
||||
_joints.push_back(joint);
|
||||
|
||||
for (auto subjoint : joint->_info->joints)
|
||||
{
|
||||
if (!cpSpaceContainsConstraint(_info->space, subjoint))
|
||||
|
@ -206,18 +213,44 @@ void PhysicsWorld::addJoint(PhysicsJoint* joint)
|
|||
cpSpaceAddConstraint(_info->space, subjoint);
|
||||
}
|
||||
}
|
||||
|
||||
_joints.push_back(joint);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeJoint(PhysicsJoint* joint)
|
||||
{
|
||||
auto it = std::find(_joints.begin(), _joints.end(), joint);
|
||||
|
||||
if (it != _joints.end())
|
||||
{
|
||||
for (auto subjoint : joint->_info->joints)
|
||||
{
|
||||
if (cpSpaceContainsConstraint(_info->space, subjoint))
|
||||
{
|
||||
cpSpaceRemoveConstraint(_info->space, subjoint);
|
||||
}
|
||||
}
|
||||
|
||||
_joints.remove(joint);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeAllJoints()
|
||||
{
|
||||
for (auto joint : _joints)
|
||||
{
|
||||
for (auto subjoint : joint->_info->joints)
|
||||
{
|
||||
if (!cpSpaceContainsConstraint(_info->space, subjoint))
|
||||
{
|
||||
cpSpaceRemoveConstraint(_info->space, subjoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_joints.clear();
|
||||
}
|
||||
|
||||
void PhysicsWorld::addShape(PhysicsShape* shape)
|
||||
|
@ -243,8 +276,15 @@ void PhysicsWorld::addBody(PhysicsBody* body)
|
|||
{
|
||||
CCASSERT(body != nullptr, "the body can not be nullptr");
|
||||
|
||||
if (body->getWorld() != this && body->getWorld() != nullptr)
|
||||
{
|
||||
body->removeFromWorld();
|
||||
}
|
||||
|
||||
if (body->isEnable())
|
||||
{
|
||||
body->_world = this;
|
||||
|
||||
//is gravity enable
|
||||
if (!body->isGravityEnable())
|
||||
{
|
||||
|
@ -258,45 +298,40 @@ void PhysicsWorld::addBody(PhysicsBody* body)
|
|||
}
|
||||
|
||||
// add shapes to space
|
||||
for (auto shape : body->getShapes())
|
||||
for (auto shape : *body->getShapes())
|
||||
{
|
||||
addShape(shape);
|
||||
addShape(dynamic_cast<PhysicsShape*>(shape));
|
||||
}
|
||||
}
|
||||
|
||||
if (_bodys == nullptr)
|
||||
{
|
||||
_bodys = Array::create(body, NULL);
|
||||
_bodys->retain();
|
||||
}else
|
||||
{
|
||||
_bodys->addObject(body);
|
||||
}
|
||||
_bodys->addObject(body);
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeBody(PhysicsBody* body)
|
||||
{
|
||||
CCASSERT(body != nullptr, "the body can not be nullptr");
|
||||
|
||||
if (body->getWorld() == this)
|
||||
if (body->getWorld() != this)
|
||||
{
|
||||
// reset the gravity
|
||||
if (!body->isGravityEnable())
|
||||
{
|
||||
body->applyForce(-_gravity);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// reset the gravity
|
||||
if (!body->isGravityEnable())
|
||||
{
|
||||
body->applyForce(-_gravity);
|
||||
}
|
||||
|
||||
// remove joints
|
||||
for (auto joint : body->_joints)
|
||||
{
|
||||
removeJoint(joint);
|
||||
}
|
||||
|
||||
// remove shaps
|
||||
for (auto shape : body->getShapes())
|
||||
for (auto shape : *body->getShapes())
|
||||
{
|
||||
for (auto cps : shape->_info->shapes)
|
||||
{
|
||||
if (cpSpaceContainsShape(_info->space, cps))
|
||||
{
|
||||
cpSpaceRemoveShape(_info->space, cps);
|
||||
}
|
||||
}
|
||||
removeShape(dynamic_cast<PhysicsShape*>(shape));
|
||||
}
|
||||
|
||||
// remove body
|
||||
|
@ -305,10 +340,8 @@ void PhysicsWorld::removeBody(PhysicsBody* body)
|
|||
cpSpaceRemoveBody(_info->space, body->_info->body);
|
||||
}
|
||||
|
||||
if (_bodys != nullptr)
|
||||
{
|
||||
_bodys->removeObject(body);
|
||||
}
|
||||
body->_world = nullptr;
|
||||
_bodys->removeObject(body);
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeBodyByTag(int tag)
|
||||
|
@ -324,6 +357,43 @@ void PhysicsWorld::removeBodyByTag(int tag)
|
|||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeAllBodys()
|
||||
{
|
||||
for (Object* obj : *_bodys)
|
||||
{
|
||||
PhysicsBody* body = dynamic_cast<PhysicsBody*>(obj);
|
||||
|
||||
// reset the gravity
|
||||
if (!body->isGravityEnable())
|
||||
{
|
||||
body->applyForce(-_gravity);
|
||||
}
|
||||
|
||||
// remove joints
|
||||
for (auto joint : body->_joints)
|
||||
{
|
||||
removeJoint(joint);
|
||||
}
|
||||
|
||||
// remove shaps
|
||||
for (auto shape : *body->getShapes())
|
||||
{
|
||||
removeShape(dynamic_cast<PhysicsShape*>(shape));
|
||||
}
|
||||
|
||||
// remove body
|
||||
if (cpSpaceContainsBody(_info->space, body->_info->body))
|
||||
{
|
||||
cpSpaceRemoveBody(_info->space, body->_info->body);
|
||||
}
|
||||
|
||||
body->_world = nullptr;
|
||||
}
|
||||
|
||||
_bodys->removeAllObjects();
|
||||
CC_SAFE_RELEASE(_bodys);
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeShape(PhysicsShape* shape)
|
||||
{
|
||||
for (auto cps : shape->_info->shapes)
|
||||
|
@ -366,11 +436,9 @@ void PhysicsWorld::debugDraw()
|
|||
{
|
||||
PhysicsBody* body = dynamic_cast<PhysicsBody*>(obj);
|
||||
|
||||
std::vector<PhysicsShape*> shapes = body->getShapes();
|
||||
|
||||
for (auto shape : shapes)
|
||||
for (auto shape : *body->getShapes())
|
||||
{
|
||||
drawWithShape(_drawNode, shape);
|
||||
drawWithShape(_drawNode, dynamic_cast<PhysicsShape*>(shape));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -449,6 +517,11 @@ int PhysicsWorld::collisionBeginCallback(PhysicsContact& contact)
|
|||
// check the joint is collision enable or not
|
||||
for (PhysicsJoint* joint : jointsA)
|
||||
{
|
||||
if (std::find(_joints.begin(), _joints.end(), joint) == _joints.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!joint->isCollisionEnable())
|
||||
{
|
||||
PhysicsBody* body = joint->getBodyA() == bodyA ? bodyB : bodyA;
|
||||
|
@ -657,8 +730,9 @@ PhysicsWorld::PhysicsWorld()
|
|||
|
||||
PhysicsWorld::~PhysicsWorld()
|
||||
{
|
||||
removeAllBodys();
|
||||
removeAllJoints();
|
||||
CC_SAFE_DELETE(_info);
|
||||
CC_SAFE_RELEASE(_bodys);
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -116,6 +116,7 @@ public:
|
|||
|
||||
virtual void removeBody(PhysicsBody* body);
|
||||
virtual void removeBodyByTag(int tag);
|
||||
virtual void removeAllBodys();
|
||||
|
||||
protected:
|
||||
static PhysicsWorld* create();
|
||||
|
|
|
@ -92,7 +92,6 @@ PhysicsDemo::PhysicsDemo()
|
|||
: _scene(nullptr)
|
||||
, _ball(nullptr)
|
||||
, _spriteTexture(nullptr)
|
||||
, _mouse(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -160,7 +159,7 @@ void PhysicsDemo::onEnter()
|
|||
#endif
|
||||
}
|
||||
|
||||
void PhysicsDemo::addGrossiniAtPosition(Point p, float scale/* = 1.0*/)
|
||||
Sprite* PhysicsDemo::addGrossiniAtPosition(Point p, float scale/* = 1.0*/)
|
||||
{
|
||||
#ifdef CC_USE_PHYSICS
|
||||
CCLOG("Add sprite %0.2f x %02.f",p.x,p.y);
|
||||
|
@ -178,6 +177,8 @@ void PhysicsDemo::addGrossiniAtPosition(Point p, float scale/* = 1.0*/)
|
|||
sp->setPhysicsBody(PhysicsBody::createBox(Size(48.0f * scale, 108.0f * scale)));
|
||||
this->addChild(sp);
|
||||
sp->setPosition(p);
|
||||
|
||||
return sp;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -367,28 +368,60 @@ Sprite* PhysicsDemo::makeTriangle(float x, float y, Size size, PhysicsMaterial m
|
|||
return triangle;
|
||||
}
|
||||
|
||||
void PhysicsDemo::onTouchesBegan(const std::vector<Touch*>& touches, Event* event)
|
||||
bool PhysicsDemo::onTouchBegan(Touch* touch, Event* event)
|
||||
{
|
||||
for( auto &touch: touches)
|
||||
auto location = touch->getLocation();
|
||||
Array* arr = _scene->getPhysicsWorld()->getShapesAtPoint(location);
|
||||
|
||||
PhysicsShape* shape = nullptr;
|
||||
for (Object* obj : *arr)
|
||||
{
|
||||
auto location = touch->getLocation();
|
||||
Array* arr = _scene->getPhysicsWorld()->getShapesAtPoint(location);
|
||||
shape = dynamic_cast<PhysicsShape*>(obj);
|
||||
|
||||
PhysicsShape* shape = nullptr;
|
||||
for (Object* obj : *arr)
|
||||
if (shape->getTag() == 1)
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (shape != nullptr)
|
||||
{
|
||||
|
||||
Node* mouse = Node::create();
|
||||
mouse->setPhysicsBody(PhysicsBody::create(PHYSICS_INFINITY, PHYSICS_INFINITY));
|
||||
mouse->getPhysicsBody()->setDynamic(false);
|
||||
mouse->setPosition(location);
|
||||
this->addChild(mouse);
|
||||
PhysicsJoint* joint = PhysicsJointPin::create(mouse->getPhysicsBody(), shape->getBody(), location);
|
||||
_scene->getPhysicsWorld()->addJoint(joint);
|
||||
_mouses.insert(std::make_pair(touch->getID(), mouse));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PhysicsDemo::onTouchMoved(Touch* touch, Event* event)
|
||||
{
|
||||
auto it = _mouses.find(touch->getID());
|
||||
|
||||
if (it != _mouses.end())
|
||||
{
|
||||
it->second->getPhysicsBody()->setVelocity((touch->getLocation() - it->second->getPosition()) * 60.0f);
|
||||
it->second->setPosition(touch->getLocation());
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsDemo::onTouchesMoved(const std::vector<Touch*>& touches, Event* event)
|
||||
void PhysicsDemo::onTouchEnded(Touch* touch, Event* event)
|
||||
{
|
||||
auto it = _mouses.find(touch->getID());
|
||||
|
||||
}
|
||||
|
||||
void PhysicsDemo::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
|
||||
{
|
||||
if (it != _mouses.end())
|
||||
{
|
||||
this->removeChild(it->second);
|
||||
_mouses.erase(it);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -440,6 +473,9 @@ void PhysicsDemoPyramidStack::onEnter()
|
|||
{
|
||||
PhysicsDemo::onEnter();
|
||||
|
||||
setTouchEnabled(true);
|
||||
setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
|
||||
|
||||
auto node = Node::create();
|
||||
node->setPhysicsBody(PhysicsBody::createEdgeSegment(VisibleRect::leftBottom() + Point(0, 50), VisibleRect::rightBottom() + Point(0, 50)));
|
||||
this->addChild(node);
|
||||
|
@ -454,7 +490,9 @@ void PhysicsDemoPyramidStack::onEnter()
|
|||
{
|
||||
for(int j=0; j<=i; j++)
|
||||
{
|
||||
addGrossiniAtPosition(VisibleRect::bottom() + Point((i/2 - j) * 11, (14 - i) * 23 + 100), 0.2f);
|
||||
auto sp = addGrossiniAtPosition(VisibleRect::bottom() + Point((i/2 - j) * 11, (14 - i) * 23 + 100), 0.2f);
|
||||
|
||||
sp->getPhysicsBody()->setTag(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "../testBasic.h"
|
||||
#include "../BaseTest.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
|
||||
class PhysicsTestScene : public TestScene
|
||||
{
|
||||
|
@ -36,19 +38,19 @@ public:
|
|||
void backCallback(Object* sender);
|
||||
void toggleDebugCallback(Object* sender);
|
||||
|
||||
void addGrossiniAtPosition(Point p, float scale = 1.0);
|
||||
Sprite* addGrossiniAtPosition(Point p, float scale = 1.0);
|
||||
Sprite* makeBall(float x, float y, float radius, PhysicsMaterial material = PhysicsMaterial(1.0f, 1.0f, 1.0f));
|
||||
Sprite* makeBox(float x, float y, Size size, PhysicsMaterial material = PhysicsMaterial(1.0f, 1.0f, 1.0f));
|
||||
Sprite* makeTriangle(float x, float y, Size size, PhysicsMaterial material = PhysicsMaterial(1.0f, 1.0f, 1.0f));
|
||||
|
||||
void onTouchesBegan(const std::vector<Touch*>& touches, Event* event) override;
|
||||
void onTouchesMoved(const std::vector<Touch*>& touches, Event* event) override;
|
||||
void onTouchesEnded(const std::vector<Touch*>& touches, Event* event) override;
|
||||
bool onTouchBegan(Touch* touch, Event* event) override;
|
||||
void onTouchMoved(Touch* touch, Event* event) override;
|
||||
void onTouchEnded(Touch* touch, Event* event) override;
|
||||
|
||||
protected:
|
||||
Texture2D* _spriteTexture; // weak ref
|
||||
SpriteBatchNode* _ball;
|
||||
DrawNode* _mouse;
|
||||
std::map<int, Node*> _mouses;
|
||||
};
|
||||
|
||||
class PhysicsDemoClickAdd : public PhysicsDemo
|
||||
|
|
Loading…
Reference in New Issue