[置顶] 【amazing cocos2d-x 3.0之十七】使用新物理引擎实现碰撞检测

如果上一篇文章,你看懂了,那么这篇文章,相信对你应该问题不大,会有一个实例提高。

我们要实现的是,让车和猫产生碰撞,碰撞之后猫消失。先上图:



1. 创建具有物理世界的场景scene


经过前一篇文章的介绍,你对于创建具有物理世界的场景应该不陌生了,HelloWorldScene.cpp的createScene()方法如下:

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
	auto scene = Scene::createWithPhysics();

	scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);

	Vect gravity = Vect(0.0f, 0.0f);
	scene->getPhysicsWorld()->setGravity(gravity);

    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

	layer->setPhyWorld(scene->getPhysicsWorld());

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

2. 使用SpriteBachNode添加我们的精灵


如果对SpriteBachNode不熟悉的话,请先看这篇文章:http://blog.csdn.net/legendof1991/article/details/21991873

首先,我们来创建一个项目,将原有的代码都删除掉。

在HelloWorldScene.h中添加成员变量:

SpriteBatchNode* _spriteSheet;

然后在HelloWorldScene.cpp中的init()方法来加载我们的SpriteBatchNode和plist文件,代码如下:

bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }

    //第二个参数“2”代表图片sprite.png中有两个精灵
    _spriteSheet = SpriteBatchNode::create("sprites.png", 2);
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile("sprites.plist", "sprites.png");
    this->addChild(_spriteSheet);
    this->spawnCar();
    this->schedule(schedule_selector(HelloWorld::secondUpadte), 1.0f);

    return true;
}

接下来,我们来实现spawnCar方法。我们让车子刚开始先做一个直接移动,然后永远地在屏幕左下角做路径为三角形的行动。添加代码如下:

void HelloWorld::spawnCar()
{
    SpriteFrame* frame = SpriteFrameCache::getInstance()->spriteFrameByName("car.png");
    Sprite* car = Sprite::createWithSpriteFrame(frame);
    car->setPosition(Point(100, 100));
    addBoxBodyForSprite(car);
    car->setTag(2);
    car->runAction(MoveTo::create(1.0f, Point(300, 300)));
    car->runAction(RepeatForever::create(Sequence::create(MoveTo::create(1.0,Point(300, 100)),MoveTo::create(1.0,Point(200, 200)),MoveTo::create(1.0,Poin(100, 100)),NULL)));
    _spriteSheet->addChild(car);
}

紧接着,我们来添加精灵猫。

void HelloWorld::spawnCat()
{
    auto winSize = Director::getInstance()->getWinSize();

    auto cat = Sprite::createWithSpriteFrameName("cat.png");

    int minY = cat->getContentSize().height / 2;
    int maxY = winSize.height - (cat->getContentSize().height / 2);
    int rangeY = maxY - minY;
    int actualY = CCRANDOM_0_1() * rangeY;

    int startX = winSize.width + (cat->getContentSize().width / 2);
    int endX = -(cat->getContentSize().width / 2);

    Point startPos = Point(startX, actualY);
    Point endPos = Point(endX, actualY);

    cat->setPosition(startPos);
    addBoxBodyForSprite(cat);
    cat->setTag(1);
    cat->runAction(Sequence::create(MoveTo::create(1.0, endPos), CallFuncN::create(this, callfuncN_selector(HelloWorld::spriteDone)),NULL));

    _spriteSheet->addChild(cat);

}

void HelloWorld::secondUpadte(float dt)
{
    this->spawnCat();
}

void HelloWorld::spriteDone(Node* sender)
{
    Sprite *sprite = (Sprite*)sender;
    _spriteSheet->removeChild(sprite,true);
}

3. 添加碰撞检测


在这里,我们将来添加碰撞检测代码:

void HelloWorld::onEnter()
{
    Layer::onEnter();

    auto contactListener = EventListenerPhysicsContact::create();
    contactListener->onContactBegin = CC_CALLBACK_2(HelloWorld::onContactBegin, this);

    auto dispatcher = Director::getInstance()->getEventDispatcher();

    dispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
}

bool HelloWorld::onContactBegin(EventCustom* event, const PhysicsContact& contact)
{
    auto spriteA = (Sprite*)contact.getShapeA()->getBody()->getNode();
    auto spriteB = (Sprite*)contact.getShapeB()->getBody()->getNode();

    if (spriteA->getTag() == 1)
    {
        spriteA->removeFromParentAndCleanup(true);
    }

    if (spriteB->getTag() == 1)
    {
        spriteB->removeFromParentAndCleanup(true);
    }

    return true;
}

相信这篇结合上一篇,这样对cocos2d-x 3.0中新的物理碰撞机制就有了更加深入的了解。

你可能感兴趣的:(box2D,碰撞检测,chipmunk,物理引擎,cocos2d-x3.0)