Cocos2D-X SimpleGame cocos2d-x如何检测碰撞 (4) ----版本cocos2d-2.0-x-2.0.3 .

本文详细介绍了如何在Cocos2d-x游戏开发中实现怪物与子弹的碰撞检测,包括使用tag进行标识、创建缓存数组追踪游戏元素及碰撞后的处理流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hi,上一节黑衣人终于反击了,但是,敌人却毫发无伤,实在郁闷呢

哈哈,是我们还没打敌人的代码,即碰撞,是不是等不及把敌人消去吗,Ok,开始吧!!

 

首先,跟踪怪物和子弹是必需的。

在游戏中,我们为这两种精灵加以不同的tag来区分它们。当tag=1时,表示这是怪物,而tag=2时,则表示这为子弹。由于在CCNode里面有m_nTag这个成员变量,并且有setTag和getTag方法,因此CCSprite就继承了这些方法,我们可以利用之。

在HelloWorldScene.h中,把以下两个成员变量加入到HelloWorld下,这两个成员变量用于缓存现有的怪物和子弹。

新版本的2.x的版本 CCArray替代了CCMutablArray

protected:

	cocos2d::CCArray* _targers;
	cocos2d::CCArray* _projectiles;

那他们的初始化加在哪里呢?我们可以这么做:

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

	// in init()
	// Initialize arrays
	//实例化数组
	_targers = new CCArray();
	_projectiles = new CCArray();

在析构函数HelloWorld::~HelloWorld()析构

HelloWorld::~HelloWorld()
{
	if (_targers)
	{
		_targers->release();
		_targers = NULL;
	}

	if (_projectiles)
	{
		_projectiles->release();
		_projectiles = NULL;
	}
	
	
}

现在可以修改void HelloWorld::addTarget()这个函数,把新目标添加到目标数组中,并设置其tag为1。

加在 target->runAction(CCSequence::create(actionMove, actionMoveDone, NULL));后面

	target->setTag(1);
	_targers->addObject(target);

修改ccTouchesEnded(),把新子弹加入到子弹数组中,并设置其tag为2。

加在projectile->runAction(CCSequence::create(
  CCMoveTo::create(realMoveDuration, realDest),
  CCCallFuncN::create(this, callfuncN_selector(HelloWorld::spriteMoveFinished)),NULL));后面

	projectile->setTag(2);
	_projectiles->addObject(projectile);

然后,按下面修改spriteMoveFinished()。这里根据标记的不同,在对应的数组中移除精灵

加在this->removeChild(sprite, true);后面

	if (sprite->getTag() == 1)
	{
		_targers->removeObject(sprite);

	}else if (sprite->getTag() == 2)
	{
		_projectiles->removeObject(sprite);
	}

下面的updateGame()函数用于检测每帧的碰撞,并从游戏中删除碰撞中的子弹和怪物。

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

1.x版本 碰撞 CCRectIntersectsRect(projectileRect,targetRect))

2.x版本 碰撞 projectileRect.intersectsRect(targetRect)

 

void HelloWorld::updateGame(float dt)
{
	CCArray* projectilesToDelete = CCArray::create();

	for (unsigned int it=0; it < _projectiles->count(); it++)
	{
		CCSprite* projectile = (CCSprite*)(_projectiles->objectAtIndex(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* targetsToDelete = CCArray::create();

		for (unsigned int jt = 0; jt<_targers->count(); jt++)
		{
			CCSprite* target = (CCSprite*)(_targers->objectAtIndex(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))//::CCRectIntersectsRect(projectileRect,targetRect))
			{
				targetsToDelete->addObject(target);
			}
			
		}

		for (unsigned int jt = 0; jt<targetsToDelete->count(); jt++)
		{
			CCSprite* target = (CCSprite*)(targetsToDelete->objectAtIndex(jt));
			_targers->removeObject(target);
			this->removeChild(target, true);
		}

		if (targetsToDelete->count() >0)
		{
			projectilesToDelete->addObject(projectile);
		}
	}

	for (unsigned int it = 0; it < projectilesToDelete->count(); it++)
	{
		CCSprite* projectile = (CCSprite*)(projectilesToDelete->objectAtIndex(it));
		_projectiles->removeObject(projectile);

		this->removeChild(projectile,true);
	}
}

好了,最后一件事,我们要把update()加入到schedule里让它每帧都能被调用。

有什么错误都可以提出来,希望大家一起进步喔!!

编译并运行项目,尽情地发射子弹吧,现在怪物都被打死了,偶也!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值