说明
看了N篇文章都没有设置应该怎么检测碰撞,经过不懈的努力下终于成功,特此记下。
效果预览
新建工程
我这里新建一个新的工程,名字叫做Test_Phy
,将HelloWorld
增加物理引擎
开启重力引擎
Scene* HelloWorld::createScene()
{
// 'scene' is an autorelease object
// auto scene = Scene::create();
auto scene = Scene::createWithPhysics();
scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
// 'layer' is an autorelease object
auto layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
layer->setPhyWorld(scene->getPhysicsWorld());
Size visibleSize = Director::getInstance()->getVisibleSize();
// 添加一个边界
auto body = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3);
auto edgeNode = Node::create();
edgeNode->setPosition(Point(visibleSize.width/2,visibleSize.height/2));
edgeNode->setPhysicsBody(body);
scene->addChild(edgeNode);
// return the scene
return scene;
}
增加点击事件
在bool HelloWorld::init()
添加点击事件,这里需要重写onTouchBegan
和onTouchEnded
两个函数
// new way to enable touch
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
touchListener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
onTouchBegan
和onTouchEnded
两个函数的格式
bool HelloWorld::onTouchBegan(Touch *touch, Event *unused_event)
{
return true;
}
void HelloWorld::onTouchEnded(Touch *touch, Event *unused_event)
{
auto location = touch->getLocation();
// 添加新精灵
addNewSpriteAtPosition(location);
}
void HelloWorld::addNewSpriteAtPosition(Point p)
{
static int tag = 1;
auto sprite = Sprite::create("CloseNormal.png");
sprite->setTag(++tag);
auto body = PhysicsBody::createCircle(sprite->getContentSize().width / 2);
body->setCategoryBitmask(tag); // 表示“我是谁”
body->setContactTestBitmask(-1); // 表示“在我和谁发生碰撞通知我”,是否调用我注册的回调函数。
body->setCollisionBitmask(-1); // 表示”我和谁发生碰撞“
// 如果a->CategoryBitmask & b->CollisionBitmask等于0或者b->CategoryBitmask & a->CollisionBitmask等于0,不发生碰撞,可以看到物体穿越另一个物体。
sprite->setPhysicsBody(body);
sprite->setPosition(p);
this->addChild(sprite);
}
上面我就可以点一下就创建一个新的含有重力的精灵了。
注册碰撞事件
auto contactListener = EventListenerPhysicsContact::create();
// 方法1
contactListener->onContactBegin = CC_CALLBACK_1(HelloWorld::onContactBegin, this);
// 方法2 他们两个效果等同
//contactListener->onContactBegin = [this](PhysicsContact& contact)
//{
// CCLOG("A=%d B=%d", contact.getShapeA()->getBody()->getNode()->getTag() , contact.getShapeB()->getBody()->getNode()->getTag());
// return true;
//};
// _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(contactListener,this);
bool HelloWorld::onContactBegin(const PhysicsContact& contact)
{
CCLOG("A=%d B=%d", contact.getShapeA()->getBody()->getNode()->getTag() , contact.getShapeB()->getBody()->getNode()->getTag());
return true;
}