您的位置:首页 > 移动开发 > Cocos引擎

cocos2dx碰撞检测实现

2016-04-21 13:19 429 查看
本文由qinning199原创,转载请注明:http://www.cocos2dx.net/?p=146

在此场景中,我们假设有很多敌人和子弹,其中子弹可以击中敌人,并且碰撞后子弹和敌人都会随之消失。

首先,我们需要去追踪这些敌人和子弹。

我们可以为这两种物体添加tag,在这里我们给敌人添加tag=1,给子弹添加tag=2,。因为CCSprite继承自CCNode,因为已经有了setTag和getTag方法;我们可以通过这种方式来区分不同的精灵。

添加两个成员对象在HelloWorldScene.h中。用来分别存储存在的敌人和子弹。

[cpp] view
plain copy

protected:

cocos2d::CCArray *_targets;

cocos2d::CCArray *_projectiles;

在cocos2dx中,在构造函数中初始化这两个变量,在init()函数中new,在析构函数中release。

[cpp] view
plain copy

// 初始化

_targets = new CCArray;

_projectiles = new CCArray;

HelloWorld::~HelloWorld()

{

if (_targets)

{

_targets->release();

_targets = NULL;

}

if (_projectiles)

{

_projectiles->release();

_projectiles = NULL;

}

// cpp不需要调用super释放,虚析构函数将会做这些事

}

HelloWorld::HelloWorld()

:_targets(NULL)

,_projectiles(NULL)

{

}

现在更改addTarget()来添加一个新的敌人到targets数组中,并且把它的tag设置为1.

[cpp] view
plain copy

// 添加到数组中

target->setTag(1);

_targets->addObject(target);

更改一下ccTouchesEnded()来添加一个新的子弹到bullets数组中,并且设置它的tag为2.

[cpp] view
plain copy

// 添加到_projectiles数组中

projectile->setTag(2);

_projectiles->addObject(projectile);

接下来,更改如下的spriteMoveFinished()函数。这里我们将从相应的数组中移除一些精灵。

[cpp] view
plain copy

void HelloWorld::spriteMoveFinished(CCNode* sender)

{

CCSprite *sprite = (CCSprite *)sender;

this->removeChild(sprite, true);

if (sprite->getTag() == 1) // target

{

_targets->removeObject(sprite);

}

else if (sprite->getTag() == 2) // projectile

{

_projectiles->removeObject(sprite);

}

}

下面的函数update()将会每帧被执行到一次,一般用来检测碰撞检测,可以移除掉碰撞的子弹和敌人。

在HelloWorldScene.h中声明它,在HelloWorldScene.cpp.定义它。

[cpp] view
plain copy

void HelloWorld::update(float dt)

{

CCArray *projectilesToDelete = new CCArray;

CCArray* targetsToDelete =new CCArray;

CCObject* it = NULL;

CCObject* jt = NULL;

CCARRAY_FOREACH(_bullet, it)

{

CCSprite *projectile = dynamic_cast<CCSprite*>(it);

CCRect projectileRect = CCRectMake(

projectile->getPosition().x - (projectile->getContentSize().width/2),

projectile->getPosition().y - (projectile->getContentSize().height/2),

projectile->getContentSize().width,

projectile->getContentSize().height);

CCARRAY_FOREACH(_target, jt)

{

CCSprite *target = dynamic_cast<CCSprite*>(jt);

CCRect targetRect = CCRectMake(

target->getPosition().x - (target->getContentSize().width/2),

target->getPosition().y - (target->getContentSize().height/2),

target->getContentSize().width,

target->getContentSize().height);

if (projectileRect.intersectsRect(targetRect))

{

targetsToDelete->addObject(target);

projectilesToDelete->addObject(projectile);

}

}

}

CCARRAY_FOREACH(targetsToDelete, jt)

{

CCSprite *target = dynamic_cast<CCSprite*>(jt);

_target->removeObject(target);

this->removeChild(target, true);

}

CCARRAY_FOREACH(projectilesToDelete, it)

{

CCSprite* projectile = dynamic_cast<CCSprite*>(it);

_bullet->removeObject(projectile);

this->removeChild(projectile, true);

}

projectilesToDelete->release();

targetsToDelete->release();

好了,最后的事情我们将要做的就是添加update()到计时器中,来让它每帧被调用一次,一般在onEnter()函数中添加此行代码。

[cpp] view
plain copy

void HelloWorld::onEnter()

{

CCLayer::onEnter();

this->schedule( schedule_selector(HelloWorld::update) );

}

一个简单的碰撞检测模型就建立好啦~

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: