mirror of https://github.com/axmolengine/axmol.git
Merge pull request #5312 from dumganhar/merge5268
closed #3716:PhysicsContact should be inherited from EventCustom, it will simplify the logic of emitting collision events
This commit is contained in:
commit
e90e0b0c23
|
@ -37,7 +37,7 @@ NS_CC_BEGIN
|
|||
const char* PHYSICSCONTACT_EVENT_NAME = "PhysicsContactEvent";
|
||||
|
||||
PhysicsContact::PhysicsContact()
|
||||
: Event(Event::Type::CUSTOM)
|
||||
: EventCustom(PHYSICSCONTACT_EVENT_NAME)
|
||||
, _world(nullptr)
|
||||
, _shapeA(nullptr)
|
||||
, _shapeB(nullptr)
|
||||
|
@ -200,32 +200,37 @@ bool EventListenerPhysicsContact::init()
|
|||
|
||||
void EventListenerPhysicsContact::onEvent(EventCustom* event)
|
||||
{
|
||||
PhysicsContact& contact = *(PhysicsContact*)(event->getUserData());
|
||||
PhysicsContact* contact = dynamic_cast<PhysicsContact*>(event);
|
||||
|
||||
switch (contact.getEventCode())
|
||||
if (contact == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (contact->getEventCode())
|
||||
{
|
||||
case PhysicsContact::EventCode::BEGIN:
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
if (onContactBegin != nullptr
|
||||
&& hitTest(contact.getShapeA(), contact.getShapeB()))
|
||||
&& hitTest(contact->getShapeA(), contact->getShapeB()))
|
||||
{
|
||||
contact._begin = true;
|
||||
contact.generateContactData();
|
||||
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);
|
||||
ret = onContactBegin(*contact);
|
||||
}else
|
||||
{
|
||||
onContactBegin(event, contact);
|
||||
onContactBegin(*contact);
|
||||
}
|
||||
}
|
||||
|
||||
contact.setResult(ret);
|
||||
contact->setResult(ret);
|
||||
break;
|
||||
}
|
||||
case PhysicsContact::EventCode::PRESOLVE:
|
||||
|
@ -233,34 +238,34 @@ void EventListenerPhysicsContact::onEvent(EventCustom* event)
|
|||
bool ret = true;
|
||||
|
||||
if (onContactPreSolve != nullptr
|
||||
&& hitTest(contact.getShapeA(), contact.getShapeB()))
|
||||
&& hitTest(contact->getShapeA(), contact->getShapeB()))
|
||||
{
|
||||
PhysicsContactPreSolve solve(contact._begin ? nullptr : contact._contactData, contact._contactInfo);
|
||||
contact._begin = false;
|
||||
contact.generateContactData();
|
||||
PhysicsContactPreSolve solve(contact->_begin ? nullptr : contact->_contactData, contact->_contactInfo);
|
||||
contact->_begin = false;
|
||||
contact->generateContactData();
|
||||
|
||||
ret = onContactPreSolve(event, contact, solve);
|
||||
ret = onContactPreSolve(*contact, solve);
|
||||
}
|
||||
|
||||
contact.setResult(ret);
|
||||
contact->setResult(ret);
|
||||
break;
|
||||
}
|
||||
case PhysicsContact::EventCode::POSTSOLVE:
|
||||
{
|
||||
if (onContactPostSolve != nullptr
|
||||
&& hitTest(contact.getShapeA(), contact.getShapeB()))
|
||||
&& hitTest(contact->getShapeA(), contact->getShapeB()))
|
||||
{
|
||||
PhysicsContactPostSolve solve(contact._contactInfo);
|
||||
onContactPostSolve(event, contact, solve);
|
||||
PhysicsContactPostSolve solve(contact->_contactInfo);
|
||||
onContactPostSolve(*contact, solve);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PhysicsContact::EventCode::SEPERATE:
|
||||
{
|
||||
if (onContactSeperate != nullptr
|
||||
&& hitTest(contact.getShapeA(), contact.getShapeB()))
|
||||
&& hitTest(contact->getShapeA(), contact->getShapeB()))
|
||||
{
|
||||
onContactSeperate(event, contact);
|
||||
onContactSeperate(*contact);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "CCGeometry.h"
|
||||
#include "CCEventListenerCustom.h"
|
||||
#include "CCEvent.h"
|
||||
#include "CCEventCustom.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -58,7 +59,7 @@ 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 : public Event
|
||||
class PhysicsContact : public EventCustom
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -201,20 +202,20 @@ public:
|
|||
/*
|
||||
* @brief it will called at two shapes start to contact, and only call it once.
|
||||
*/
|
||||
std::function<bool(EventCustom* event, const PhysicsContact& contact)> onContactBegin;
|
||||
std::function<bool(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(EventCustom* event, const PhysicsContact& contact, const PhysicsContactPreSolve& solve)> onContactPreSolve;
|
||||
std::function<bool(PhysicsContact& contact, 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(EventCustom* event, const PhysicsContact& contact, const PhysicsContactPostSolve& solve)> onContactPostSolve;
|
||||
std::function<void(PhysicsContact& contact, const PhysicsContactPostSolve& solve)> onContactPostSolve;
|
||||
/*
|
||||
* @brief it will called at two shapes separated, and only call it once.
|
||||
* onContactBegin and onContactSeperate will called in pairs.
|
||||
*/
|
||||
std::function<void(EventCustom* event, const PhysicsContact& contact)> onContactSeperate;
|
||||
std::function<void(PhysicsContact& contact)> onContactSeperate;
|
||||
|
||||
protected:
|
||||
bool init();
|
||||
|
|
|
@ -283,9 +283,7 @@ int PhysicsWorld::collisionBeginCallback(PhysicsContact& contact)
|
|||
|
||||
contact.setEventCode(PhysicsContact::EventCode::BEGIN);
|
||||
contact.setWorld(this);
|
||||
EventCustom event(PHYSICSCONTACT_EVENT_NAME);
|
||||
event.setUserData(&contact);
|
||||
_scene->getEventDispatcher()->dispatchEvent(&event);
|
||||
_scene->getEventDispatcher()->dispatchEvent(&contact);
|
||||
|
||||
return ret ? contact.resetResult() : false;
|
||||
}
|
||||
|
@ -300,9 +298,7 @@ int PhysicsWorld::collisionPreSolveCallback(PhysicsContact& contact)
|
|||
|
||||
contact.setEventCode(PhysicsContact::EventCode::PRESOLVE);
|
||||
contact.setWorld(this);
|
||||
EventCustom event(PHYSICSCONTACT_EVENT_NAME);
|
||||
event.setUserData(&contact);
|
||||
_scene->getEventDispatcher()->dispatchEvent(&event);
|
||||
_scene->getEventDispatcher()->dispatchEvent(&contact);
|
||||
|
||||
return contact.resetResult();
|
||||
}
|
||||
|
@ -316,9 +312,7 @@ void PhysicsWorld::collisionPostSolveCallback(PhysicsContact& contact)
|
|||
|
||||
contact.setEventCode(PhysicsContact::EventCode::POSTSOLVE);
|
||||
contact.setWorld(this);
|
||||
EventCustom event(PHYSICSCONTACT_EVENT_NAME);
|
||||
event.setUserData(&contact);
|
||||
_scene->getEventDispatcher()->dispatchEvent(&event);
|
||||
_scene->getEventDispatcher()->dispatchEvent(&contact);
|
||||
}
|
||||
|
||||
void PhysicsWorld::collisionSeparateCallback(PhysicsContact& contact)
|
||||
|
@ -330,9 +324,7 @@ void PhysicsWorld::collisionSeparateCallback(PhysicsContact& contact)
|
|||
|
||||
contact.setEventCode(PhysicsContact::EventCode::SEPERATE);
|
||||
contact.setWorld(this);
|
||||
EventCustom event(PHYSICSCONTACT_EVENT_NAME);
|
||||
event.setUserData(&contact);
|
||||
_scene->getEventDispatcher()->dispatchEvent(&event);
|
||||
_scene->getEventDispatcher()->dispatchEvent(&contact);
|
||||
}
|
||||
|
||||
void PhysicsWorld::rayCast(PhysicsRayCastCallbackFunc func, const Point& point1, const Point& point2, void* data)
|
||||
|
|
|
@ -1175,11 +1175,10 @@ static int tolua_cocos2dx_EventListenerPhysicsContact_registerScriptHandler(lua_
|
|||
{
|
||||
ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, type);
|
||||
|
||||
self->onContactBegin = [handler](EventCustom* event, const PhysicsContact& contact) -> bool{
|
||||
self->onContactBegin = [handler](PhysicsContact& contact) -> bool{
|
||||
LuaStack* stack = LuaEngine::getInstance()->getLuaStack();
|
||||
stack->pushObject(event, "cc.EventCustom");
|
||||
stack->pushObject(const_cast<PhysicsContact*>(&contact), "cc.PhysicsContact");
|
||||
bool ret = stack->executeFunctionByHandler(handler, 2);
|
||||
stack->pushObject(&contact, "cc.PhysicsContact");
|
||||
bool ret = stack->executeFunctionByHandler(handler, 1);
|
||||
stack->clean();
|
||||
|
||||
return ret;
|
||||
|
@ -1190,12 +1189,11 @@ static int tolua_cocos2dx_EventListenerPhysicsContact_registerScriptHandler(lua_
|
|||
{
|
||||
ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, type);
|
||||
|
||||
self->onContactPreSolve = [handler](EventCustom* event, const PhysicsContact& contact, const PhysicsContactPreSolve& solve) -> bool{
|
||||
self->onContactPreSolve = [handler](PhysicsContact& contact, PhysicsContactPreSolve& solve) -> bool{
|
||||
LuaStack* stack = LuaEngine::getInstance()->getLuaStack();
|
||||
stack->pushObject(event, "cc.EventCustom");
|
||||
stack->pushObject(const_cast<PhysicsContact*>(&contact), "cc.PhysicsContact");
|
||||
tolua_pushusertype(stack->getLuaState(), const_cast<PhysicsContactPreSolve*>(&solve), "cc.PhysicsContactPreSolve");
|
||||
bool ret = stack->executeFunctionByHandler(handler, 3);
|
||||
stack->pushObject(&contact, "cc.PhysicsContact");
|
||||
tolua_pushusertype(stack->getLuaState(), &solve, "cc.PhysicsContactPreSolve");
|
||||
bool ret = stack->executeFunctionByHandler(handler, 2);
|
||||
stack->clean();
|
||||
|
||||
return ret;
|
||||
|
@ -1206,12 +1204,11 @@ static int tolua_cocos2dx_EventListenerPhysicsContact_registerScriptHandler(lua_
|
|||
{
|
||||
ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, type);
|
||||
|
||||
self->onContactPostSolve = [handler](EventCustom* event, const PhysicsContact& contact, const PhysicsContactPostSolve& solve){
|
||||
self->onContactPostSolve = [handler](PhysicsContact& contact, const PhysicsContactPostSolve& solve){
|
||||
LuaStack* stack = LuaEngine::getInstance()->getLuaStack();
|
||||
stack->pushObject(event, "cc.EventCustom");
|
||||
stack->pushObject(const_cast<PhysicsContact*>(&contact), "cc.PhysicsContact");
|
||||
stack->pushObject(&contact, "cc.PhysicsContact");
|
||||
tolua_pushusertype(stack->getLuaState(), const_cast<PhysicsContactPostSolve*>(&solve), "cc.PhysicsContactPostSolve");
|
||||
stack->executeFunctionByHandler(handler, 3);
|
||||
stack->executeFunctionByHandler(handler, 2);
|
||||
stack->clean();
|
||||
};
|
||||
}
|
||||
|
@ -1220,11 +1217,10 @@ static int tolua_cocos2dx_EventListenerPhysicsContact_registerScriptHandler(lua_
|
|||
{
|
||||
ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, type);
|
||||
|
||||
self->onContactSeperate = [handler](EventCustom* event, const PhysicsContact& contact){
|
||||
self->onContactSeperate = [handler](PhysicsContact& contact){
|
||||
LuaStack* stack = LuaEngine::getInstance()->getLuaStack();
|
||||
stack->pushObject(event, "cc.EventCustom");
|
||||
stack->pushObject(const_cast<PhysicsContact*>(&contact), "cc.PhysicsContact");
|
||||
stack->executeFunctionByHandler(handler, 2);
|
||||
stack->pushObject(&contact, "cc.PhysicsContact");
|
||||
stack->executeFunctionByHandler(handler, 1);
|
||||
stack->clean();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1101,11 +1101,11 @@ void PhysicsDemoOneWayPlatform::onEnter()
|
|||
this->addChild(ball);
|
||||
|
||||
auto contactListener = EventListenerPhysicsContactWithBodies::create(platform->getPhysicsBody(), ball->getPhysicsBody());
|
||||
contactListener->onContactBegin = CC_CALLBACK_2(PhysicsDemoOneWayPlatform::onContactBegin, this);
|
||||
contactListener->onContactBegin = CC_CALLBACK_1(PhysicsDemoOneWayPlatform::onContactBegin, this);
|
||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
|
||||
}
|
||||
|
||||
bool PhysicsDemoOneWayPlatform::onContactBegin(EventCustom* event, const PhysicsContact& contact)
|
||||
bool PhysicsDemoOneWayPlatform::onContactBegin(PhysicsContact& contact)
|
||||
{
|
||||
return contact.getContactData()->normal.y < 0;
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ public:
|
|||
void onEnter() override;
|
||||
virtual std::string title() const override;
|
||||
|
||||
bool onContactBegin(EventCustom* event, const PhysicsContact& contact);
|
||||
bool onContactBegin(PhysicsContact& contact);
|
||||
};
|
||||
|
||||
class PhysicsDemoSlice : public PhysicsDemo
|
||||
|
|
|
@ -702,7 +702,7 @@ local function PhysicsDemoOneWayPlatform()
|
|||
ball:getPhysicsBody():setMass(1.0);
|
||||
layer:addChild(ball);
|
||||
|
||||
local function onContactBegin(event, contact)
|
||||
local function onContactBegin(contact)
|
||||
return contact:getContactData().normal.y < 0;
|
||||
end
|
||||
local contactListener = cc.EventListenerPhysicsContactWithBodies:create(platform:getPhysicsBody(), ball:getPhysicsBody());
|
||||
|
|
Loading…
Reference in New Issue