issue #2771: enhance Listener use EventListener mechanism

This commit is contained in:
boyu0 2013-11-01 14:50:06 +08:00
Родитель dec749a692
Коммит b2951b70ff
9 изменённых файлов: 373 добавлений и 136 удалений

Просмотреть файл

@ -102,8 +102,7 @@ bool Scene::initWithPhysics()
Director * pDirector;
CC_BREAK_IF( ! (pDirector = Director::getInstance()) );
this->setContentSize(pDirector->getWinSize());
CC_BREAK_IF(! (_physicsWorld = PhysicsWorld::create()));
_physicsWorld->setScene(this);
CC_BREAK_IF(! (_physicsWorld = PhysicsWorld::create(*this)));
this->scheduleUpdate();
// success

Просмотреть файл

@ -207,6 +207,7 @@ typedef int (Object::*SEL_Compare)(Object*);
#define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)
#define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__)
#define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)
#define CC_CALLBACK_3(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3 ##__VA_ARGS__)
// end of base_nodes group
/// @}

Просмотреть файл

@ -44,7 +44,7 @@ class PhysicsJoint;
class PhysicsBodyInfo;
const PhysicsMaterial PHYSICSBODY_MATERIAL_DEFAULT(0.01f, 0.5f, 0.5f);
const PhysicsMaterial PHYSICSBODY_MATERIAL_DEFAULT(0.1f, 0.5f, 0.5f);
/**
* A body affect by physics.

Просмотреть файл

@ -30,22 +30,30 @@
#include "Box2D.h"
#endif
#include "CCPhysicsBody.h"
#include "chipmunk/CCPhysicsContactInfo_chipmunk.h"
#include "box2d/CCPhysicsContactInfo_box2d.h"
#include "chipmunk/CCPhysicsHelper_chipmunk.h"
#include "box2d/CCPhysicsHelper_box2d.h"
#include "CCEventCustom.h"
NS_CC_BEGIN
PhysicsContact::PhysicsContact()
: _shapeA(nullptr)
: Event(Event::Type::CUSTOM)
, _world(nullptr)
, _shapeA(nullptr)
, _shapeB(nullptr)
, _eventCode(EventCode::NONE)
, _info(nullptr)
, _notify(true)
, _begin(false)
, _data(nullptr)
, _contactInfo(nullptr)
, _contactData(nullptr)
, _result(true)
{
}
@ -172,25 +180,106 @@ Point PhysicsContactPostSolve::getSurfaceVelocity()
return PhysicsHelper::cpv2point(((cpArbiter*)_contactInfo)->surface_vr);
}
PhysicsContactListener::PhysicsContactListener()
EventListenerPhysicsContact::EventListenerPhysicsContact()
: onContactBegin(nullptr)
, onContactPreSolve(nullptr)
, onContactPostSolve(nullptr)
, onContactEnd(nullptr)
, onContactSeperate(nullptr)
{
}
bool EventListenerPhysicsContact::init()
{
auto func = [this](EventCustom* event) -> void
{
return onEvent(event);
};
return EventListenerCustom::init(std::hash<std::string>()(PHYSICSCONTACT_EVENT_NAME), func);
}
void EventListenerPhysicsContact::onEvent(EventCustom* event)
{
PhysicsContact& contact = *(PhysicsContact*)(event->getUserData());
switch (contact.getEventCode())
{
case PhysicsContact::EventCode::BEGIN:
{
bool ret = true;
if (onContactBegin != nullptr
&& contact.getNotify()
&& test(contact.getShapeA(), contact.getShapeB()))
{
contact._begin = true;
contact.generateContactData();
// the mask has high priority than _listener->onContactBegin.
// so if the mask test is false, the two bodies won't have collision.
if (ret)
{
ret = onContactBegin(event, contact);
}else
{
onContactBegin(event, contact);
}
}
contact.setResult(ret);
break;
}
case PhysicsContact::EventCode::PRESOLVE:
{
bool ret = true;
if (onContactPreSolve != nullptr
&& test(contact.getShapeA(), contact.getShapeB()))
{
PhysicsContactPreSolve solve(contact._begin ? nullptr : contact._contactData, contact._contactInfo);
contact._begin = false;
contact.generateContactData();
ret = onContactPreSolve(event, contact, solve);
}
contact.setResult(ret);
break;
}
case PhysicsContact::EventCode::POSTSOLVE:
{
if (onContactPreSolve != nullptr
&& test(contact.getShapeA(), contact.getShapeB()))
{
PhysicsContactPostSolve solve(contact._contactInfo);
onContactPostSolve(event, contact, solve);
}
break;
}
case PhysicsContact::EventCode::SEPERATE:
{
if (onContactSeperate != nullptr
&& test(contact.getShapeA(), contact.getShapeB()))
{
onContactSeperate(event, contact);
}
break;
}
default:
break;
}
}
EventListenerPhysicsContact::~EventListenerPhysicsContact()
{
}
PhysicsContactListener::~PhysicsContactListener()
EventListenerPhysicsContact* EventListenerPhysicsContact::create()
{
EventListenerPhysicsContact* obj = new EventListenerPhysicsContact();
}
PhysicsContactListener* PhysicsContactListener::create()
{
PhysicsContactListener* obj = new PhysicsContactListener();
if (obj != nullptr)
if (obj != nullptr && obj->init())
{
obj->autorelease();
return obj;
@ -200,17 +289,17 @@ PhysicsContactListener* PhysicsContactListener::create()
return nullptr;
}
bool PhysicsContactListener::test(PhysicsShape* shapeA, PhysicsShape* shapeB)
bool EventListenerPhysicsContact::test(PhysicsShape* shapeA, PhysicsShape* shapeB)
{
CC_UNUSED_PARAM(shapeA);
CC_UNUSED_PARAM(shapeB);
return true;
}
bool PhysicsContactListener::checkAvailable()
bool EventListenerPhysicsContact::checkAvailable()
{
if (onContactBegin == nullptr && onContactPreSolve == nullptr
&& onContactPostSolve == nullptr && onContactEnd == nullptr)
&& onContactPostSolve == nullptr && onContactSeperate == nullptr)
{
CCASSERT(false, "Invalid PhysicsContactListener.");
return false;
@ -219,16 +308,16 @@ bool PhysicsContactListener::checkAvailable()
return true;
}
EventListener* PhysicsContactListener::clone()
EventListenerPhysicsContact* EventListenerPhysicsContact::clone()
{
PhysicsContactListener* obj = PhysicsContactListener::create();
EventListenerPhysicsContact* obj = EventListenerPhysicsContact::create();
if (obj != nullptr)
{
obj->onContactBegin = onContactBegin;
obj->onContactPreSolve = onContactPreSolve;
obj->onContactPostSolve = onContactPostSolve;
obj->onContactEnd = onContactEnd;
obj->onContactSeperate = onContactSeperate;
return obj;
}
@ -237,14 +326,79 @@ EventListener* PhysicsContactListener::clone()
return nullptr;
}
PhysicsContactWithBodysListener* PhysicsContactWithBodysListener::create(PhysicsShape* shapeA, PhysicsShape* shapeB)
EventListenerPhysicsContactWithBodies* EventListenerPhysicsContactWithBodies::create(PhysicsBody* bodyA, PhysicsBody* bodyB)
{
PhysicsContactWithBodysListener* obj = new PhysicsContactWithBodysListener();
EventListenerPhysicsContactWithBodies* obj = new EventListenerPhysicsContactWithBodies();
if (obj != nullptr && obj->init())
{
obj->_a = bodyA;
obj->_b = bodyB;
obj->autorelease();
return obj;
}
CC_SAFE_DELETE(obj);
return nullptr;
}
EventListenerPhysicsContactWithBodies::EventListenerPhysicsContactWithBodies()
: _a(nullptr)
, _b(nullptr)
{
}
EventListenerPhysicsContactWithBodies::~EventListenerPhysicsContactWithBodies()
{
}
bool EventListenerPhysicsContactWithBodies::test(PhysicsShape* shapeA, PhysicsShape* shapeB)
{
if ((shapeA->getBody() == _a && shapeB->getBody() == _b)
|| (shapeA->getBody() == _b && shapeB->getBody() == _a))
{
return true;
}
return false;
}
EventListenerPhysicsContactWithBodies* EventListenerPhysicsContactWithBodies::clone()
{
EventListenerPhysicsContactWithBodies* obj = EventListenerPhysicsContactWithBodies::create(_a, _b);
if (obj != nullptr)
{
obj->onContactBegin = onContactBegin;
obj->onContactPreSolve = onContactPreSolve;
obj->onContactPostSolve = onContactPostSolve;
obj->onContactSeperate = onContactSeperate;
return obj;
}
CC_SAFE_DELETE(obj);
return nullptr;
}
EventListenerPhysicsContactWithShapes::EventListenerPhysicsContactWithShapes()
: _a(nullptr)
, _b(nullptr)
{
}
EventListenerPhysicsContactWithShapes::~EventListenerPhysicsContactWithShapes()
{
}
EventListenerPhysicsContactWithShapes* EventListenerPhysicsContactWithShapes::create(PhysicsShape* shapeA, PhysicsShape* shapeB)
{
EventListenerPhysicsContactWithShapes* obj = new EventListenerPhysicsContactWithShapes();
if (obj != nullptr && obj->init())
{
obj->_a = shapeA;
obj->_b = shapeB;
@ -256,17 +410,7 @@ PhysicsContactWithBodysListener* PhysicsContactWithBodysListener::create(Physics
return nullptr;
}
PhysicsContactWithBodysListener::PhysicsContactWithBodysListener()
{
}
PhysicsContactWithBodysListener::~PhysicsContactWithBodysListener()
{
}
bool PhysicsContactWithBodysListener::test(PhysicsShape* shapeA, PhysicsShape* shapeB)
bool EventListenerPhysicsContactWithShapes::test(PhysicsShape* shapeA, PhysicsShape* shapeB)
{
if ((shapeA == _a && shapeB == _b)
|| (shapeA == _b && shapeB == _a))
@ -277,16 +421,68 @@ bool PhysicsContactWithBodysListener::test(PhysicsShape* shapeA, PhysicsShape* s
return false;
}
EventListener* PhysicsContactWithBodysListener::clone()
EventListenerPhysicsContactWithShapes* EventListenerPhysicsContactWithShapes::clone()
{
PhysicsContactWithBodysListener* obj = PhysicsContactWithBodysListener::create(_a, _b);
EventListenerPhysicsContactWithShapes* obj = EventListenerPhysicsContactWithShapes::create(_a, _b);
if (obj != nullptr)
{
obj->onContactBegin = onContactBegin;
obj->onContactPreSolve = onContactPreSolve;
obj->onContactPostSolve = onContactPostSolve;
obj->onContactEnd = onContactEnd;
obj->onContactSeperate = onContactSeperate;
return obj;
}
CC_SAFE_DELETE(obj);
return nullptr;
}
EventListenerPhysicsContactWithGroup::EventListenerPhysicsContactWithGroup()
: _group(CP_NO_GROUP)
{
}
EventListenerPhysicsContactWithGroup::~EventListenerPhysicsContactWithGroup()
{
}
EventListenerPhysicsContactWithGroup* EventListenerPhysicsContactWithGroup::create(int group)
{
EventListenerPhysicsContactWithGroup* obj = new EventListenerPhysicsContactWithGroup();
if (obj != nullptr && obj->init())
{
obj->_group = group;
obj->autorelease();
return obj;
}
CC_SAFE_DELETE(obj);
return nullptr;
}
bool EventListenerPhysicsContactWithGroup::test(PhysicsShape* shapeA, PhysicsShape* shapeB)
{
if (shapeA->getGroup() == _group || shapeB->getGroup() == _group)
{
return true;
}
return false;
}
EventListenerPhysicsContactWithGroup* EventListenerPhysicsContactWithGroup::clone()
{
EventListenerPhysicsContactWithGroup* obj = EventListenerPhysicsContactWithGroup::create(_group);
if (obj != nullptr)
{
obj->onContactBegin = onContactBegin;
obj->onContactPreSolve = onContactPreSolve;
obj->onContactPostSolve = onContactPostSolve;
obj->onContactSeperate = onContactSeperate;
return obj;
}

Просмотреть файл

@ -30,11 +30,13 @@
#include "CCObject.h"
#include "CCGeometry.h"
#include "CCEventListener.h"
#include "CCEventListenerCustom.h"
#include "CCEvent.h"
NS_CC_BEGIN
class PhysicsShape;
class PhysicsBody;
class PhysicsWorld;
class PhysicsContactInfo;
@ -54,9 +56,19 @@ typedef struct PhysicsContactData
/**
* @brief Contact infomation. it will created automatically when two shape contact with each other. and it will destoried automatically when two shape separated.
*/
class PhysicsContact
class PhysicsContact : Event
{
public:
enum class EventCode
{
NONE,
BEGIN,
PRESOLVE,
POSTSOLVE,
SEPERATE
};
/*
* @brief get contact shape A.
*/
@ -75,12 +87,19 @@ public:
*/
inline void setData(void* data) { _data = data; }
EventCode getEventCode() { return _eventCode; };
private:
static PhysicsContact* create(PhysicsShape* a, PhysicsShape* b);
bool init(PhysicsShape* a, PhysicsShape* b);
void setEventCode(EventCode eventCode) { _eventCode = eventCode; };
inline bool getNotify() { return _notify; }
inline void setNotify(bool notify) { _notify = notify; }
inline PhysicsWorld* getWorld() { return _world; }
inline void setWorld(PhysicsWorld* world) { _world = world; }
inline void setResult(bool result) { _result = result; }
inline bool resetResult() { bool ret = _result; _result = true; return ret; }
void generateContactData();
@ -89,18 +108,22 @@ private:
~PhysicsContact();
private:
PhysicsWorld* _world;
PhysicsShape* _shapeA;
PhysicsShape* _shapeB;
EventCode _eventCode;
PhysicsContactInfo* _info;
bool _notify;
bool _begin;
bool _result;
void* _data;
void* _contactInfo;
PhysicsContactData* _contactData;
friend class PhysicsWorld;
friend class EventListenerPhysicsContact;
friend class PhysicsWorldCallback;
friend class PhysicsWorld;
};
/*
@ -128,7 +151,7 @@ private:
PhysicsContactData* _preContactData;
void* _contactInfo;
friend class PhysicsWorld;
friend class EventListenerPhysicsContact;
};
/*
@ -149,60 +172,99 @@ private:
private:
void* _contactInfo;
friend class PhysicsWorld;
friend class EventListenerPhysicsContact;
};
static const char* PHYSICSCONTACT_EVENT_NAME = "PhysicsContactEvent";
/*
* @brief contact listener.
*/
class PhysicsContactListener : public EventListener
class EventListenerPhysicsContact : public EventListenerCustom
{
public:
static PhysicsContactListener* create();
static EventListenerPhysicsContact* create();
virtual bool test(PhysicsShape* shapeA, PhysicsShape* shapeB);
virtual bool checkAvailable();
virtual EventListener* clone();
virtual bool checkAvailable() override;
virtual EventListenerPhysicsContact* clone() override;
public:
/*
* @brief it will called at two shapes start to contact, and only call it once.
*/
std::function<bool(PhysicsWorld& world, const PhysicsContact& contact)> onContactBegin;
std::function<bool(EventCustom* event, const PhysicsContact& contact)> onContactBegin;
/*
* @brief Two shapes are touching during this step. Return false from the callback to make world ignore the collision this step or true to process it normally. Additionally, you may override collision values, elasticity, or surface velocity values.
*/
std::function<bool(PhysicsWorld& world, const PhysicsContact& contact, const PhysicsContactPreSolve& solve)> onContactPreSolve;
std::function<bool(EventCustom* event, const PhysicsContact& contact, const PhysicsContactPreSolve& solve)> onContactPreSolve;
/*
* @brief Two shapes are touching and their collision response has been processed. You can retrieve the collision impulse or kinetic energy at this time if you want to use it to calculate sound volumes or damage amounts. See cpArbiter for more info
*/
std::function<void(PhysicsWorld& world, const PhysicsContact& contact, const PhysicsContactPostSolve& solve)> onContactPostSolve;
std::function<void(EventCustom* event, const PhysicsContact& contact, const PhysicsContactPostSolve& solve)> onContactPostSolve;
/*
* @brief it will called at two shapes separated, and only call it once.
* onContactBegin and onContactEnd will called in pairs.
* onContactBegin and onContactSeperate will called in pairs.
*/
std::function<void(PhysicsWorld& world, const PhysicsContact& contact)> onContactEnd;
std::function<void(EventCustom* event, const PhysicsContact& contact)> onContactSeperate;
protected:
PhysicsContactListener();
virtual ~PhysicsContactListener();
bool init();
void onEvent(EventCustom* event);
protected:
EventListenerPhysicsContact();
virtual ~EventListenerPhysicsContact();
};
class PhysicsContactWithBodysListener : public PhysicsContactListener
class EventListenerPhysicsContactWithBodies : public EventListenerPhysicsContact
{
public:
static PhysicsContactWithBodysListener* create(PhysicsShape* shapeA, PhysicsShape* shapeB);
static EventListenerPhysicsContactWithBodies* create(PhysicsBody* bodyA, PhysicsBody* bodyB);
virtual bool test(PhysicsShape* shapeA, PhysicsShape* shapeB);
virtual EventListener* clone();
virtual EventListenerPhysicsContactWithBodies* clone() override;
protected:
PhysicsBody* _a;
PhysicsBody* _b;
protected:
EventListenerPhysicsContactWithBodies();
virtual ~EventListenerPhysicsContactWithBodies();
};
class EventListenerPhysicsContactWithShapes : public EventListenerPhysicsContact
{
public:
static EventListenerPhysicsContactWithShapes* create(PhysicsShape* shapeA, PhysicsShape* shapeB);
virtual bool test(PhysicsShape* shapeA, PhysicsShape* shapeB);
virtual EventListenerPhysicsContactWithShapes* clone() override;
protected:
PhysicsShape* _a;
PhysicsShape* _b;
protected:
PhysicsContactWithBodysListener();
virtual ~PhysicsContactWithBodysListener();
EventListenerPhysicsContactWithShapes();
virtual ~EventListenerPhysicsContactWithShapes();
};
class EventListenerPhysicsContactWithGroup : public EventListenerPhysicsContact
{
public:
static EventListenerPhysicsContactWithGroup* create(int group);
virtual bool test(PhysicsShape* shapeA, PhysicsShape* shapeB);
virtual EventListenerPhysicsContactWithGroup* clone() override;
protected:
int _group;
protected:
EventListenerPhysicsContactWithGroup();
virtual ~EventListenerPhysicsContactWithGroup();
};
NS_CC_END

Просмотреть файл

@ -53,6 +53,8 @@
#include "CCArray.h"
#include "CCScene.h"
#include "CCDirector.h"
#include "CCEventDispatcher.h"
#include "CCEventCustom.h"
#include <algorithm>
@ -175,7 +177,7 @@ void PhysicsWorldCallback::nearestPointQueryFunc(cpShape *shape, cpFloat distanc
arr->addObject(it->second->shape);
}
bool PhysicsWorld::init()
bool PhysicsWorld::init(Scene& scene)
{
do
{
@ -184,6 +186,8 @@ bool PhysicsWorld::init()
_bodies = Array::create();
CC_BREAK_IF(_bodies == nullptr);
_bodies->retain();
_scene = &scene;
cpSpaceSetGravity(_info->space, PhysicsHelper::point2cpv(_gravity));
@ -458,11 +462,6 @@ void PhysicsWorld::debugDraw()
}
}
void PhysicsWorld::setScene(Scene *scene)
{
_scene = scene;
}
void PhysicsWorld::drawWithJoint(DrawNode* node, PhysicsJoint* joint)
{
for (auto it = joint->_info->joints.begin(); it != joint->_info->joints.end(); ++it)
@ -571,6 +570,7 @@ void PhysicsWorld::drawWithShape(DrawNode* node, PhysicsShape* shape)
int PhysicsWorld::collisionBeginCallback(PhysicsContact& contact)
{
bool ret = true;
PhysicsShape* shapeA = contact.getShapeA();
PhysicsShape* shapeB = contact.getShapeB();
PhysicsBody* bodyA = shapeA->getBody();
@ -597,7 +597,6 @@ int PhysicsWorld::collisionBeginCallback(PhysicsContact& contact)
}
}
// bitmask check
if ((shapeA->getCategoryBitmask() & shapeB->getContactTestBitmask()) == 0
|| (shapeB->getContactTestBitmask() & shapeA->getCategoryBitmask()) == 0)
@ -617,69 +616,42 @@ int PhysicsWorld::collisionBeginCallback(PhysicsContact& contact)
}
}
if (contact.getNotify() && _listener && _listener->onContactBegin)
{
contact._begin = true;
contact.generateContactData();
// the mask has high priority than _listener->onContactBegin.
// so if the mask test is false, the two bodies won't have collision.
if (ret)
{
ret = _listener->onContactBegin(*this, contact);
}else
{
_listener->onContactBegin(*this, contact);
}
}
contact.setEventCode(PhysicsContact::EventCode::BEGIN);
contact.setWorld(this);
EventCustom event(PHYSICSCONTACT_EVENT_NAME);
event.setUserData(&contact);
_scene->getEventDispatcher()->dispatchEvent(&event);
return ret;
return ret ? contact.resetResult() : false;
}
int PhysicsWorld::collisionPreSolveCallback(PhysicsContact& contact)
{
if (!contact.getNotify())
{
return true;
}
contact.setEventCode(PhysicsContact::EventCode::PRESOLVE);
contact.setWorld(this);
EventCustom event(PHYSICSCONTACT_EVENT_NAME);
event.setUserData(&contact);
_scene->getEventDispatcher()->dispatchEvent(&event);
if (_listener && _listener->onContactPreSolve)
{
PhysicsContactPreSolve solve(contact._begin ? nullptr : contact._contactData, contact._contactInfo);
contact._begin = false;
contact.generateContactData();
return _listener->onContactPreSolve(*this, contact, solve);
}
return true;
return contact.resetResult();
}
void PhysicsWorld::collisionPostSolveCallback(PhysicsContact& contact)
{
if (!contact.getNotify())
{
return;
}
if (_listener && _listener->onContactPreSolve)
{
PhysicsContactPostSolve solve(contact._contactInfo);
_listener->onContactPostSolve(*this, contact, solve);
}
contact.setEventCode(PhysicsContact::EventCode::POSTSOLVE);
contact.setWorld(this);
EventCustom event(PHYSICSCONTACT_EVENT_NAME);
event.setUserData(&contact);
_scene->getEventDispatcher()->dispatchEvent(&event);
}
void PhysicsWorld::collisionSeparateCallback(PhysicsContact& contact)
{
if (!contact.getNotify())
{
return;
}
if (_listener && _listener->onContactEnd)
{
_listener->onContactEnd(*this, contact);
}
contact.setEventCode(PhysicsContact::EventCode::SEPERATE);
contact.setWorld(this);
EventCustom event(PHYSICSCONTACT_EVENT_NAME);
event.setUserData(&contact);
_scene->getEventDispatcher()->dispatchEvent(&event);
}
void PhysicsWorld::setGravity(Point gravity)
@ -786,10 +758,10 @@ PhysicsBody* PhysicsWorld::getBodyByTag(int tag)
#endif
PhysicsWorld* PhysicsWorld::create()
PhysicsWorld* PhysicsWorld::create(Scene& scene)
{
PhysicsWorld * world = new PhysicsWorld();
if(world && world->init())
if(world && world->init(scene))
{
return world;
}
@ -802,7 +774,6 @@ PhysicsWorld::PhysicsWorld()
: _gravity(Point(0.0f, -98.0f))
, _speed(1.0f)
, _info(nullptr)
, _listener(nullptr)
, _bodies(nullptr)
, _scene(nullptr)
, _debugDraw(false)

Просмотреть файл

@ -40,7 +40,6 @@ class PhysicsJoint;
class PhysicsWorldInfo;
class PhysicsShape;
class PhysicsContact;
class PhysicsContactListener;
class Array;
class Sprite;
@ -101,10 +100,11 @@ public:
PhysicsBody* getBodyByTag(int tag);
/** Register a listener to receive contact callbacks*/
inline void registerContactListener(PhysicsContactListener* delegate) { _listener = delegate; }
//inline void registerContactListener(EventListenerPhysicsContact* delegate) { _listener = delegate; }
/** Unregister a listener. */
inline void unregisterContactListener() { _listener = nullptr; }
//inline void unregisterContactListener() { _listener = nullptr; }
inline Scene& getScene() { return *_scene; }
/** get the gravity value */
inline Point getGravity() { return _gravity; }
/** set the gravity value */
@ -120,10 +120,8 @@ public:
virtual void removeAllBodies();
protected:
static PhysicsWorld* create();
bool init();
void setScene(Scene* scene);
static PhysicsWorld* create(Scene& scene);
bool init(Scene& scene);
virtual PhysicsBody* addBody(PhysicsBody* body);
virtual PhysicsShape* addShape(PhysicsShape* shape);
@ -144,8 +142,7 @@ protected:
Point _gravity;
float _speed;
PhysicsWorldInfo* _info;
PhysicsContactListener* _listener;
//EventListenerPhysicsContact* _listener;
Array* _bodies;
std::list<PhysicsJoint*> _joints;

Просмотреть файл

@ -898,7 +898,7 @@ void PhysicsDemoPump::onEnter()
// balls
for (int i = 0; i < 6; ++i)
{
auto ball = makeBall(VisibleRect::leftTop() + Point(75 + CCRANDOM_0_1() * 90, 0), 22, PhysicsMaterial(0.5f, 0.0f, 0.1f));
auto ball = makeBall(VisibleRect::leftTop() + Point(75 + CCRANDOM_0_1() * 90, 0), 22, PhysicsMaterial(0.05f, 0.0f, 0.1f));
ball->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
addChild(ball);
}
@ -908,8 +908,8 @@ void PhysicsDemoPump::onEnter()
Point vec[4] =
{
VisibleRect::leftTop() + Point(102, -146),
VisibleRect::leftTop() + Point(148, -159),
VisibleRect::leftTop() + Point(102, -148),
VisibleRect::leftTop() + Point(148, -161),
VisibleRect::leftBottom() + Point(148, 20),
VisibleRect::leftBottom() + Point(102, 20)
};
@ -918,7 +918,7 @@ void PhysicsDemoPump::onEnter()
// small gear
auto sgear = Node::create();
auto sgearB = PhysicsBody::createCircle(50);
auto sgearB = PhysicsBody::createCircle(44);
sgear->setPhysicsBody(sgearB);
sgear->setPosition(VisibleRect::leftBottom() + Point(125, 0));
this->addChild(sgear);
@ -946,7 +946,7 @@ void PhysicsDemoPump::onEnter()
this->addChild(pump);
pumpB->setCategoryBitmask(0x02);
pumpB->setGravityEnable(false);
_world->addJoint(PhysicsJointDistance::create(pumpB, sgearB, Point(0, 0), Point(0, -50)));
_world->addJoint(PhysicsJointDistance::create(pumpB, sgearB, Point(0, 0), Point(0, -44)));
// plugger
Point seg[] = {VisibleRect::leftTop() + Point(75, -120), VisibleRect::leftBottom() + Point(75, -100)};
@ -964,7 +964,7 @@ void PhysicsDemoPump::onEnter()
pluggerB->setCategoryBitmask(0x02);
sgearB->setCollisionBitmask(0x04 | 0x01);
_world->addJoint(PhysicsJointPin::create(body, pluggerB, VisibleRect::leftBottom() + Point(75, -90)));
_world->addJoint(PhysicsJointDistance::create(pluggerB, sgearB, pluggerB->world2Local(VisibleRect::leftBottom() + Point(75, 0)), Point(50, 0)));
_world->addJoint(PhysicsJointDistance::create(pluggerB, sgearB, pluggerB->world2Local(VisibleRect::leftBottom() + Point(75, 0)), Point(44, 0)));
}
void PhysicsDemoPump::update(float delta)
@ -1024,7 +1024,6 @@ std::string PhysicsDemoPump::title()
return "Pump";
}
void PhysicsDemoOneWayPlatform::onEnter()
{
PhysicsDemo::onEnter();
@ -1044,7 +1043,17 @@ void PhysicsDemoOneWayPlatform::onEnter()
platform->setPosition(VisibleRect::center());
this->addChild(platform);
this->addChild(makeBall(VisibleRect::center() + Point(0, 50), 5));
auto ball = makeBall(VisibleRect::center() + Point(0, 50), 5);
this->addChild(ball);
auto contactListener = EventListenerPhysicsContactWithBodies::create(platform->getPhysicsBody(), ball->getPhysicsBody());
contactListener->onContactPreSolve = CC_CALLBACK_3(PhysicsDemoOneWayPlatform::onPreSolve, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
}
bool PhysicsDemoOneWayPlatform::onPreSolve(EventCustom* event, const PhysicsContact& contact, const PhysicsContactPreSolve& solve)
{
return true;
}
std::string PhysicsDemoOneWayPlatform::title()

Просмотреть файл

@ -139,6 +139,8 @@ class PhysicsDemoOneWayPlatform : public PhysicsDemo
public:
void onEnter() override;
std::string title() override;
bool onPreSolve(EventCustom* event, const PhysicsContact& contact, const PhysicsContactPreSolve& solve);
};
#endif