issue #2771: edit physics effect with all bodies and fix some bugs

This commit is contained in:
boyu0 2013-10-28 16:17:19 +08:00
parent d0d8694091
commit 66d1bbd89f
13 changed files with 124 additions and 77 deletions

View File

@ -476,30 +476,6 @@ void Layer::onTouchesCancelled(const std::vector<Touch*>& pTouches, Event *pEven
CC_UNUSED_PARAM(pEvent);
}
#ifdef CC_USE_PHYSICS
void Layer::addChild(Node* child)
{
Node::addChild(child);
}
void Layer::addChild(Node* child, int zOrder)
{
Node::addChild(child, zOrder);
}
void Layer::addChild(Node* child, int zOrder, int tag)
{
Node::addChild(child, zOrder, tag);
if (this->getParent() &&
dynamic_cast<Scene*>(this->getParent()) != nullptr)
{
dynamic_cast<Scene*>(this->getParent())->addChildToPhysicsWorld(child);
}
}
#endif
// LayerRGBA
LayerRGBA::LayerRGBA()
: _displayedOpacity(255)

View File

@ -180,12 +180,6 @@ public:
*/
virtual void onEnterTransitionDidFinish() override;
#ifdef CC_USE_PHYSICS
virtual void addChild(Node* child) override;
virtual void addChild(Node* child, int zOrder) override;
virtual void addChild(Node* child, int zOrder, int tag) override;
#endif // CC_USE_PHYSICS
protected:
void addTouchListener();

View File

@ -43,6 +43,7 @@ THE SOFTWARE.
#include "CCEventDispatcher.h"
#include "CCEvent.h"
#include "CCEventTouch.h"
#include "CCScene.h"
#ifdef CC_USE_PHYSICS
#include "CCPhysicsBody.h"
@ -627,6 +628,17 @@ void Node::addChild(Node *child, int zOrder, int tag)
this->insertChild(child, zOrder);
#ifdef CC_USE_PHYSICS
for (Node* node = this->getParent(); node != nullptr; node = node->getParent())
{
if (dynamic_cast<Scene*>(node) != nullptr)
{
(dynamic_cast<Scene*>(node))->addChildToPhysicsWorld(child);
break;
}
}
#endif
child->_tag = tag;
child->setParent(this);
@ -1392,10 +1404,12 @@ void Node::setPhysicsBody(PhysicsBody* body)
{
if (_physicsBody != nullptr)
{
_physicsBody->_owner = nullptr;
_physicsBody->release();
}
_physicsBody = body;
_physicsBody->_owner = this;
_physicsBody->retain();
_physicsBody->setPosition(getPosition());
_physicsBody->setRotation(getRotation());

View File

@ -136,14 +136,8 @@ void Scene::addChildToPhysicsWorld(Node* child)
std::function<void(Object*)> addToPhysicsWorldFunc = nullptr;
addToPhysicsWorldFunc = [this, &addToPhysicsWorldFunc](Object* child) -> void
{
if (dynamic_cast<SpriteBatchNode*>(child) != nullptr)
{
Object* subChild = nullptr;
CCARRAY_FOREACH((dynamic_cast<SpriteBatchNode*>(child))->getChildren(), subChild)
{
addToPhysicsWorldFunc(subChild);
}
}else if (dynamic_cast<Node*>(child) != nullptr)
if (dynamic_cast<Node*>(child) != nullptr)
{
Node* node = dynamic_cast<Node*>(child);
@ -151,20 +145,16 @@ void Scene::addChildToPhysicsWorld(Node* child)
{
_physicsWorld->addBody(node->getPhysicsBody());
}
Object* subChild = nullptr;
CCARRAY_FOREACH(node->getChildren(), subChild)
{
addToPhysicsWorldFunc(subChild);
}
}
};
if(dynamic_cast<Layer*>(child) != nullptr)
{
Object* subChild = nullptr;
CCARRAY_FOREACH(child->getChildren(), subChild)
{
addToPhysicsWorldFunc(subChild);
}
}else
{
addToPhysicsWorldFunc(child);
}
addToPhysicsWorldFunc(child);
}
}

View File

@ -87,7 +87,7 @@ protected:
PhysicsWorld* _physicsWorld;
#endif // CC_USE_PHYSICS
friend class Layer;
friend class Node;
friend class SpriteBatchNode;
};

View File

@ -182,17 +182,6 @@ 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

View File

@ -44,7 +44,7 @@ class PhysicsJoint;
class PhysicsBodyInfo;
const PhysicsMaterial PHYSICSBODY_MATERIAL_DEFAULT(1.0f, 1.0f, 1.0f);
const PhysicsMaterial PHYSICSBODY_MATERIAL_DEFAULT(0.01f, 0.5f, 0.5f);
/**
* A body affect by physics.
@ -152,7 +152,7 @@ public:
/*
* @brief get the sprite the body set to.
*/
inline Sprite* getOwner() const { return _owner; }
inline Node* getOwner() const { return _owner; }
inline void setCategoryBitmask(int bitmask) { _categoryBitmask = bitmask; }
inline int getCategoryBitmask() const { return _categoryBitmask; }
@ -261,7 +261,7 @@ protected:
virtual ~PhysicsBody();
protected:
Sprite* _owner;
Node* _owner;
std::vector<PhysicsJoint*> _joints;
Array* _shapes;
PhysicsWorld* _world;

View File

@ -41,6 +41,7 @@
#include "box2d/CCPhysicsShapeInfo.h"
#include "chipmunk/CCPhysicsHelper.h"
#include "box2d/CCPhysicsHelper.h"
#include "CCNode.h"
NS_CC_BEGIN
@ -149,6 +150,11 @@ PhysicsBodyInfo* PhysicsJoint::bodyInfo(PhysicsBody* body) const
return body->_info;
}
Node* PhysicsJoint::bodyOwner(PhysicsBody* body) const
{
return body->_owner;
}
void PhysicsJoint::setCollisionEnable(bool enable)
{
@ -182,6 +188,9 @@ bool PhysicsJointFixed::init(PhysicsBody* a, PhysicsBody* b, const Point& anchr)
{
CC_BREAK_IF(!PhysicsJoint::init(a, b));
bodyOwner(a)->setPosition(anchr);
bodyOwner(b)->setPosition(anchr);
// add a pivot joint to fixed two body together
cpConstraint* joint = cpPivotJointNew(bodyInfo(a)->body, bodyInfo(b)->body,
PhysicsHelper::point2cpv(anchr));
@ -219,7 +228,6 @@ bool PhysicsJointPin::init(PhysicsBody *a, PhysicsBody *b, const Point& anchr)
do
{
CC_BREAK_IF(!PhysicsJoint::init(a, b));
cpConstraint* joint = cpPivotJointNew(bodyInfo(a)->body, bodyInfo(b)->body,
PhysicsHelper::point2cpv(anchr));
@ -227,7 +235,7 @@ bool PhysicsJointPin::init(PhysicsBody *a, PhysicsBody *b, const Point& anchr)
_info->add(joint);
setCollisionEnable(false);
//setCollisionEnable(false);
return true;
} while (false);
@ -235,6 +243,16 @@ bool PhysicsJointPin::init(PhysicsBody *a, PhysicsBody *b, const Point& anchr)
return false;
}
void PhysicsJointPin::setMaxForce(float force)
{
_info->joints.front()->maxForce = PhysicsHelper::float2cpfloat(force);
}
float PhysicsJointPin::getMaxForce()
{
return PhysicsHelper::cpfloat2float(_info->joints.front()->maxForce);
}
PhysicsJointSliding* PhysicsJointSliding::create(PhysicsBody* a, PhysicsBody* b, const Point& grooveA, const Point& grooveB, const Point& anchr)
{
PhysicsJointSliding* joint = new PhysicsJointSliding();

View File

@ -63,6 +63,7 @@ protected:
* 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(PhysicsBody* body) const;
Node* bodyOwner(PhysicsBody* body) const;
protected:
PhysicsBody* _bodyA;
@ -82,7 +83,7 @@ protected:
class PhysicsJointFixed : public PhysicsJoint
{
public:
PhysicsJointFixed* create(PhysicsBody* a, PhysicsBody* b, const Point& anchr);
static PhysicsJointFixed* create(PhysicsBody* a, PhysicsBody* b, const Point& anchr);
protected:
bool init(PhysicsBody* a, PhysicsBody* b, const Point& anchr);
@ -98,7 +99,7 @@ protected:
class PhysicsJointSliding : public PhysicsJoint
{
public:
PhysicsJointSliding* create(PhysicsBody* a, PhysicsBody* b, const Point& grooveA, const Point& grooveB, const Point& anchr);
static PhysicsJointSliding* create(PhysicsBody* a, PhysicsBody* b, const Point& grooveA, const Point& grooveB, const Point& anchr);
protected:
bool init(PhysicsBody* a, PhysicsBody* b, const Point& grooveA, const Point& grooveB, const Point& anchr);
@ -153,6 +154,9 @@ class PhysicsJointPin : public PhysicsJoint
public:
static PhysicsJointPin* create(PhysicsBody* a, PhysicsBody* b, const Point& anchr);
void setMaxForce(float force);
float getMaxForce();
protected:
bool init(PhysicsBody* a, PhysicsBody* b, const Point& anchr);

View File

@ -57,7 +57,7 @@ typedef struct PhysicsMaterial
{}
}PhysicsMaterial;
const PhysicsMaterial PHYSICSSHAPE_MATERIAL_DEFAULT(0.0f, 1.0f, 1.0f);
const PhysicsMaterial PHYSICSSHAPE_MATERIAL_DEFAULT(0.0f, 0.5f, 0.5f);
/**
* @brief A shape for body. You do not create PhysicsWorld objects directly, instead, you can view PhysicsBody to see how to create it.

View File

@ -524,7 +524,7 @@ int PhysicsWorld::collisionBeginCallback(PhysicsContact& contact)
if (!joint->isCollisionEnable())
{
PhysicsBody* body = joint->getBodyA() == bodyA ? bodyB : bodyA;
PhysicsBody* body = joint->getBodyA() == bodyA ? joint->getBodyB() : joint->getBodyA();
if (body == bodyB)
{

View File

@ -10,6 +10,7 @@ namespace
CL(PhysicsDemoPlink),
CL(PhysicsDemoClickAdd),
CL(PhysicsDemoRayCast),
CL(PhysicsDemoJoints),
};
static int sceneIdx=-1;
@ -51,6 +52,7 @@ namespace
}
static const Color4F STATIC_COLOR(1.0f, 0.0f, 0.0f, 1.0f);
static const int DRAG_BODYS_TAG = 100;
}
@ -378,7 +380,7 @@ bool PhysicsDemo::onTouchBegan(Touch* touch, Event* event)
{
shape = dynamic_cast<PhysicsShape*>(obj);
if (shape->getTag() == 1)
if (shape->getTag() == DRAG_BODYS_TAG)
{
break;
}
@ -392,7 +394,8 @@ bool PhysicsDemo::onTouchBegan(Touch* touch, Event* event)
mouse->getPhysicsBody()->setDynamic(false);
mouse->setPosition(location);
this->addChild(mouse);
PhysicsJoint* joint = PhysicsJointPin::create(mouse->getPhysicsBody(), shape->getBody(), location);
PhysicsJointPin* joint = PhysicsJointPin::create(mouse->getPhysicsBody(), shape->getBody(), location);
joint->setMaxForce(5000.0f);
_scene->getPhysicsWorld()->addJoint(joint);
_mouses.insert(std::make_pair(touch->getID(), mouse));
@ -492,7 +495,7 @@ void PhysicsDemoPyramidStack::onEnter()
{
auto sp = addGrossiniAtPosition(VisibleRect::bottom() + Point((i/2 - j) * 11, (14 - i) * 23 + 100), 0.2f);
sp->getPhysicsBody()->setTag(1);
sp->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
}
}
}
@ -741,15 +744,74 @@ std::string PhysicsDemoRayCast::title()
}
PhysicsDemoJoints::PhysicsDemoJoints()
{
}
void PhysicsDemoJoints::onEnter()
{
PhysicsDemo::onEnter();
setTouchEnabled(true);
setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
_scene->getPhysicsWorld()->setGravity(Point::ZERO);
//_scene->getPhysicsWorld()->setGravity(Point::ZERO);
float width = (VisibleRect::getVisibleRect().size.width - 10) / 4;
float height = (VisibleRect::getVisibleRect().size.height - 50) / 4;
Node* node = Node::create();
PhysicsBody* box = PhysicsBody::create();
node->setPhysicsBody(box);
box->setDynamic(false);
node->setPosition(Point::ZERO);
this->addChild(node);
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 4; ++j)
{
Point offset(VisibleRect::leftBottom().x + 5 + j * width + width/2, VisibleRect::leftBottom().y + 50 + i * height + height/2);
box->addShape(PhysicsShapeEdgeBox::create(Size(width, height), PHYSICSSHAPE_MATERIAL_DEFAULT, 1, offset));
switch (i*4 + j)
{
case 0:
{
auto sp1 = makeBall(offset.x - 30, offset.y, 10);
sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
auto sp2 = makeBall(offset.x + 30, offset.y, 10);
sp2->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
PhysicsJointPin* joint = PhysicsJointPin::create(sp1->getPhysicsBody(), sp2->getPhysicsBody(), offset);
_scene->getPhysicsWorld()->addJoint(joint);
this->addChild(sp1);
this->addChild(sp2);
break;
}
case 1:
{
auto sp1 = makeBall(offset.x - 30, offset.y, 10);
sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
auto sp2 = makeBox(offset.x + 30, offset.y, Size(30, 10));
sp2->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
PhysicsJointFixed* joint = PhysicsJointFixed::create(sp1->getPhysicsBody(), sp2->getPhysicsBody(), offset);
_scene->getPhysicsWorld()->addJoint(joint);
this->addChild(sp1);
this->addChild(sp2);
break;
}
default:
break;
}
}
}
}
std::string PhysicsDemoJoints::title()

View File

@ -39,9 +39,9 @@ public:
void toggleDebugCallback(Object* sender);
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));
Sprite* makeBall(float x, float y, float radius, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT);
Sprite* makeBox(float x, float y, Size size, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT);
Sprite* makeTriangle(float x, float y, Size size, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT);
bool onTouchBegan(Touch* touch, Event* event) override;
void onTouchMoved(Touch* touch, Event* event) override;