mirror of https://github.com/axmolengine/axmol.git
Merge pull request #3916 from boyu0/iss2771_physical
[ci skip]issue 2771: physical
This commit is contained in:
commit
0130aae044
|
@ -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
|
||||
|
@ -340,6 +362,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
|
||||
|
@ -808,6 +839,7 @@ void Node::visit()
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
kmGLPushMatrix();
|
||||
|
||||
if (_grid && _grid->isActive())
|
||||
|
@ -1268,6 +1300,16 @@ Point Node::convertTouchToNodeSpaceAR(Touch *touch) const
|
|||
|
||||
void Node::updateTransform()
|
||||
{
|
||||
#ifdef CC_USE_PHYSICS
|
||||
if (_physicsBody)
|
||||
{
|
||||
_physicsPositionMark = false;
|
||||
_physicsRotationMark = false;
|
||||
setPosition(_physicsBody->getPosition());
|
||||
setRotation(_physicsBody->getRotation());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Recursively iterate over children
|
||||
arrayMakeObjectsPerformSelector(_children, updateTransform, Node*);
|
||||
}
|
||||
|
@ -1337,6 +1379,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)
|
||||
|
|
|
@ -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
|
||||
|
@ -1374,6 +1378,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:
|
||||
|
@ -1486,6 +1503,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
|
||||
|
|
|
@ -28,12 +28,13 @@ THE SOFTWARE.
|
|||
#include "CCDirector.h"
|
||||
#include "CCLayer.h"
|
||||
#include "sprite_nodes/CCSprite.h"
|
||||
#include "sprite_nodes/CCSpriteBatchNode.h"
|
||||
#include "physics/CCPhysicsWorld.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
Scene::Scene()
|
||||
#ifdef _physicsWorld
|
||||
#ifdef CC_USE_PHYSICS
|
||||
: _physicsWorld(nullptr)
|
||||
#endif
|
||||
{
|
||||
|
@ -43,6 +44,9 @@ Scene::Scene()
|
|||
|
||||
Scene::~Scene()
|
||||
{
|
||||
#ifdef CC_USE_PHYSICS
|
||||
CC_SAFE_DELETE(_physicsWorld);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Scene::init()
|
||||
|
@ -129,15 +133,23 @@ void Scene::addChildToPhysicsWorld(Node* child)
|
|||
{
|
||||
if (_physicsWorld)
|
||||
{
|
||||
auto addToPhysicsWorldFunc = [this](Object* node) -> void
|
||||
std::function<void(Object*)> addToPhysicsWorldFunc = nullptr;
|
||||
addToPhysicsWorldFunc = [this, &addToPhysicsWorldFunc](Object* child) -> void
|
||||
{
|
||||
if (dynamic_cast<Sprite*>(node) != nullptr)
|
||||
if (dynamic_cast<SpriteBatchNode*>(child) != nullptr)
|
||||
{
|
||||
Sprite* sp = dynamic_cast<Sprite*>(node);
|
||||
|
||||
if (sp->getPhysicsBody())
|
||||
Object* subChild = nullptr;
|
||||
CCARRAY_FOREACH((dynamic_cast<SpriteBatchNode*>(child))->getChildren(), subChild)
|
||||
{
|
||||
_physicsWorld->addChild(sp->getPhysicsBody());
|
||||
addToPhysicsWorldFunc(subChild);
|
||||
}
|
||||
}else if (dynamic_cast<Node*>(child) != nullptr)
|
||||
{
|
||||
Node* node = dynamic_cast<Node*>(child);
|
||||
|
||||
if (node->getPhysicsBody())
|
||||
{
|
||||
_physicsWorld->addBody(node->getPhysicsBody());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -88,6 +88,7 @@ protected:
|
|||
#endif // CC_USE_PHYSICS
|
||||
|
||||
friend class Layer;
|
||||
friend class SpriteBatchNode;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include "Box2D/CCPhysicsJointInfo.h"
|
||||
#include "chipmunk/CCPhysicsWorldInfo.h"
|
||||
#include "Box2D/CCPhysicsWorldInfo.h"
|
||||
#include "chipmunk/CCPhysicsShapeInfo.h"
|
||||
#include "Box2D/CCPhysicsShapeInfo.h"
|
||||
|
||||
#include "chipmunk/CCPhysicsHelper.h"
|
||||
#include "Box2D/CCPhysicsHelper.h"
|
||||
|
@ -62,13 +64,15 @@ PhysicsBody::PhysicsBody()
|
|||
: _owner(nullptr)
|
||||
, _world(nullptr)
|
||||
, _info(nullptr)
|
||||
, _dynamic(false)
|
||||
, _dynamic(true)
|
||||
, _enable(true)
|
||||
, _massDefault(true)
|
||||
, _angularDampingDefault(true)
|
||||
, _mass(MASS_DEFAULT)
|
||||
, _area(0.0)
|
||||
, _density(DENSITY_DEFAULT)
|
||||
, _angularDamping(ANGULARDAMPING_DEFAULT)
|
||||
, _tag(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -76,10 +80,7 @@ PhysicsBody::~PhysicsBody()
|
|||
{
|
||||
CC_SAFE_DELETE(_info);
|
||||
|
||||
for (auto it = _shapes.begin(); it != _shapes.end(); ++it)
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
removeAllShapes();
|
||||
|
||||
for (auto it = _joints.begin(); it != _joints.end(); ++it)
|
||||
{
|
||||
|
@ -91,12 +92,11 @@ PhysicsBody::~PhysicsBody()
|
|||
}
|
||||
}
|
||||
|
||||
PhysicsBody* PhysicsBody::createCircle(float radius)
|
||||
PhysicsBody* PhysicsBody::create()
|
||||
{
|
||||
PhysicsBody* body = new PhysicsBody();
|
||||
if (body && body->init())
|
||||
{
|
||||
body->addCircle(radius);
|
||||
body->autorelease();
|
||||
return body;
|
||||
}
|
||||
|
@ -105,12 +105,12 @@ PhysicsBody* PhysicsBody::createCircle(float radius)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
PhysicsBody* PhysicsBody::createBox(Size size)
|
||||
PhysicsBody* PhysicsBody::createCircle(float radius, PhysicsMaterial material)
|
||||
{
|
||||
PhysicsBody* body = new PhysicsBody();
|
||||
if (body && body->init())
|
||||
{
|
||||
body->addBox(size);
|
||||
body->addShape(PhysicsShapeCircle::create(radius, material));
|
||||
body->autorelease();
|
||||
return body;
|
||||
}
|
||||
|
@ -119,12 +119,12 @@ PhysicsBody* PhysicsBody::createBox(Size size)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
PhysicsBody* PhysicsBody::createPolygon(Point* points, int count)
|
||||
PhysicsBody* PhysicsBody::createBox(Size size, PhysicsMaterial material)
|
||||
{
|
||||
PhysicsBody* body = new PhysicsBody();
|
||||
if (body && body->init())
|
||||
{
|
||||
body->addPolygon(points, count);
|
||||
body->addShape(PhysicsShapeBox::create(size, material));
|
||||
body->autorelease();
|
||||
return body;
|
||||
}
|
||||
|
@ -133,12 +133,12 @@ PhysicsBody* PhysicsBody::createPolygon(Point* points, int count)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
PhysicsBody* PhysicsBody::createEdgeSegment(Point a, Point b, float border/* = 1*/)
|
||||
PhysicsBody* PhysicsBody::createPolygon(Point* points, int count, PhysicsMaterial material)
|
||||
{
|
||||
PhysicsBody* body = new PhysicsBody();
|
||||
if (body && body->initStatic())
|
||||
if (body && body->init())
|
||||
{
|
||||
body->addEdgeSegment(a, b, border);
|
||||
body->addShape(PhysicsShapePolygon::create(points, count, material));
|
||||
body->autorelease();
|
||||
return body;
|
||||
}
|
||||
|
@ -147,27 +147,28 @@ PhysicsBody* PhysicsBody::createEdgeSegment(Point a, Point b, float border/* = 1
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
PhysicsBody* PhysicsBody::createEdgeBox(Size size, float border/* = 1*/)
|
||||
PhysicsBody* PhysicsBody::createEdgeSegment(Point a, Point b, PhysicsMaterial material, float border/* = 1*/)
|
||||
{
|
||||
PhysicsBody* body = new PhysicsBody();
|
||||
if (body && body->initStatic())
|
||||
if (body && body->init())
|
||||
{
|
||||
body->addEdgeBox(size, border);
|
||||
body->addShape(PhysicsShapeEdgeSegment::create(a, b, material, border));
|
||||
body->_dynamic = false;
|
||||
body->autorelease();
|
||||
return body;
|
||||
}
|
||||
|
||||
CC_SAFE_DELETE(body);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PhysicsBody* PhysicsBody::createEdgePolygon(Point* points, int count, float border/* = 1*/)
|
||||
PhysicsBody* PhysicsBody::createEdgeBox(Size size, PhysicsMaterial material, float border/* = 1*/)
|
||||
{
|
||||
PhysicsBody* body = new PhysicsBody();
|
||||
if (body && body->initStatic())
|
||||
if (body && body->init())
|
||||
{
|
||||
body->addEdgePolygon(points, count, border);
|
||||
body->addShape(PhysicsShapeEdgeBox::create(size, material, border));
|
||||
body->_dynamic = false;
|
||||
body->autorelease();
|
||||
return body;
|
||||
}
|
||||
|
@ -177,12 +178,13 @@ PhysicsBody* PhysicsBody::createEdgePolygon(Point* points, int count, float bord
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
PhysicsBody* PhysicsBody::createEdgeChain(Point* points, int count, float border/* = 1*/)
|
||||
PhysicsBody* PhysicsBody::createEdgePolygon(Point* points, int count, PhysicsMaterial material, float border/* = 1*/)
|
||||
{
|
||||
PhysicsBody* body = new PhysicsBody();
|
||||
if (body && body->initStatic())
|
||||
if (body && body->init())
|
||||
{
|
||||
body->addEdgeChain(points, count);
|
||||
body->addShape(PhysicsShapeEdgePolygon::create(points, count, material, border));
|
||||
body->_dynamic = false;
|
||||
body->autorelease();
|
||||
return body;
|
||||
}
|
||||
|
@ -192,67 +194,20 @@ PhysicsBody* PhysicsBody::createEdgeChain(Point* points, int count, float border
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
PhysicsShapeCircle* PhysicsBody::addCircle(float radius, Point offset/* = Point(0, 0)*/)
|
||||
PhysicsBody* PhysicsBody::createEdgeChain(Point* points, int count, PhysicsMaterial material, float border/* = 1*/)
|
||||
{
|
||||
_area = PhysicsHelper::cpfloat2float(cpAreaForCircle(0, radius));
|
||||
setMass((_massDefault ? 0 : getMass()) + _area * _density);
|
||||
PhysicsBody* body = new PhysicsBody();
|
||||
if (body && body->init())
|
||||
{
|
||||
body->addShape(PhysicsShapeEdgeChain::create(points, count, material, border));
|
||||
body->_dynamic = false;
|
||||
body->autorelease();
|
||||
return body;
|
||||
}
|
||||
|
||||
setAngularDamping((_angularDampingDefault ? 0 : getAngularDamping())
|
||||
+ PhysicsHelper::cpfloat2float(cpMomentForCircle(getMass(), 0, radius, PhysicsHelper::point2cpv(offset))));
|
||||
CC_SAFE_DELETE(body);
|
||||
|
||||
return PhysicsShapeCircle::create(this, radius, offset);
|
||||
}
|
||||
|
||||
PhysicsShapeBox* PhysicsBody::addBox(Size size, Point offset/* = Point(0, 0)*/)
|
||||
{
|
||||
cpVect cpOffset = PhysicsHelper::size2cpv(size);
|
||||
cpVect vec[4] = {};
|
||||
vec[0] = cpv(0, 0);
|
||||
vec[1] = cpv(0, cpOffset.y);
|
||||
vec[2] = cpv(cpOffset.x, cpOffset.y);
|
||||
vec[3] = cpv(cpOffset.x, 0);
|
||||
|
||||
_area = PhysicsHelper::cpfloat2float(cpAreaForPoly(4, vec));
|
||||
setMass((_massDefault ? 0 : getMass()) + _area * _density);
|
||||
|
||||
setAngularDamping((_angularDampingDefault ? 0 : getAngularDamping())
|
||||
+ PhysicsHelper::cpfloat2float(cpMomentForBox(getMass(), PhysicsHelper::float2cpfloat(size.width), PhysicsHelper::float2cpfloat(size.height))));
|
||||
|
||||
return PhysicsShapeBox::create(this, size, offset);
|
||||
}
|
||||
|
||||
PhysicsShapePolygon* PhysicsBody::addPolygon(Point* points, int count, Point offset/* = Point(0, 0)*/)
|
||||
{
|
||||
cpVect* vec = new cpVect[count];
|
||||
PhysicsHelper::points2cpvs(points, vec, count);
|
||||
_area = PhysicsHelper::cpfloat2float(cpAreaForPoly(count, vec));
|
||||
|
||||
setAngularDamping((_angularDampingDefault ? 0 : getAngularDamping())
|
||||
+ PhysicsHelper::cpfloat2float(cpMomentForPoly(getMass(), count, vec, PhysicsHelper::point2cpv(offset))));
|
||||
|
||||
delete[] vec;
|
||||
|
||||
return PhysicsShapePolygon::create(this, points, count, offset);
|
||||
}
|
||||
|
||||
PhysicsShapeEdgeSegment* PhysicsBody::addEdgeSegment(Point a, Point b, float border/* = 1*/)
|
||||
{
|
||||
return PhysicsShapeEdgeSegment::create(this, a, b, border);
|
||||
}
|
||||
|
||||
PhysicsShapeEdgeBox* PhysicsBody::addEdgeBox(Size size, float border/* = 1*/, Point offset/* = Point(0, 0)*/)
|
||||
{
|
||||
return PhysicsShapeEdgeBox::create(this, size, border, offset);
|
||||
}
|
||||
|
||||
PhysicsShapeEdgePolygon* PhysicsBody::addEdgePolygon(Point* points, int count, float border/* = 1*/)
|
||||
{
|
||||
return PhysicsShapeEdgePolygon::create(this, points, count);
|
||||
}
|
||||
|
||||
PhysicsShapeEdgeChain* PhysicsBody::addEdgeChain(Point* points, int count, float border/* = 1*/)
|
||||
{
|
||||
return PhysicsShapeEdgeChain::create(this, points, count, border);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsBody::init()
|
||||
|
@ -264,7 +219,6 @@ bool PhysicsBody::init()
|
|||
|
||||
_info->body = cpBodyNew(PhysicsHelper::float2cpfloat(_mass), PhysicsHelper::float2cpfloat(_angularDamping));
|
||||
CC_BREAK_IF(_info->body == nullptr);
|
||||
_dynamic = true;
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -274,36 +228,22 @@ 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, PHYSICS_INFINITY);
|
||||
cpBodySetMoment(_info->body, PHYSICS_INFINITY);
|
||||
}
|
||||
|
||||
_dynamic = dynamic;
|
||||
}
|
||||
}
|
||||
|
||||
bool PhysicsBody::initStatic()
|
||||
{
|
||||
do
|
||||
{
|
||||
_info = new PhysicsBodyInfo();
|
||||
CC_BREAK_IF(_info == nullptr);
|
||||
|
||||
_info->body = cpBodyNewStatic();
|
||||
CC_BREAK_IF(_info->body == nullptr);
|
||||
_dynamic = false;
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PhysicsBody::setPosition(Point position)
|
||||
{
|
||||
cpBodySetPos(_info->body, PhysicsHelper::point2cpv(position));
|
||||
|
@ -329,9 +269,79 @@ void PhysicsBody::addShape(PhysicsShape* shape)
|
|||
{
|
||||
if (shape == nullptr) return;
|
||||
|
||||
_shapes.push_back(shape);
|
||||
// already added
|
||||
if (shape->getBody() == this)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (shape->getBody() != nullptr)
|
||||
{
|
||||
shape->getBody()->removeShape(shape);
|
||||
}
|
||||
|
||||
if (_world != nullptr) _world->addShape(shape);
|
||||
// reset the body
|
||||
if (shape->_info->body != _info->body)
|
||||
{
|
||||
for (cpShape* subShape : shape->_info->shapes)
|
||||
{
|
||||
cpShapeSetBody(subShape, _info->body);
|
||||
}
|
||||
shape->_info->body = _info->body;
|
||||
}
|
||||
|
||||
// add shape to body
|
||||
if (std::find(_shapes.begin(), _shapes.end(), shape) == _shapes.end())
|
||||
{
|
||||
shape->setBody(this);
|
||||
_shapes.push_back(shape);
|
||||
|
||||
// calculate the mass, area and desity
|
||||
_area += shape->getArea();
|
||||
if (_mass == PHYSICS_INFINITY || shape->getMass() == PHYSICS_INFINITY)
|
||||
{
|
||||
_mass = PHYSICS_INFINITY;
|
||||
_massDefault = false;
|
||||
}else
|
||||
{
|
||||
if (shape->getMass() > 0)
|
||||
{
|
||||
_mass = (_massDefault ? 0 : _mass) + shape->getMass();
|
||||
_massDefault = false;
|
||||
}
|
||||
}
|
||||
cpBodySetMass(_info->body, _mass);
|
||||
|
||||
if (!_massDefault)
|
||||
{
|
||||
if (_mass == PHYSICS_INFINITY)
|
||||
{
|
||||
_density = PHYSICS_INFINITY;
|
||||
}else
|
||||
{
|
||||
_density = _mass / _area;
|
||||
}
|
||||
}
|
||||
|
||||
if (shape->getAngularDumping() > 0)
|
||||
{
|
||||
if (shape->getAngularDumping() == INFINITY)
|
||||
{
|
||||
_angularDamping = INFINITY;
|
||||
_angularDampingDefault = false;
|
||||
cpBodySetMoment(_info->body, _angularDamping);
|
||||
}
|
||||
else if (_angularDamping != INFINITY)
|
||||
{
|
||||
_angularDamping = (_angularDampingDefault ? 0 : _angularDamping) + shape->getAngularDumping();
|
||||
_angularDampingDefault = false;
|
||||
cpBodySetMoment(_info->body, _angularDamping);
|
||||
}
|
||||
}
|
||||
|
||||
if (_world != nullptr) _world->addShape(shape);
|
||||
|
||||
shape->retain();
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsBody::applyForce(Point force)
|
||||
|
@ -367,6 +377,16 @@ void PhysicsBody::setMass(float mass)
|
|||
cpBodySetMass(_info->body, PhysicsHelper::float2cpfloat(_mass));
|
||||
}
|
||||
|
||||
void PhysicsBody::setVelocity(Point velocity)
|
||||
{
|
||||
cpBodySetVel(_info->body, PhysicsHelper::point2cpv(velocity));
|
||||
}
|
||||
|
||||
Point PhysicsBody::getVelocity()
|
||||
{
|
||||
return PhysicsHelper::cpv2point(cpBodyGetVel(_info->body));
|
||||
}
|
||||
|
||||
void PhysicsBody::setAngularDamping(float angularDamping)
|
||||
{
|
||||
_angularDamping = angularDamping;
|
||||
|
@ -375,6 +395,120 @@ void PhysicsBody::setAngularDamping(float angularDamping)
|
|||
cpBodySetMoment(_info->body, _angularDamping);
|
||||
}
|
||||
|
||||
PhysicsShape* PhysicsBody::getShapeByTag(int tag)
|
||||
{
|
||||
for (auto shape : _shapes)
|
||||
{
|
||||
if (shape->getTag() == tag)
|
||||
{
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PhysicsBody::removeShapeByTag(int tag)
|
||||
{
|
||||
for (auto shape : _shapes)
|
||||
{
|
||||
if (shape->getTag() == tag)
|
||||
{
|
||||
removeShape(shape);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsBody::removeShape(PhysicsShape* shape)
|
||||
{
|
||||
auto it = std::find(_shapes.begin(), _shapes.end(), shape);
|
||||
|
||||
if (it != _shapes.end())
|
||||
{
|
||||
if (_world)
|
||||
{
|
||||
_world->removeShape(shape);
|
||||
}
|
||||
|
||||
_shapes.erase(it);
|
||||
|
||||
|
||||
// deduce the mass, area and angularDamping
|
||||
if (_mass != PHYSICS_INFINITY && shape->getMass() != PHYSICS_INFINITY)
|
||||
{
|
||||
if (_mass - shape->getMass() <= 0)
|
||||
{
|
||||
_mass = MASS_DEFAULT;
|
||||
_massDefault = true;
|
||||
}else
|
||||
{
|
||||
_mass = _mass = shape->getMass();
|
||||
}
|
||||
|
||||
_area -= shape->getArea();
|
||||
|
||||
if (_mass == PHYSICS_INFINITY)
|
||||
{
|
||||
_density = PHYSICS_INFINITY;
|
||||
}
|
||||
else if (_area > 0)
|
||||
{
|
||||
_density = _mass / _area;
|
||||
}
|
||||
else
|
||||
{
|
||||
_density = DENSITY_DEFAULT;
|
||||
}
|
||||
|
||||
if (_angularDamping - shape->getAngularDumping() > 0)
|
||||
{
|
||||
_angularDamping -= shape->getAngularDumping();
|
||||
}else
|
||||
{
|
||||
_angularDamping = ANGULARDAMPING_DEFAULT;
|
||||
_angularDampingDefault = true;
|
||||
}
|
||||
}
|
||||
|
||||
shape->release();
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsBody::removeAllShapes()
|
||||
{
|
||||
for (auto shape : _shapes)
|
||||
{
|
||||
if (_world)
|
||||
{
|
||||
_world->removeShape(shape);
|
||||
}
|
||||
|
||||
delete shape;
|
||||
}
|
||||
|
||||
_shapes.clear();
|
||||
}
|
||||
|
||||
void PhysicsBody::setEnable(bool enable)
|
||||
{
|
||||
if (_enable != enable)
|
||||
{
|
||||
_enable = enable;
|
||||
|
||||
if (_world)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
_world->addBody(this);
|
||||
}else
|
||||
{
|
||||
_world->removeBody(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Clonable* PhysicsBody::clone() const
|
||||
//{
|
||||
// PhysicsBody* body = new PhysicsBody();
|
||||
|
|
|
@ -30,22 +30,21 @@
|
|||
|
||||
#include "cocoa/CCObject.h"
|
||||
#include "cocoa/CCGeometry.h"
|
||||
|
||||
#include "CCPhysicsShape.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
NS_CC_BEGIN
|
||||
class Sprite;
|
||||
class PhysicsWorld;
|
||||
class PhysicsJoint;
|
||||
class PhysicsShape;
|
||||
class PhysicsShapeCircle;
|
||||
class PhysicsShapeBox;
|
||||
class PhysicsShapePolygon;
|
||||
class PhysicsShapeEdgeSegment;
|
||||
class PhysicsShapeEdgeBox;
|
||||
class PhysicsShapeEdgePolygon;
|
||||
class PhysicsShapeEdgeChain;
|
||||
|
||||
class PhysicsBodyInfo;
|
||||
|
||||
|
||||
const PhysicsMaterial PHYSICSBODY_MATERIAL_DEFAULT = {0.0f, 1.0f, 1.0f};
|
||||
|
||||
/**
|
||||
* A body affect by physics.
|
||||
* it can attach one or more shapes.
|
||||
|
@ -53,68 +52,39 @@ class PhysicsBodyInfo;
|
|||
class PhysicsBody : public Object//, public Clonable
|
||||
{
|
||||
public:
|
||||
static PhysicsBody* create();
|
||||
/**
|
||||
* @brief Create a body contains a circle shape.
|
||||
*/
|
||||
static PhysicsBody* createCircle(float radius);
|
||||
static PhysicsBody* createCircle(float radius, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT);
|
||||
/**
|
||||
* @brief Create a body contains a box shape.
|
||||
*/
|
||||
static PhysicsBody* createBox(Size size);
|
||||
static PhysicsBody* createBox(Size size, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT);
|
||||
/**
|
||||
* @brief Create a body contains a polygon shape.
|
||||
* points is an array of Point structs defining a convex hull with a clockwise winding.
|
||||
*/
|
||||
static PhysicsBody* createPolygon(Point* points, int count);
|
||||
static PhysicsBody* createPolygon(Point* points, int count, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT);
|
||||
|
||||
/**
|
||||
* @brief Create a body contains a EdgeSegment shape.
|
||||
*/
|
||||
static PhysicsBody* createEdgeSegment(Point a, Point b, float border = 1);
|
||||
static PhysicsBody* createEdgeSegment(Point a, Point b, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT, float border = 1);
|
||||
/**
|
||||
* @brief Create a body contains a EdgeBox shape.
|
||||
*/
|
||||
static PhysicsBody* createEdgeBox(Size size, float border = 1);
|
||||
static PhysicsBody* createEdgeBox(Size size, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT, float border = 1);
|
||||
/**
|
||||
* @brief Create a body contains a EdgePolygon shape.
|
||||
*/
|
||||
static PhysicsBody* createEdgePolygon(Point* points, int count, float border = 1);
|
||||
static PhysicsBody* createEdgePolygon(Point* points, int count, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT, float border = 1);
|
||||
/**
|
||||
* @brief Create a body contains a EdgeChain shape.
|
||||
*/
|
||||
static PhysicsBody* createEdgeChain(Point* points, int count, float border = 1);
|
||||
static PhysicsBody* createEdgeChain(Point* points, int count, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT, float border = 1);
|
||||
|
||||
/**
|
||||
* @brief Attach a circle shape with body
|
||||
*/
|
||||
virtual PhysicsShapeCircle* addCircle(float radius, Point offset = Point(0, 0));
|
||||
/**
|
||||
* @brief Attach a box shape with body
|
||||
*/
|
||||
virtual PhysicsShapeBox* addBox(Size size, Point offset = Point(0, 0));
|
||||
/**
|
||||
* @brief Attach a polygon shape with body
|
||||
*/
|
||||
virtual PhysicsShapePolygon* addPolygon(Point* points, int count, Point offset = Point(0, 0));
|
||||
|
||||
/**
|
||||
* @brief Attach a edge segment shape with body
|
||||
*/
|
||||
virtual PhysicsShapeEdgeSegment* addEdgeSegment(Point a, Point b, float border = 1);
|
||||
/**
|
||||
* @brief Attach a edge box shape with body
|
||||
*/
|
||||
virtual PhysicsShapeEdgeBox* addEdgeBox(Size size, float border = 1, Point offset = Point(0, 0));
|
||||
/**
|
||||
* @brief Attach a edge polygon shape with body
|
||||
* points is an array of Point structs defining a convex hull with a clockwise winding.
|
||||
*/
|
||||
virtual PhysicsShapeEdgePolygon* addEdgePolygon(Point* points, int count, float border = 1);
|
||||
/**
|
||||
* @brief Attach a edge chain shape with body
|
||||
* points is an array of Point structs defining a convex hull with a clockwise winding.
|
||||
*/
|
||||
virtual PhysicsShapeEdgeChain* addEdgeChain(Point* points, int count, float border = 1);
|
||||
virtual void addShape(PhysicsShape* shape);
|
||||
|
||||
/**
|
||||
* @brief Applies a immediate force to body.
|
||||
|
@ -137,6 +107,9 @@ public:
|
|||
*/
|
||||
virtual void applyTorque(float torque);
|
||||
|
||||
virtual void setVelocity(Point velocity);
|
||||
virtual Point getVelocity();
|
||||
|
||||
/*
|
||||
* @brief get the body shapes.
|
||||
*/
|
||||
|
@ -145,10 +118,12 @@ public:
|
|||
* @brief get the first body shapes.
|
||||
*/
|
||||
inline PhysicsShape* getShape() { return _shapes.size() >= 1 ? _shapes.front() : nullptr; }
|
||||
PhysicsShape* getShapeByTag(int tag);
|
||||
/*
|
||||
* @brief remove a shape from body
|
||||
*/
|
||||
void removeShape(PhysicsShape* shape);
|
||||
void removeShapeByTag(int tag);
|
||||
/*
|
||||
* @brief remove all shapes
|
||||
*/
|
||||
|
@ -215,14 +190,18 @@ public:
|
|||
|
||||
//virtual Clonable* clone() const override;
|
||||
|
||||
inline bool isEnable() { return _enable; }
|
||||
void setEnable(bool enable);
|
||||
|
||||
inline int getTag() { return _tag; }
|
||||
inline void setTag(int tag) { _tag = tag; }
|
||||
|
||||
protected:
|
||||
|
||||
bool init();
|
||||
bool initStatic();
|
||||
|
||||
virtual void setPosition(Point position);
|
||||
virtual void setRotation(float rotation);
|
||||
virtual void addShape(PhysicsShape* shape);
|
||||
|
||||
protected:
|
||||
PhysicsBody();
|
||||
|
@ -235,12 +214,14 @@ protected:
|
|||
PhysicsWorld* _world;
|
||||
PhysicsBodyInfo* _info;
|
||||
bool _dynamic;
|
||||
bool _enable;
|
||||
bool _massDefault;
|
||||
bool _angularDampingDefault;
|
||||
float _mass;
|
||||
float _area;
|
||||
float _density;
|
||||
float _angularDamping;
|
||||
int _tag;
|
||||
|
||||
int _categoryBitmask;
|
||||
int _contactTestBitmask;
|
||||
|
@ -249,7 +230,7 @@ protected:
|
|||
friend class PhysicsWorld;
|
||||
friend class PhysicsShape;
|
||||
friend class PhysicsJoint;
|
||||
friend class Sprite;
|
||||
friend class Node;
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -46,6 +46,8 @@ PhysicsJoint::PhysicsJoint()
|
|||
: _bodyA(nullptr)
|
||||
, _bodyB(nullptr)
|
||||
, _info(nullptr)
|
||||
, _enable(false)
|
||||
, _tag(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -79,6 +81,21 @@ bool PhysicsJoint::init(cocos2d::PhysicsBody *a, cocos2d::PhysicsBody *b)
|
|||
return false;
|
||||
}
|
||||
|
||||
void PhysicsJoint::setEnable(bool enable)
|
||||
{
|
||||
if (_enable != enable)
|
||||
{
|
||||
_enable = enable;
|
||||
|
||||
if (enable)
|
||||
{
|
||||
|
||||
}else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PhysicsJointPin::PhysicsJointPin()
|
||||
{
|
||||
|
|
|
@ -49,6 +49,10 @@ protected:
|
|||
public:
|
||||
PhysicsBody* getBodyA() { return _bodyA; }
|
||||
PhysicsBody* getBodyB() { return _bodyB; }
|
||||
inline int getTag() { return _tag; }
|
||||
inline void setTag(int tag) { _tag = tag; }
|
||||
inline bool isEnable() { return _enable; }
|
||||
void setEnable(bool enable);
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* a, PhysicsBody* b);
|
||||
|
@ -62,8 +66,11 @@ protected:
|
|||
PhysicsBody* _bodyA;
|
||||
PhysicsBody* _bodyB;
|
||||
PhysicsJointInfo* _info;
|
||||
bool _enable;
|
||||
int _tag;
|
||||
|
||||
friend class PhysicsBody;
|
||||
friend class PhysicsWorld;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -43,4 +43,9 @@
|
|||
#define CC_USE_PHYSICS
|
||||
#endif
|
||||
|
||||
namespace cocos2d
|
||||
{
|
||||
extern const float PHYSICS_INFINITY;
|
||||
}
|
||||
|
||||
#endif // __CCPHYSICS_SETTING_H__
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#endif
|
||||
|
||||
#include "CCPhysicsBody.h"
|
||||
#include "CCPhysicsWorld.h"
|
||||
|
||||
#include "chipmunk/CCPhysicsBodyInfo.h"
|
||||
#include "Box2D/CCPhysicsBodyInfo.h"
|
||||
|
@ -45,6 +46,11 @@ PhysicsShape::PhysicsShape()
|
|||
: _body(nullptr)
|
||||
, _info(nullptr)
|
||||
, _type(Type::UNKNOWN)
|
||||
, _area(0)
|
||||
, _mass(0)
|
||||
, _angularDamping(0)
|
||||
, _tag(0)
|
||||
, _enable(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -54,20 +60,41 @@ PhysicsShape::~PhysicsShape()
|
|||
CC_SAFE_DELETE(_info);
|
||||
}
|
||||
|
||||
bool PhysicsShape::init(PhysicsBody* body, Type type)
|
||||
bool PhysicsShape::init(Type type, PhysicsMaterial material/* = MaterialDefault*/)
|
||||
{
|
||||
if (body == nullptr) return false;
|
||||
|
||||
_body = body;
|
||||
|
||||
_info = new PhysicsShapeInfo(this);
|
||||
if (_info == nullptr) return false;
|
||||
|
||||
_type = type;
|
||||
_material = material;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PhysicsShape::setMass(float mass)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PhysicsShape::setEnable(bool enable)
|
||||
{
|
||||
if (_enable != enable)
|
||||
{
|
||||
_enable = enable;
|
||||
|
||||
if (_body->getWorld() && _body->isEnable())
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
_body->getWorld()->addShape(this);
|
||||
}else
|
||||
{
|
||||
_body->getWorld()->removeShape(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsShape::addToBody()
|
||||
{
|
||||
if(_body != nullptr) _body->addShape(this);
|
||||
|
@ -75,7 +102,13 @@ void PhysicsShape::addToBody()
|
|||
|
||||
PhysicsBodyInfo* PhysicsShape::bodyInfo() const
|
||||
{
|
||||
return _body->_info;
|
||||
if (_body != nullptr)
|
||||
{
|
||||
return _body->_info;
|
||||
}else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PhysicsShapeCircle::PhysicsShapeCircle()
|
||||
|
@ -150,12 +183,38 @@ PhysicsShapeEdgeSegment::~PhysicsShapeEdgeSegment()
|
|||
|
||||
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
|
||||
|
||||
void PhysicsShape::initEnd()
|
||||
{
|
||||
for (auto shape : _info->shapes)
|
||||
{
|
||||
cpShapeSetElasticity(shape, _material.elasticity);
|
||||
cpShapeSetFriction(shape, _material.friction);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsShape::setElasticity(float elasticity)
|
||||
{
|
||||
for (cpShape* shape : _info->shapes)
|
||||
{
|
||||
cpShapeSetElasticity(shape, PhysicsHelper::float2cpfloat(elasticity));
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsShape::setFriction(float friction)
|
||||
{
|
||||
for (cpShape* shape : _info->shapes)
|
||||
{
|
||||
cpShapeSetFriction(shape, PhysicsHelper::float2cpfloat(friction));
|
||||
}
|
||||
}
|
||||
|
||||
// PhysicsShapeCircle
|
||||
PhysicsShapeCircle* PhysicsShapeCircle::create(PhysicsBody* body, float radius, Point offset/* = Point(0, 0)*/)
|
||||
PhysicsShapeCircle* PhysicsShapeCircle::create(float radius, PhysicsMaterial material/* = MaterialDefault*/, Point offset/* = Point(0, 0)*/)
|
||||
{
|
||||
PhysicsShapeCircle* shape = new PhysicsShapeCircle();
|
||||
if (shape && shape->init(body, radius, offset))
|
||||
if (shape && shape->init(radius, material, offset))
|
||||
{
|
||||
shape->autorelease();
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
@ -163,19 +222,23 @@ PhysicsShapeCircle* PhysicsShapeCircle::create(PhysicsBody* body, float radius,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsShapeCircle::init(PhysicsBody* body, float radius, Point offset /*= Point(0, 0)*/)
|
||||
bool PhysicsShapeCircle::init(float radius, PhysicsMaterial material/* = MaterialDefault*/, Point offset /*= Point(0, 0)*/)
|
||||
{
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsShape::init(body, Type::CIRCLE));
|
||||
CC_BREAK_IF(!PhysicsShape::init(Type::CIRCLE, material));
|
||||
|
||||
cpShape* shape = cpCircleShapeNew(bodyInfo()->body, radius, PhysicsHelper::point2cpv(offset));
|
||||
cpShape* shape = cpCircleShapeNew(_info->shareBody, radius, PhysicsHelper::point2cpv(offset));
|
||||
|
||||
CC_BREAK_IF(shape == nullptr);
|
||||
|
||||
_info->add(shape);
|
||||
addToBody();
|
||||
_area = PhysicsHelper::cpfloat2float(cpAreaForCircle(0, radius));
|
||||
_mass = _material.density == PHYSICS_INFINITY ? PHYSICS_INFINITY : _material.density * _area;
|
||||
_angularDamping = _mass == PHYSICS_INFINITY ? PHYSICS_INFINITY : cpMomentForCircle(_mass, 0, radius, PhysicsHelper::point2cpv(offset));
|
||||
|
||||
_info->add(shape);
|
||||
|
||||
initEnd();
|
||||
return true;
|
||||
} while (false);
|
||||
|
||||
|
@ -183,11 +246,12 @@ bool PhysicsShapeCircle::init(PhysicsBody* body, float radius, Point offset /*=
|
|||
}
|
||||
|
||||
// PhysicsShapeEdgeSegment
|
||||
PhysicsShapeEdgeSegment* PhysicsShapeEdgeSegment::create(PhysicsBody* body, Point a, Point b, float border/* = 1*/)
|
||||
PhysicsShapeEdgeSegment* PhysicsShapeEdgeSegment::create(Point a, Point b, PhysicsMaterial material/* = MaterialDefault*/, float border/* = 1*/)
|
||||
{
|
||||
PhysicsShapeEdgeSegment* shape = new PhysicsShapeEdgeSegment();
|
||||
if (shape && shape->init(body, a, b, border))
|
||||
if (shape && shape->init(a, b, material, border))
|
||||
{
|
||||
shape->autorelease();
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
@ -195,21 +259,25 @@ PhysicsShapeEdgeSegment* PhysicsShapeEdgeSegment::create(PhysicsBody* body, Poin
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsShapeEdgeSegment::init(PhysicsBody* body, Point a, Point b, float border/* = 1*/)
|
||||
bool PhysicsShapeEdgeSegment::init(Point a, Point b, PhysicsMaterial material/* = MaterialDefault*/, float border/* = 1*/)
|
||||
{
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsShape::init(body, Type::EDGESEGMENT));
|
||||
CC_BREAK_IF(!PhysicsShape::init(Type::EDGESEGMENT, material));
|
||||
|
||||
cpShape* shape = cpSegmentShapeNew(bodyInfo()->body,
|
||||
cpShape* shape = cpSegmentShapeNew(_info->shareBody,
|
||||
PhysicsHelper::point2cpv(a),
|
||||
PhysicsHelper::point2cpv(b),
|
||||
PhysicsHelper::float2cpfloat(border));
|
||||
|
||||
CC_BREAK_IF(shape == nullptr);
|
||||
|
||||
_mass = PHYSICS_INFINITY;
|
||||
_angularDamping = PHYSICS_INFINITY;
|
||||
|
||||
_info->add(shape);
|
||||
addToBody();
|
||||
|
||||
initEnd();
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -218,11 +286,12 @@ bool PhysicsShapeEdgeSegment::init(PhysicsBody* body, Point a, Point b, float bo
|
|||
}
|
||||
|
||||
// PhysicsShapeBox
|
||||
PhysicsShapeBox* PhysicsShapeBox::create(PhysicsBody* body, Size size, Point offset/* = Point(0, 0)*/)
|
||||
PhysicsShapeBox* PhysicsShapeBox::create(Size size, PhysicsMaterial material/* = MaterialDefault*/, Point offset/* = Point(0, 0)*/)
|
||||
{
|
||||
PhysicsShapeBox* shape = new PhysicsShapeBox();
|
||||
if (shape && shape->init(body, size, offset))
|
||||
if (shape && shape->init(size, material, offset))
|
||||
{
|
||||
shape->autorelease();
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
@ -230,18 +299,23 @@ PhysicsShapeBox* PhysicsShapeBox::create(PhysicsBody* body, Size size, Point off
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsShapeBox::init(PhysicsBody* body, Size size, Point offset /*= Point(0, 0)*/)
|
||||
bool PhysicsShapeBox::init(Size size, PhysicsMaterial material/* = MaterialDefault*/, Point offset /*= Point(0, 0)*/)
|
||||
{
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsShape::init(body, Type::BOX));
|
||||
CC_BREAK_IF(!PhysicsShape::init(Type::BOX, material));
|
||||
|
||||
cpShape* shape = cpBoxShapeNew(bodyInfo()->body, PhysicsHelper::float2cpfloat(size.width), PhysicsHelper::float2cpfloat(size.height));
|
||||
cpShape* shape = cpBoxShapeNew(_info->shareBody, PhysicsHelper::float2cpfloat(size.width), PhysicsHelper::float2cpfloat(size.height));
|
||||
|
||||
CC_BREAK_IF(shape == nullptr);
|
||||
|
||||
_area = PhysicsHelper::cpfloat2float(cpAreaForPoly(4, ((cpPolyShape*)shape)->verts));
|
||||
_mass = _material.density == PHYSICS_INFINITY ? PHYSICS_INFINITY : _material.density * _area;
|
||||
_angularDamping = _mass == PHYSICS_INFINITY ? PHYSICS_INFINITY : cpMomentForBox(_mass, PhysicsHelper::float2cpfloat(size.width), PhysicsHelper::float2cpfloat(size.height));
|
||||
|
||||
_info->add(shape);
|
||||
addToBody();
|
||||
|
||||
initEnd();
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -250,11 +324,12 @@ bool PhysicsShapeBox::init(PhysicsBody* body, Size size, Point offset /*= Point(
|
|||
}
|
||||
|
||||
// PhysicsShapeCircle
|
||||
PhysicsShapePolygon* PhysicsShapePolygon::create(PhysicsBody* body, Point* points, int count, Point offset/* = Point(0, 0)*/)
|
||||
PhysicsShapePolygon* PhysicsShapePolygon::create(Point* points, int count, PhysicsMaterial material/* = MaterialDefault*/, Point offset/* = Point(0, 0)*/)
|
||||
{
|
||||
PhysicsShapePolygon* shape = new PhysicsShapePolygon();
|
||||
if (shape && shape->init(body, points, count, offset))
|
||||
if (shape && shape->init(points, count, material, offset))
|
||||
{
|
||||
shape->autorelease();
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
@ -262,20 +337,26 @@ PhysicsShapePolygon* PhysicsShapePolygon::create(PhysicsBody* body, Point* point
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsShapePolygon::init(PhysicsBody* body, Point* points, int count, Point offset /*= Point(0, 0)*/)
|
||||
bool PhysicsShapePolygon::init(Point* points, int count, PhysicsMaterial material/* = MaterialDefault*/, Point offset /*= Point(0, 0)*/)
|
||||
{
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsShape::init(body, Type::POLYGEN));
|
||||
CC_BREAK_IF(!PhysicsShape::init(Type::POLYGEN, material));
|
||||
|
||||
cpVect* vecs = new cpVect[count];
|
||||
PhysicsHelper::points2cpvs(points, vecs, count);
|
||||
cpShape* shape = cpPolyShapeNew(bodyInfo()->body, count, vecs, PhysicsHelper::point2cpv(offset));
|
||||
cpShape* shape = cpPolyShapeNew(_info->shareBody, count, vecs, PhysicsHelper::point2cpv(offset));
|
||||
CC_SAFE_DELETE(vecs);
|
||||
|
||||
CC_BREAK_IF(shape == nullptr);
|
||||
|
||||
_area = PhysicsHelper::cpfloat2float(cpAreaForPoly(((cpPolyShape*)shape)->numVerts, ((cpPolyShape*)shape)->verts));
|
||||
_mass = _material.density == PHYSICS_INFINITY ? PHYSICS_INFINITY : _material.density * _area;
|
||||
_angularDamping = _mass == PHYSICS_INFINITY ? PHYSICS_INFINITY : cpMomentForPoly(_mass, ((cpPolyShape*)shape)->numVerts, ((cpPolyShape*)shape)->verts, PhysicsHelper::point2cpv(offset));
|
||||
|
||||
_info->add(shape);
|
||||
addToBody();
|
||||
|
||||
initEnd();
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -284,11 +365,12 @@ bool PhysicsShapePolygon::init(PhysicsBody* body, Point* points, int count, Poin
|
|||
}
|
||||
|
||||
// PhysicsShapeEdgeBox
|
||||
PhysicsShapeEdgeBox* PhysicsShapeEdgeBox::create(PhysicsBody* body, Size size, float border/* = 1*/, Point offset/* = Point(0, 0)*/)
|
||||
PhysicsShapeEdgeBox* PhysicsShapeEdgeBox::create(Size size, PhysicsMaterial material/* = MaterialDefault*/, float border/* = 1*/, Point offset/* = Point(0, 0)*/)
|
||||
{
|
||||
PhysicsShapeEdgeBox* shape = new PhysicsShapeEdgeBox();
|
||||
if (shape && shape->init(body, size, border, offset))
|
||||
if (shape && shape->init(size, material, border, offset))
|
||||
{
|
||||
shape->autorelease();
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
@ -296,33 +378,32 @@ PhysicsShapeEdgeBox* PhysicsShapeEdgeBox::create(PhysicsBody* body, Size size, f
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsShapeEdgeBox::init(PhysicsBody* body, Size size, float border/* = 1*/, Point offset/*= Point(0, 0)*/)
|
||||
bool PhysicsShapeEdgeBox::init(Size size, PhysicsMaterial material/* = MaterialDefault*/, float border/* = 1*/, Point offset/*= Point(0, 0)*/)
|
||||
{
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsShape::init(body, Type::EDGEBOX));
|
||||
|
||||
Point bodyPos = body->getPosition();
|
||||
CC_BREAK_IF(!PhysicsShape::init(Type::EDGEBOX, material));
|
||||
|
||||
cpVect vec[4] = {};
|
||||
vec[0] = PhysicsHelper::point2cpv(Point(bodyPos.x-size.width/2+offset.x, bodyPos.y-size.height/2+offset.y));
|
||||
vec[1] = PhysicsHelper::point2cpv(Point(bodyPos.x+size.width/2+offset.x, bodyPos.y-size.height/2+offset.y));
|
||||
vec[2] = PhysicsHelper::point2cpv(Point(bodyPos.x+size.width/2+offset.x, bodyPos.y+size.height/2+offset.y));
|
||||
vec[3] = PhysicsHelper::point2cpv(Point(bodyPos.x-size.width/2+offset.x, bodyPos.y+size.height/2+offset.y));
|
||||
vec[0] = PhysicsHelper::point2cpv(Point(-size.width/2+offset.x, -size.height/2+offset.y));
|
||||
vec[1] = PhysicsHelper::point2cpv(Point(+size.width/2+offset.x, -size.height/2+offset.y));
|
||||
vec[2] = PhysicsHelper::point2cpv(Point(+size.width/2+offset.x, +size.height/2+offset.y));
|
||||
vec[3] = PhysicsHelper::point2cpv(Point(-size.width/2+offset.x, +size.height/2+offset.y));
|
||||
|
||||
int i = 0;
|
||||
for (; i < 4; ++i)
|
||||
{
|
||||
cpShape* shape = cpSegmentShapeNew(bodyInfo()->body, vec[i], vec[(i+1)%4],
|
||||
cpShape* shape = cpSegmentShapeNew(_info->shareBody, vec[i], vec[(i+1)%4],
|
||||
PhysicsHelper::float2cpfloat(border));
|
||||
CC_BREAK_IF(shape == nullptr);
|
||||
cpShapeSetElasticity(shape, 1.0f);
|
||||
cpShapeSetFriction(shape, 1.0f);
|
||||
_info->add(shape);
|
||||
}
|
||||
CC_BREAK_IF(i < 4);
|
||||
|
||||
addToBody();
|
||||
_mass = PHYSICS_INFINITY;
|
||||
_angularDamping = PHYSICS_INFINITY;
|
||||
|
||||
initEnd();
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -331,11 +412,12 @@ bool PhysicsShapeEdgeBox::init(PhysicsBody* body, Size size, float border/* = 1*
|
|||
}
|
||||
|
||||
// PhysicsShapeEdgeBox
|
||||
PhysicsShapeEdgePolygon* PhysicsShapeEdgePolygon::create(PhysicsBody* body, Point* points, int count, float border/* = 1*/)
|
||||
PhysicsShapeEdgePolygon* PhysicsShapeEdgePolygon::create(Point* points, int count, PhysicsMaterial material/* = MaterialDefault*/, float border/* = 1*/)
|
||||
{
|
||||
PhysicsShapeEdgePolygon* shape = new PhysicsShapeEdgePolygon();
|
||||
if (shape && shape->init(body, points, count, border))
|
||||
{
|
||||
if (shape && shape->init(points, count, material, border))
|
||||
{
|
||||
shape->autorelease();
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
@ -343,12 +425,12 @@ PhysicsShapeEdgePolygon* PhysicsShapeEdgePolygon::create(PhysicsBody* body, Poin
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsShapeEdgePolygon::init(PhysicsBody* body, Point* points, int count, float border/* = 1*/)
|
||||
bool PhysicsShapeEdgePolygon::init(Point* points, int count, PhysicsMaterial material/* = MaterialDefault*/, float border/* = 1*/)
|
||||
{
|
||||
cpVect* vec = nullptr;
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsShape::init(body, Type::EDGEPOLYGEN));
|
||||
CC_BREAK_IF(!PhysicsShape::init(Type::EDGEPOLYGEN, material));
|
||||
|
||||
vec = new cpVect[count];
|
||||
PhysicsHelper::points2cpvs(points, vec, count);
|
||||
|
@ -356,18 +438,22 @@ bool PhysicsShapeEdgePolygon::init(PhysicsBody* body, Point* points, int count,
|
|||
int i = 0;
|
||||
for (; i < count; ++i)
|
||||
{
|
||||
cpShape* shape = cpSegmentShapeNew(bodyInfo()->body, vec[i], vec[(i+1)%count],
|
||||
cpShape* shape = cpSegmentShapeNew(_info->shareBody, vec[i], vec[(i+1)%count],
|
||||
PhysicsHelper::float2cpfloat(border));
|
||||
CC_BREAK_IF(shape == nullptr);
|
||||
cpShapeSetElasticity(shape, 1.0f);
|
||||
cpShapeSetFriction(shape, 1.0f);
|
||||
_info->add(shape);
|
||||
}
|
||||
CC_SAFE_DELETE(vec);
|
||||
|
||||
CC_BREAK_IF(i < count);
|
||||
|
||||
addToBody();
|
||||
_mass = PHYSICS_INFINITY;
|
||||
_angularDamping = PHYSICS_INFINITY;
|
||||
|
||||
initEnd();
|
||||
|
||||
if (vec != nullptr) delete[] vec;
|
||||
return true;
|
||||
} while (false);
|
||||
|
||||
|
@ -377,11 +463,12 @@ bool PhysicsShapeEdgePolygon::init(PhysicsBody* body, Point* points, int count,
|
|||
}
|
||||
|
||||
// PhysicsShapeEdgeChain
|
||||
PhysicsShapeEdgeChain* PhysicsShapeEdgeChain::create(PhysicsBody* body, Point* points, int count, float border/* = 1*/)
|
||||
PhysicsShapeEdgeChain* PhysicsShapeEdgeChain::create(Point* points, int count, PhysicsMaterial material/* = MaterialDefault*/, float border/* = 1*/)
|
||||
{
|
||||
PhysicsShapeEdgeChain* shape = new PhysicsShapeEdgeChain();
|
||||
if (shape && shape->init(body, points, count, border))
|
||||
if (shape && shape->init(points, count, material, border))
|
||||
{
|
||||
shape->autorelease();
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
@ -389,12 +476,12 @@ PhysicsShapeEdgeChain* PhysicsShapeEdgeChain::create(PhysicsBody* body, Point* p
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsShapeEdgeChain::init(PhysicsBody* body, Point* points, int count, float border/* = 1*/)
|
||||
bool PhysicsShapeEdgeChain::init(Point* points, int count, PhysicsMaterial material/* = MaterialDefault*/, float border/* = 1*/)
|
||||
{
|
||||
cpVect* vec = nullptr;
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsShape::init(body, Type::EDGECHAIN));
|
||||
CC_BREAK_IF(!PhysicsShape::init(Type::EDGECHAIN, material));
|
||||
|
||||
vec = new cpVect[count];
|
||||
PhysicsHelper::points2cpvs(points, vec, count);
|
||||
|
@ -402,18 +489,21 @@ bool PhysicsShapeEdgeChain::init(PhysicsBody* body, Point* points, int count, fl
|
|||
int i = 0;
|
||||
for (; i < count - 1; ++i)
|
||||
{
|
||||
cpShape* shape = cpSegmentShapeNew(bodyInfo()->body, vec[i], vec[i+1],
|
||||
cpShape* shape = cpSegmentShapeNew(_info->shareBody, vec[i], vec[i+1],
|
||||
PhysicsHelper::float2cpfloat(border));
|
||||
CC_BREAK_IF(shape == nullptr);
|
||||
cpShapeSetElasticity(shape, 1.0f);
|
||||
cpShapeSetFriction(shape, 1.0f);
|
||||
_info->add(shape);
|
||||
}
|
||||
if (vec != nullptr) delete[] vec;
|
||||
CC_BREAK_IF(i < count);
|
||||
|
||||
addToBody();
|
||||
_mass = PHYSICS_INFINITY;
|
||||
_angularDamping = PHYSICS_INFINITY;
|
||||
|
||||
initEnd();
|
||||
|
||||
if (vec != nullptr) delete[] vec;
|
||||
return true;
|
||||
} while (false);
|
||||
|
||||
|
@ -422,7 +512,6 @@ bool PhysicsShapeEdgeChain::init(PhysicsBody* body, Point* points, int count, fl
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
#elif (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,7 +37,27 @@ class PhysicsShapeInfo;
|
|||
class PhysicsBody;
|
||||
class PhysicsBodyInfo;
|
||||
|
||||
/**
|
||||
|
||||
typedef struct PhysicsMaterial
|
||||
{
|
||||
float density;
|
||||
float elasticity;
|
||||
float friction;
|
||||
|
||||
PhysicsMaterial()
|
||||
: density(0.0f)
|
||||
, elasticity(0.0f)
|
||||
, friction(0.0f){}
|
||||
|
||||
PhysicsMaterial(float density, float elasticity, float friction)
|
||||
: density(density)
|
||||
, elasticity(elasticity)
|
||||
, friction(friction){}
|
||||
}PhysicsMaterial;
|
||||
|
||||
const PhysicsMaterial PHYSICSSHAPE_MATERIAL_DEFAULT = {0.0f, 1.0f, 1.0f};
|
||||
|
||||
/**
|
||||
* @brief A shape for body. You do not create PhysicsWorld objects directly, instead, you can view PhysicsBody to see how to create it.
|
||||
*/
|
||||
class PhysicsShape : public Object
|
||||
|
@ -58,16 +78,32 @@ public:
|
|||
public:
|
||||
inline PhysicsBody* getBody(){ return _body; }
|
||||
inline Type getType() { return _type; }
|
||||
inline float getArea() { return _area; }
|
||||
inline float getAngularDumping() { return _angularDamping; }
|
||||
void setAngularDumping(float angularDumping);
|
||||
inline void setTag(int tag) { _tag = tag; }
|
||||
inline int getTag() { return _tag; }
|
||||
void setEnable(bool enable);
|
||||
inline bool isEnable() { return _enable; }
|
||||
void addToBody();
|
||||
|
||||
inline float getMass() { return _mass; }
|
||||
void setMass(float mass);
|
||||
inline float getDensity() { return _material.density; }
|
||||
void setDensity(float density);
|
||||
void setElasticity(float elasticity);
|
||||
void setFriction(float friction);
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* body, Type type);
|
||||
bool init(Type type, PhysicsMaterial material);
|
||||
void initEnd();
|
||||
|
||||
/**
|
||||
* @brief PhysicsShape is PhysicsBody's friend class, but all the subclasses isn't. so this method is use for subclasses to catch the bodyInfo from PhysicsBody.
|
||||
*/
|
||||
PhysicsBodyInfo* bodyInfo() const;
|
||||
|
||||
void addToBody();
|
||||
inline void setBody(PhysicsBody* body) { _body = body; }
|
||||
|
||||
protected:
|
||||
PhysicsShape();
|
||||
|
@ -77,6 +113,12 @@ protected:
|
|||
PhysicsBody* _body;
|
||||
PhysicsShapeInfo* _info;
|
||||
Type _type;
|
||||
float _area;
|
||||
float _mass;
|
||||
float _angularDamping;
|
||||
PhysicsMaterial _material;
|
||||
int _tag;
|
||||
bool _enable;
|
||||
|
||||
friend class PhysicsWorld;
|
||||
friend class PhysicsBody;
|
||||
|
@ -85,9 +127,11 @@ protected:
|
|||
/** A circle shape */
|
||||
class PhysicsShapeCircle : public PhysicsShape
|
||||
{
|
||||
public:
|
||||
static PhysicsShapeCircle* create(float radius, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT, Point offset = Point(0, 0));
|
||||
|
||||
protected:
|
||||
static PhysicsShapeCircle* create(PhysicsBody* body, float radius, Point offset = Point(0, 0));
|
||||
bool init(PhysicsBody* body, float radius, Point offset = Point(0, 0));
|
||||
bool init(float radius, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT, Point offset = Point(0, 0));
|
||||
|
||||
protected:
|
||||
PhysicsShapeCircle();
|
||||
|
@ -99,9 +143,11 @@ protected:
|
|||
/** A box shape */
|
||||
class PhysicsShapeBox : public PhysicsShape
|
||||
{
|
||||
public:
|
||||
static PhysicsShapeBox* create(Size size, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT, Point offset = Point(0, 0));
|
||||
|
||||
protected:
|
||||
static PhysicsShapeBox* create(PhysicsBody* body, Size size, Point offset = Point(0, 0));
|
||||
bool init(PhysicsBody* body, Size size, Point offset = Point(0, 0));
|
||||
bool init(Size size, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT, Point offset = Point(0, 0));
|
||||
|
||||
protected:
|
||||
PhysicsShapeBox();
|
||||
|
@ -113,9 +159,11 @@ protected:
|
|||
/** A polygon shape */
|
||||
class PhysicsShapePolygon : public PhysicsShape
|
||||
{
|
||||
public:
|
||||
static PhysicsShapePolygon* create(Point* points, int count, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT, Point offset = Point(0, 0));
|
||||
|
||||
protected:
|
||||
static PhysicsShapePolygon* create(PhysicsBody* body, Point* points, int count, Point offset = Point(0, 0));
|
||||
bool init(PhysicsBody* body, Point* points, int count, Point offset = Point(0, 0));
|
||||
bool init(Point* points, int count, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT, Point offset = Point(0, 0));
|
||||
|
||||
protected:
|
||||
PhysicsShapePolygon();
|
||||
|
@ -127,9 +175,11 @@ protected:
|
|||
/** A segment shape */
|
||||
class PhysicsShapeEdgeSegment : public PhysicsShape
|
||||
{
|
||||
public:
|
||||
static PhysicsShapeEdgeSegment* create(Point a, Point b, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT, float border = 1);
|
||||
|
||||
protected:
|
||||
static PhysicsShapeEdgeSegment* create(PhysicsBody* body, Point a, Point b, float border = 1);
|
||||
bool init(PhysicsBody* body, Point a, Point b, float border = 1);
|
||||
bool init(Point a, Point b, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT, float border = 1);
|
||||
|
||||
protected:
|
||||
PhysicsShapeEdgeSegment();
|
||||
|
@ -142,10 +192,10 @@ protected:
|
|||
class PhysicsShapeEdgeBox : public PhysicsShape
|
||||
{
|
||||
public:
|
||||
static PhysicsShapeEdgeBox* create(PhysicsBody* body, Size size, float border = 0, Point offset = Point(0, 0));
|
||||
static PhysicsShapeEdgeBox* create(Size size, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT, float border = 0, Point offset = Point(0, 0));
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* body, Size size, float border = 1, Point offset = Point(0, 0));
|
||||
bool init(Size size, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT, float border = 1, Point offset = Point(0, 0));
|
||||
|
||||
protected:
|
||||
PhysicsShapeEdgeBox();
|
||||
|
@ -158,10 +208,10 @@ protected:
|
|||
class PhysicsShapeEdgePolygon : public PhysicsShape
|
||||
{
|
||||
public:
|
||||
static PhysicsShapeEdgePolygon* create(PhysicsBody* body, Point* points, int count, float border = 1);
|
||||
static PhysicsShapeEdgePolygon* create(Point* points, int count, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT, float border = 1);
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* body, Point* points, int count, float border = 1);
|
||||
bool init(Point* points, int count, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT, float border = 1);
|
||||
|
||||
protected:
|
||||
PhysicsShapeEdgePolygon();
|
||||
|
@ -174,10 +224,10 @@ protected:
|
|||
class PhysicsShapeEdgeChain : public PhysicsShape
|
||||
{
|
||||
public:
|
||||
static PhysicsShapeEdgeChain* create(PhysicsBody* body, Point* points, int count, float border = 1);
|
||||
static PhysicsShapeEdgeChain* create(Point* points, int count, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT, float border = 1);
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* body, Point* points, int count, float border = 1);
|
||||
bool init(Point* points, int count, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT, float border = 1);
|
||||
|
||||
protected:
|
||||
PhysicsShapeEdgeChain();
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "CCPhysicsBody.h"
|
||||
#include "CCPhysicsShape.h"
|
||||
#include "CCPhysicsContact.h"
|
||||
#include "CCPhysicsJoint.h"
|
||||
|
||||
#include "chipmunk/CCPhysicsWorldInfo.h"
|
||||
#include "Box2D/CCPhysicsWorldInfo.h"
|
||||
|
@ -43,6 +44,8 @@
|
|||
#include "Box2D/CCPhysicsShapeInfo.h"
|
||||
#include "chipmunk/CCPhysicsContactInfo.h"
|
||||
#include "Box2D/CCPhysicsContactInfo.h"
|
||||
#include "chipmunk/CCPhysicsJointInfo.h"
|
||||
#include "Box2D/CCPhysicsJointInfo.h"
|
||||
#include "chipmunk/CCPhysicsHelper.h"
|
||||
|
||||
#include "draw_nodes/CCDrawNode.h"
|
||||
|
@ -50,10 +53,14 @@
|
|||
#include "layers_scenes_transitions_nodes/CCScene.h"
|
||||
#include "CCDirector.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
|
||||
|
||||
const float PHYSICS_INFINITY = INFINITY;
|
||||
|
||||
int PhysicsWorld::collisionBeginCallbackFunc(cpArbiter *arb, struct cpSpace *space, void *data)
|
||||
{
|
||||
PhysicsWorld* world = static_cast<PhysicsWorld*>(data);
|
||||
|
@ -110,34 +117,69 @@ bool PhysicsWorld::init()
|
|||
return true;
|
||||
}
|
||||
|
||||
void PhysicsWorld::addJoint(PhysicsJoint* joint)
|
||||
{
|
||||
auto it = std::find(_joints.begin(), _joints.end(), joint);
|
||||
|
||||
if (it == _joints.end())
|
||||
{
|
||||
_joints.push_back(joint);
|
||||
|
||||
if (!cpSpaceContainsConstraint(_info->space, joint->_info->joint))
|
||||
{
|
||||
cpSpaceAddConstraint(_info->space, joint->_info->joint);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeJoint(PhysicsJoint* joint)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeAllJoints()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PhysicsWorld::addShape(PhysicsShape* shape)
|
||||
{
|
||||
for (auto it = shape->_info->shapes.begin(); it != shape->_info->shapes.end(); it++)
|
||||
for (auto cps : shape->_info->shapes)
|
||||
{
|
||||
if (cpSpaceContainsShape(_info->space, cps))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cpBodyIsStatic(shape->getBody()->_info->body))
|
||||
{
|
||||
cpSpaceAddStaticShape(_info->space, *it);
|
||||
cpSpaceAddStaticShape(_info->space, cps);
|
||||
}else
|
||||
{
|
||||
cpSpaceAddShape(_info->space, *it);
|
||||
cpSpaceAddShape(_info->space, cps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::addChild(PhysicsBody* body)
|
||||
void PhysicsWorld::addBody(PhysicsBody* body)
|
||||
{
|
||||
auto shapes = body->getShapes();
|
||||
|
||||
// add body to space
|
||||
if (body->isDynamic())
|
||||
if (body->isEnable())
|
||||
{
|
||||
cpSpaceAddBody(_info->space, body->_info->body);
|
||||
}
|
||||
|
||||
// add shapes to space
|
||||
for (auto it = shapes.begin(); it != shapes.end(); it++)
|
||||
{
|
||||
addShape(*it);
|
||||
// add body to space
|
||||
if (body->isDynamic())
|
||||
{
|
||||
cpSpaceAddBody(_info->space, body->_info->body);
|
||||
}
|
||||
|
||||
// add shapes to space
|
||||
for (auto shape : body->getShapes())
|
||||
{
|
||||
if (shape->isEnable())
|
||||
{
|
||||
addShape(shape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_bodys == nullptr)
|
||||
|
@ -150,6 +192,54 @@ void PhysicsWorld::addChild(PhysicsBody* body)
|
|||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeBody(PhysicsBody* body)
|
||||
{
|
||||
for (auto shape : body->getShapes())
|
||||
{
|
||||
for (auto cps : shape->_info->shapes)
|
||||
{
|
||||
if (cpSpaceContainsShape(_info->space, cps))
|
||||
{
|
||||
cpSpaceRemoveShape(_info->space, cps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cpSpaceContainsBody(_info->space, body->_info->body))
|
||||
{
|
||||
cpSpaceRemoveBody(_info->space, body->_info->body);
|
||||
}
|
||||
|
||||
if (_bodys != nullptr)
|
||||
{
|
||||
_bodys->removeObject(body);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeBodyByTag(int tag)
|
||||
{
|
||||
for (Object* obj : *_bodys)
|
||||
{
|
||||
PhysicsBody* body = dynamic_cast<PhysicsBody*>(obj);
|
||||
if (body->getTag() == tag)
|
||||
{
|
||||
removeBody(body);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeShape(PhysicsShape* shape)
|
||||
{
|
||||
for (auto cps : shape->_info->shapes)
|
||||
{
|
||||
if (cpSpaceContainsShape(_info->space, cps))
|
||||
{
|
||||
cpSpaceRemoveShape(_info->space, cps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::update(float delta)
|
||||
{
|
||||
cpSpaceStep(_info->space, delta);
|
||||
|
@ -171,17 +261,16 @@ void PhysicsWorld::debugDraw()
|
|||
if (_debugDraw && _bodys != nullptr)
|
||||
{
|
||||
_drawNode= DrawNode::create();
|
||||
|
||||
Object* child = nullptr;
|
||||
CCARRAY_FOREACH(_bodys, child)
|
||||
|
||||
for (Object* obj : *_bodys)
|
||||
{
|
||||
PhysicsBody* body = dynamic_cast<PhysicsBody*>(child);
|
||||
PhysicsBody* body = dynamic_cast<PhysicsBody*>(obj);
|
||||
|
||||
std::vector<PhysicsShape*> shapes = body->getShapes();
|
||||
|
||||
for (auto it = shapes.begin(); it != shapes.end(); ++it)
|
||||
for (auto shape : shapes)
|
||||
{
|
||||
drawWithShape(_drawNode, *it);
|
||||
drawWithShape(_drawNode, shape);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,7 +284,6 @@ void PhysicsWorld::debugDraw()
|
|||
void PhysicsWorld::setScene(Scene *scene)
|
||||
{
|
||||
_scene = scene;
|
||||
scene->retain();
|
||||
}
|
||||
|
||||
void PhysicsWorld::drawWithShape(DrawNode* node, PhysicsShape* shape)
|
||||
|
@ -322,7 +410,6 @@ PhysicsWorld::~PhysicsWorld()
|
|||
{
|
||||
CC_SAFE_DELETE(_info);
|
||||
CC_SAFE_RELEASE(_bodys);
|
||||
CC_SAFE_RELEASE(_scene);
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#ifndef __CCPHYSICS_WORLD_H__
|
||||
#define __CCPHYSICS_WORLD_H__
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "cocoa/CCObject.h"
|
||||
#include "cocoa/CCGeometry.h"
|
||||
|
||||
|
@ -86,14 +88,18 @@ public:
|
|||
/** set the debug draw */
|
||||
inline void setDebugDraw(bool debugDraw) { _debugDraw = debugDraw; }
|
||||
|
||||
virtual void removeBody(PhysicsBody* body);
|
||||
virtual void removeBodyByTag(int tag);
|
||||
|
||||
protected:
|
||||
static PhysicsWorld* create();
|
||||
bool init();
|
||||
|
||||
void setScene(Scene* scene);
|
||||
|
||||
virtual void addChild(PhysicsBody* body);
|
||||
virtual void addBody(PhysicsBody* body);
|
||||
virtual void addShape(PhysicsShape* shape);
|
||||
virtual void removeShape(PhysicsShape* shape);
|
||||
virtual void update(float delta);
|
||||
|
||||
virtual void debugDraw();
|
||||
|
@ -120,6 +126,7 @@ protected:
|
|||
|
||||
|
||||
Array* _bodys;
|
||||
std::list<PhysicsJoint*> _joints;
|
||||
Scene* _scene;
|
||||
|
||||
bool _debugDraw;
|
||||
|
@ -132,6 +139,7 @@ protected:
|
|||
friend class Sprite;
|
||||
friend class Scene;
|
||||
friend class PhysicsBody;
|
||||
friend class PhysicsShape;
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -28,20 +28,27 @@
|
|||
NS_CC_BEGIN
|
||||
|
||||
std::map<cpShape*, PhysicsShapeInfo*> PhysicsShapeInfo::map;
|
||||
cpBody* PhysicsShapeInfo::shareBody = nullptr;
|
||||
|
||||
PhysicsShapeInfo::PhysicsShapeInfo(PhysicsShape* shape)
|
||||
: shape(shape)
|
||||
{
|
||||
if (shareBody == nullptr)
|
||||
{
|
||||
shareBody = cpBodyNewStatic();
|
||||
}
|
||||
|
||||
body = shareBody;
|
||||
}
|
||||
|
||||
PhysicsShapeInfo::~PhysicsShapeInfo()
|
||||
{
|
||||
for (auto it = shapes.begin(); it != shapes.end(); it++)
|
||||
for (auto shape : shapes)
|
||||
{
|
||||
cpShapeFree(*it);
|
||||
auto it = map.find(shape);
|
||||
if (it != map.end()) map.erase(shape);
|
||||
|
||||
auto mit = map.find(*it);
|
||||
if (mit != map.end()) map.erase(*it);
|
||||
cpShapeFree(shape);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,8 +46,10 @@ public:
|
|||
|
||||
public:
|
||||
std::vector<cpShape*> shapes;
|
||||
static std::map<cpShape*, PhysicsShapeInfo*> map;
|
||||
PhysicsShape* shape;
|
||||
cpBody* body;
|
||||
static std::map<cpShape*, PhysicsShapeInfo*> map;
|
||||
static cpBody* shareBody;
|
||||
|
||||
private:
|
||||
PhysicsShapeInfo(PhysicsShape* shape);
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ THE SOFTWARE.
|
|||
#include "CCDirector.h"
|
||||
#include "support/TransformUtils.h"
|
||||
#include "support/CCProfiling.h"
|
||||
#include "layers_scenes_transitions_nodes/CCLayer.h"
|
||||
#include "layers_scenes_transitions_nodes/CCScene.h"
|
||||
// external
|
||||
#include "kazmath/GL/matrix.h"
|
||||
|
||||
|
@ -180,6 +182,17 @@ void SpriteBatchNode::addChild(Node *child, int zOrder, int tag)
|
|||
Node::addChild(child, zOrder, tag);
|
||||
|
||||
appendChild(sprite);
|
||||
|
||||
|
||||
if (this->getParent() &&
|
||||
dynamic_cast<Layer*>(this->getParent()) != nullptr)
|
||||
{
|
||||
if (this->getParent()->getParent() &&
|
||||
dynamic_cast<Scene*>(this->getParent()->getParent()))
|
||||
{
|
||||
dynamic_cast<Scene*>(this->getParent()->getParent())->addChildToPhysicsWorld(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// override reorderChild
|
||||
|
|
|
@ -2,39 +2,204 @@
|
|||
#include "../testResource.h"
|
||||
USING_NS_CC;
|
||||
|
||||
PhysicsTestLayer::PhysicsTestLayer()
|
||||
: _spriteTexture(nullptr)
|
||||
, _scene(nullptr)
|
||||
namespace
|
||||
{
|
||||
static std::function<Layer*()> createFunctions[] = {
|
||||
CL(PhysicsDemoLogoSmash),
|
||||
CL(PhysicsDemoPyramidStack),
|
||||
CL(PhysicsDemoPlink),
|
||||
CL(PhysicsDemoClickAdd),
|
||||
};
|
||||
|
||||
static int sceneIdx=-1;
|
||||
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
|
||||
|
||||
static Layer* next()
|
||||
{
|
||||
sceneIdx++;
|
||||
sceneIdx = sceneIdx % MAX_LAYER;
|
||||
|
||||
auto layer = (createFunctions[sceneIdx])();
|
||||
layer->init();
|
||||
layer->autorelease();
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
static Layer* back()
|
||||
{
|
||||
sceneIdx--;
|
||||
int total = MAX_LAYER;
|
||||
if( sceneIdx < 0 )
|
||||
sceneIdx += total;
|
||||
|
||||
auto layer = (createFunctions[sceneIdx])();
|
||||
layer->init();
|
||||
layer->autorelease();
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
static Layer* restart()
|
||||
{
|
||||
auto layer = (createFunctions[sceneIdx])();
|
||||
layer->init();
|
||||
layer->autorelease();
|
||||
|
||||
return layer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool PhysicsTestScene::_debugDraw = false;
|
||||
|
||||
bool PhysicsTestScene::initTest()
|
||||
{
|
||||
#ifdef CC_USE_PHYSICS
|
||||
if(TestScene::initWithPhysics())
|
||||
{
|
||||
this->getPhysicsWorld()->setDebugDraw(_debugDraw);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
return TestScene::init();
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PhysicsTestScene::runThisTest()
|
||||
{
|
||||
#ifdef CC_USE_PHYSICS
|
||||
sceneIdx = -1;
|
||||
addChild(next());
|
||||
|
||||
Director::getInstance()->replaceScene(this);
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
void PhysicsTestScene::toggleDebug()
|
||||
{
|
||||
_debugDraw = !_debugDraw;
|
||||
getPhysicsWorld()->setDebugDraw(_debugDraw);
|
||||
}
|
||||
|
||||
PhysicsDemo::PhysicsDemo()
|
||||
: _scene(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PhysicsDemo::~PhysicsDemo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string PhysicsDemo::title()
|
||||
{
|
||||
return "PhysicsTest";
|
||||
}
|
||||
|
||||
std::string PhysicsDemo::subtitle()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
void PhysicsDemo::restartCallback(Object* sender)
|
||||
{
|
||||
auto s = new PhysicsTestScene();
|
||||
s->initTest();
|
||||
s->addChild( restart() );
|
||||
Director::getInstance()->replaceScene(s);
|
||||
s->release();
|
||||
}
|
||||
|
||||
void PhysicsDemo::nextCallback(Object* sender)
|
||||
{
|
||||
auto s = new PhysicsTestScene();
|
||||
s->initTest();
|
||||
s->addChild( next() );
|
||||
Director::getInstance()->replaceScene(s);
|
||||
s->release();
|
||||
}
|
||||
|
||||
void PhysicsDemo::backCallback(Object* sender)
|
||||
{
|
||||
auto s = new PhysicsTestScene();
|
||||
s->initTest();
|
||||
s->addChild( back() );
|
||||
Director::getInstance()->replaceScene(s);
|
||||
s->release();
|
||||
}
|
||||
|
||||
void PhysicsDemo::onEnter()
|
||||
{
|
||||
BaseTest::onEnter();
|
||||
|
||||
_scene = dynamic_cast<PhysicsTestScene*>(this->getParent());
|
||||
|
||||
_spriteTexture = SpriteBatchNode::create("Images/grossini_dance_atlas.png", 100)->getTexture();
|
||||
|
||||
#ifdef CC_USE_PHYSICS
|
||||
|
||||
// menu for debug layer
|
||||
MenuItemFont::setFontSize(18);
|
||||
auto item = MenuItemFont::create("Toggle debug", CC_CALLBACK_1(PhysicsDemo::toggleDebugCallback, this));
|
||||
|
||||
auto menu = Menu::create(item, NULL);
|
||||
this->addChild(menu);
|
||||
menu->setPosition(Point(VisibleRect::right().x-50, VisibleRect::top().y-10));
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
void PhysicsDemo::addGrossiniAtPosition(Point p, float scale/* = 1.0*/)
|
||||
{
|
||||
#ifdef CC_USE_PHYSICS
|
||||
CCLOG("Add sprite %0.2f x %02.f",p.x,p.y);
|
||||
|
||||
int posx, posy;
|
||||
|
||||
posx = CCRANDOM_0_1() * 200.0f;
|
||||
posy = CCRANDOM_0_1() * 200.0f;
|
||||
|
||||
posx = (posx % 4) * 85;
|
||||
posy = (posy % 3) * 121;
|
||||
|
||||
auto sp = Sprite::createWithTexture(_spriteTexture, Rect(posx, posy, 85, 121));
|
||||
sp->setScale(scale);
|
||||
sp->setPhysicsBody(PhysicsBody::createBox(Size(48.0f * scale, 108.0f * scale)));
|
||||
this->addChild(sp);
|
||||
sp->setPosition(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PhysicsDemo::toggleDebugCallback(Object* sender)
|
||||
{
|
||||
#ifdef CC_USE_PHYSICS
|
||||
if (_scene != nullptr)
|
||||
{
|
||||
_scene->toggleDebug();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void PhysicsDemoClickAdd::onEnter()
|
||||
{
|
||||
PhysicsDemo::onEnter();
|
||||
|
||||
#ifdef CC_USE_PHYSICS
|
||||
setTouchEnabled(true);
|
||||
setAccelerometerEnabled(true);
|
||||
|
||||
// title
|
||||
auto label = LabelTTF::create("Multi touch the screen", "Marker Felt", 36);
|
||||
label->setPosition(Point( VisibleRect::center().x, VisibleRect::top().y - 30));
|
||||
this->addChild(label, -1);
|
||||
auto node = Node::create();
|
||||
node->setPhysicsBody(PhysicsBody::createEdgeBox(VisibleRect::getVisibleRect().size));
|
||||
node->setPosition(VisibleRect::center());
|
||||
this->addChild(node);
|
||||
|
||||
// menu for debug layer
|
||||
MenuItemFont::setFontSize(18);
|
||||
auto item = MenuItemFont::create("Toggle debug", CC_CALLBACK_1(PhysicsTestLayer::toggleDebugCallback, this));
|
||||
|
||||
auto menu = Menu::create(item, NULL);
|
||||
this->addChild(menu);
|
||||
menu->setPosition(Point(VisibleRect::right().x-100, VisibleRect::top().y-60));
|
||||
|
||||
auto sp = Sprite::create();
|
||||
auto body = PhysicsBody::createEdgeBox(VisibleRect::getVisibleRect().size);
|
||||
sp->setPhysicsBody(body);
|
||||
this->addChild(sp);
|
||||
sp->setPosition(VisibleRect::center());
|
||||
|
||||
auto parent = SpriteBatchNode::create("Images/grossini_dance_atlas.png", 100);
|
||||
_spriteTexture = parent->getTexture();
|
||||
|
||||
addNewSpriteAtPosition(VisibleRect::center());
|
||||
|
||||
createResetButton();
|
||||
addGrossiniAtPosition(VisibleRect::center());
|
||||
|
||||
#else
|
||||
auto label = LabelTTF::create("Should define CC_USE_BOX2D or CC_USE_CHIPMUNK\n to run this test case",
|
||||
|
@ -47,41 +212,12 @@ PhysicsTestLayer::PhysicsTestLayer()
|
|||
#endif
|
||||
}
|
||||
|
||||
void PhysicsTestLayer::toggleDebugCallback(Object* sender)
|
||||
std::string PhysicsDemoClickAdd::subtitle()
|
||||
{
|
||||
#ifdef CC_USE_PHYSICS
|
||||
if (_scene != nullptr)
|
||||
{
|
||||
_scene->getPhysicsWorld()->setDebugDraw(!_scene->getPhysicsWorld()->isDebugDraw());
|
||||
}
|
||||
#endif
|
||||
return "multi touch to add grossini";
|
||||
}
|
||||
|
||||
PhysicsTestLayer::~PhysicsTestLayer()
|
||||
{
|
||||
}
|
||||
|
||||
void PhysicsTestLayer::createResetButton()
|
||||
{
|
||||
auto reset = MenuItemImage::create("Images/r1.png", "Images/r2.png", [](Object *sender) {
|
||||
auto s = new PhysicsTestScene();
|
||||
s->initTest();
|
||||
auto child = new PhysicsTestLayer();
|
||||
child->setScene(s);
|
||||
s->addChild(child);
|
||||
child->release();
|
||||
Director::getInstance()->replaceScene(s);
|
||||
s->release();
|
||||
});
|
||||
|
||||
auto menu = Menu::create(reset, NULL);
|
||||
|
||||
menu->setPosition(Point(VisibleRect::bottom().x, VisibleRect::bottom().y + 30));
|
||||
this->addChild(menu, -1);
|
||||
|
||||
}
|
||||
|
||||
void PhysicsTestLayer::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
|
||||
void PhysicsDemoClickAdd::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
|
||||
{
|
||||
//Add a new body/atlas sprite at the touched location
|
||||
|
||||
|
@ -89,12 +225,11 @@ void PhysicsTestLayer::onTouchesEnded(const std::vector<Touch*>& touches, Event*
|
|||
{
|
||||
auto location = touch->getLocation();
|
||||
|
||||
addNewSpriteAtPosition( location );
|
||||
addGrossiniAtPosition( location );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PhysicsTestLayer::onAcceleration(Acceleration* acc, Event* event)
|
||||
void PhysicsDemoClickAdd::onAcceleration(Acceleration* acc, Event* event)
|
||||
{
|
||||
#ifdef CC_USE_PHYSICS
|
||||
static float prevX=0, prevY=0;
|
||||
|
@ -117,48 +252,169 @@ void PhysicsTestLayer::onAcceleration(Acceleration* acc, Event* event)
|
|||
#endif
|
||||
}
|
||||
|
||||
void PhysicsTestLayer::addNewSpriteAtPosition(Point p)
|
||||
namespace
|
||||
{
|
||||
#ifdef CC_USE_PHYSICS
|
||||
CCLOG("Add sprite %0.2f x %02.f",p.x,p.y);
|
||||
|
||||
int posx, posy;
|
||||
|
||||
posx = CCRANDOM_0_1() * 200.0f;
|
||||
posy = CCRANDOM_0_1() * 200.0f;
|
||||
|
||||
posx = (posx % 4) * 85;
|
||||
posy = (posy % 3) * 121;
|
||||
|
||||
auto sp = Sprite::createWithTexture(_spriteTexture, Rect(posx, posy, 85, 121));
|
||||
auto body = PhysicsBody::createBox(Size(48, 108));
|
||||
sp->setPhysicsBody(body);
|
||||
sp->setPosition(p);
|
||||
this->addChild(sp);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool PhysicsTestScene::initTest()
|
||||
{
|
||||
#ifdef CC_USE_PHYSICS
|
||||
if (TestScene::initWithPhysics())
|
||||
static const int logo_width = 188;
|
||||
static const int logo_height = 35;
|
||||
static const int logo_row_length = 24;
|
||||
static const char logo_image[] =
|
||||
{
|
||||
this->getPhysicsWorld()->setDebugDraw(true);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
return TestScene::init();
|
||||
#endif
|
||||
15,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,-64,15,63,-32,-2,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,31,-64,15,127,-125,-1,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,127,-64,15,127,15,-1,-64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,-64,15,-2,
|
||||
31,-1,-64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,-64,0,-4,63,-1,-32,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,1,-1,-64,15,-8,127,-1,-32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
1,-1,-64,0,-8,-15,-1,-32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-31,-1,-64,15,-8,-32,
|
||||
-1,-32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,-15,-1,-64,9,-15,-32,-1,-32,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,31,-15,-1,-64,0,-15,-32,-1,-32,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,63,-7,-1,-64,9,-29,-32,127,-61,-16,63,15,-61,-1,-8,31,-16,15,-8,126,7,-31,
|
||||
-8,31,-65,-7,-1,-64,9,-29,-32,0,7,-8,127,-97,-25,-1,-2,63,-8,31,-4,-1,15,-13,
|
||||
-4,63,-1,-3,-1,-64,9,-29,-32,0,7,-8,127,-97,-25,-1,-2,63,-8,31,-4,-1,15,-13,
|
||||
-2,63,-1,-3,-1,-64,9,-29,-32,0,7,-8,127,-97,-25,-1,-1,63,-4,63,-4,-1,15,-13,
|
||||
-2,63,-33,-1,-1,-32,9,-25,-32,0,7,-8,127,-97,-25,-1,-1,63,-4,63,-4,-1,15,-13,
|
||||
-1,63,-33,-1,-1,-16,9,-25,-32,0,7,-8,127,-97,-25,-1,-1,63,-4,63,-4,-1,15,-13,
|
||||
-1,63,-49,-1,-1,-8,9,-57,-32,0,7,-8,127,-97,-25,-8,-1,63,-2,127,-4,-1,15,-13,
|
||||
-1,-65,-49,-1,-1,-4,9,-57,-32,0,7,-8,127,-97,-25,-8,-1,63,-2,127,-4,-1,15,-13,
|
||||
-1,-65,-57,-1,-1,-2,9,-57,-32,0,7,-8,127,-97,-25,-8,-1,63,-2,127,-4,-1,15,-13,
|
||||
-1,-1,-57,-1,-1,-1,9,-57,-32,0,7,-1,-1,-97,-25,-8,-1,63,-1,-1,-4,-1,15,-13,-1,
|
||||
-1,-61,-1,-1,-1,-119,-57,-32,0,7,-1,-1,-97,-25,-8,-1,63,-1,-1,-4,-1,15,-13,-1,
|
||||
-1,-61,-1,-1,-1,-55,-49,-32,0,7,-1,-1,-97,-25,-8,-1,63,-1,-1,-4,-1,15,-13,-1,
|
||||
-1,-63,-1,-1,-1,-23,-49,-32,127,-57,-1,-1,-97,-25,-1,-1,63,-1,-1,-4,-1,15,-13,
|
||||
-1,-1,-63,-1,-1,-1,-16,-49,-32,-1,-25,-1,-1,-97,-25,-1,-1,63,-33,-5,-4,-1,15,
|
||||
-13,-1,-1,-64,-1,-9,-1,-7,-49,-32,-1,-25,-8,127,-97,-25,-1,-1,63,-33,-5,-4,-1,
|
||||
15,-13,-1,-1,-64,-1,-13,-1,-32,-49,-32,-1,-25,-8,127,-97,-25,-1,-2,63,-49,-13,
|
||||
-4,-1,15,-13,-1,-1,-64,127,-7,-1,-119,-17,-15,-1,-25,-8,127,-97,-25,-1,-2,63,
|
||||
-49,-13,-4,-1,15,-13,-3,-1,-64,127,-8,-2,15,-17,-1,-1,-25,-8,127,-97,-25,-1,
|
||||
-8,63,-49,-13,-4,-1,15,-13,-3,-1,-64,63,-4,120,0,-17,-1,-1,-25,-8,127,-97,-25,
|
||||
-8,0,63,-57,-29,-4,-1,15,-13,-4,-1,-64,63,-4,0,15,-17,-1,-1,-25,-8,127,-97,
|
||||
-25,-8,0,63,-57,-29,-4,-1,-1,-13,-4,-1,-64,31,-2,0,0,103,-1,-1,-57,-8,127,-97,
|
||||
-25,-8,0,63,-57,-29,-4,-1,-1,-13,-4,127,-64,31,-2,0,15,103,-1,-1,-57,-8,127,
|
||||
-97,-25,-8,0,63,-61,-61,-4,127,-1,-29,-4,127,-64,15,-8,0,0,55,-1,-1,-121,-8,
|
||||
127,-97,-25,-8,0,63,-61,-61,-4,127,-1,-29,-4,63,-64,15,-32,0,0,23,-1,-2,3,-16,
|
||||
63,15,-61,-16,0,31,-127,-127,-8,31,-1,-127,-8,31,-128,7,-128,0,0};
|
||||
|
||||
return false;
|
||||
static inline int get_pixel(int x, int y)
|
||||
{
|
||||
return (logo_image[(x>>3) + y*logo_row_length]>>(~x&0x7)) & 1;
|
||||
}
|
||||
|
||||
static inline float frand(void)
|
||||
{
|
||||
return rand()/RAND_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsTestScene::runThisTest()
|
||||
Node* PhysicsDemoLogoSmash::makeBall(float x, float y)
|
||||
{
|
||||
auto layer = new PhysicsTestLayer();
|
||||
layer->setScene(this);
|
||||
addChild(layer);
|
||||
layer->release();
|
||||
auto ball = Sprite::createWithTexture(_ball->getTexture());
|
||||
ball->setScale(0.1);
|
||||
|
||||
Director::getInstance()->replaceScene(this);
|
||||
auto body = PhysicsBody::createCircle(0.95, PhysicsMaterial(1, 0, 0));
|
||||
body->setMass(1.0);
|
||||
body->setAngularDamping(PHYSICS_INFINITY);
|
||||
|
||||
//body->setDynamic(false);
|
||||
ball->setPhysicsBody(body);
|
||||
|
||||
ball->setPosition(Point(x, y));
|
||||
|
||||
return ball;
|
||||
}
|
||||
|
||||
void PhysicsDemoLogoSmash::onEnter()
|
||||
{
|
||||
PhysicsDemo::onEnter();
|
||||
|
||||
_scene->getPhysicsWorld()->setGravity(Point(0, 0));
|
||||
|
||||
_ball = SpriteBatchNode::create("Images/ball.png", sizeof(logo_image)/sizeof(logo_image[0]));
|
||||
addChild(_ball);
|
||||
for (int y = 0; y < logo_height; ++y)
|
||||
{
|
||||
for (int x = 0; x < logo_width; ++x)
|
||||
{
|
||||
if (get_pixel(x, y))
|
||||
{
|
||||
float x_jitter = 0.05*frand();
|
||||
float y_jitter = 0.05*frand();
|
||||
|
||||
_ball->addChild(makeBall(2*(x - logo_width/2 + x_jitter) + VisibleRect::getVisibleRect().size.width/2,
|
||||
2*(logo_height-y + y_jitter) + VisibleRect::getVisibleRect().size.height/2 - logo_height/2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
auto bullet = Sprite::createWithTexture(_ball->getTexture());
|
||||
bullet->setScale(0.5);
|
||||
|
||||
auto body = PhysicsBody::createCircle(8, PhysicsMaterial(PHYSICS_INFINITY, 0, 0));
|
||||
body->setVelocity(Point(400, 0));
|
||||
bullet->setPhysicsBody(body);
|
||||
|
||||
bullet->setPosition(Point(-1000, VisibleRect::getVisibleRect().size.height/2));
|
||||
|
||||
_ball->addChild(bullet);
|
||||
}
|
||||
|
||||
std::string PhysicsDemoLogoSmash::title()
|
||||
{
|
||||
return "Logo Smash";
|
||||
}
|
||||
|
||||
void PhysicsDemoPyramidStack::onEnter()
|
||||
{
|
||||
PhysicsDemo::onEnter();
|
||||
|
||||
auto node = Node::create();
|
||||
node->setPhysicsBody(PhysicsBody::createEdgeSegment(VisibleRect::leftBottom() + Point(0, 50), VisibleRect::rightBottom() + Point(0, 50)));
|
||||
this->addChild(node);
|
||||
|
||||
auto ball = Sprite::create("Images/ball.png");
|
||||
ball->setScale(1);
|
||||
ball->setPhysicsBody(PhysicsBody::createCircle(10));
|
||||
ball->setPosition(VisibleRect::bottom() + Point(0, 60));
|
||||
this->addChild(ball);
|
||||
|
||||
for(int i=0; i<14; i++)
|
||||
{
|
||||
for(int j=0; j<=i; j++)
|
||||
{
|
||||
addGrossiniAtPosition(VisibleRect::bottom() + Point((i/2 - j) * 11, (14 - i) * 23 + 100), 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string PhysicsDemoPyramidStack::title()
|
||||
{
|
||||
return "Pyramid Stack";
|
||||
}
|
||||
|
||||
|
||||
void PhysicsDemoPlink::onEnter()
|
||||
{
|
||||
PhysicsDemo::onEnter();
|
||||
|
||||
auto node = Node::create();
|
||||
auto body = PhysicsBody::create();
|
||||
body->setDynamic(false);
|
||||
node->setPhysicsBody(body);
|
||||
|
||||
Point tris[] = { Point(-15, -15), Point(0, 10), Point(15, -15) };
|
||||
|
||||
auto rect = VisibleRect::getVisibleRect();
|
||||
for (int i = 0; i < 9; ++i)
|
||||
{
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
body->addShape(PhysicsShapePolygon::create(tris, 3, PHYSICSSHAPE_MATERIAL_DEFAULT, Point(rect.origin.x + rect.size.width/9*i + (j%2)*40 - 20, rect.origin.y + j*70)));
|
||||
}
|
||||
}
|
||||
|
||||
addChild(node);
|
||||
|
||||
}
|
||||
|
||||
std::string PhysicsDemoPlink::title()
|
||||
{
|
||||
return "Plink";
|
||||
}
|
|
@ -3,30 +3,79 @@
|
|||
|
||||
#include "cocos2d.h"
|
||||
#include "../testBasic.h"
|
||||
#include "../BaseTest.h"
|
||||
|
||||
class PhysicsTestLayer : public Layer
|
||||
{
|
||||
Texture2D* _spriteTexture; // weak ref
|
||||
Scene* _scene;
|
||||
|
||||
public:
|
||||
PhysicsTestLayer();
|
||||
~PhysicsTestLayer();
|
||||
|
||||
void createResetButton();
|
||||
|
||||
inline void setScene(Scene* scene) { _scene = scene; }
|
||||
void toggleDebugCallback(Object* sender);
|
||||
void addNewSpriteAtPosition(Point p);
|
||||
virtual void onTouchesEnded(const std::vector<Touch*>& touches, Event* event) override;
|
||||
virtual void onAcceleration(Acceleration* acc, Event* event) override;
|
||||
} ;
|
||||
|
||||
class PhysicsTestScene : public TestScene
|
||||
{
|
||||
public:
|
||||
virtual bool initTest() override;
|
||||
virtual void runThisTest();
|
||||
|
||||
void toggleDebug();
|
||||
|
||||
private:
|
||||
static bool _debugDraw;
|
||||
};
|
||||
|
||||
class PhysicsDemo : public BaseTest
|
||||
{
|
||||
protected:
|
||||
PhysicsTestScene* _scene;
|
||||
|
||||
public:
|
||||
PhysicsDemo();
|
||||
virtual ~PhysicsDemo();
|
||||
|
||||
virtual void onEnter() override;
|
||||
virtual std::string title() override;
|
||||
virtual std::string subtitle() override;
|
||||
|
||||
void restartCallback(Object* sender);
|
||||
void nextCallback(Object* sender);
|
||||
void backCallback(Object* sender);
|
||||
void toggleDebugCallback(Object* sender);
|
||||
|
||||
void addGrossiniAtPosition(Point p, float scale = 1.0);
|
||||
|
||||
private:
|
||||
Texture2D* _spriteTexture; // weak ref
|
||||
};
|
||||
|
||||
class PhysicsDemoClickAdd : public PhysicsDemo
|
||||
{
|
||||
public:
|
||||
void onEnter() override;
|
||||
std::string subtitle() override;
|
||||
|
||||
void onTouchesEnded(const std::vector<Touch*>& touches, Event* event) override;
|
||||
void onAcceleration(Acceleration* acc, Event* event) override;
|
||||
};
|
||||
|
||||
class PhysicsDemoLogoSmash : public PhysicsDemo
|
||||
{
|
||||
public:
|
||||
void onEnter() override;
|
||||
std::string title() override;
|
||||
|
||||
Node* makeBall(float x, float y);
|
||||
|
||||
private:
|
||||
SpriteBatchNode* _ball;
|
||||
};
|
||||
|
||||
class PhysicsDemoPyramidStack : public PhysicsDemo
|
||||
{
|
||||
public:
|
||||
void onEnter() override;
|
||||
std::string title() override;
|
||||
};
|
||||
|
||||
class PhysicsDemoPlink : public PhysicsDemo
|
||||
{
|
||||
public:
|
||||
void onEnter() override;
|
||||
std::string title() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue