微信经典飞机大战之四:子弹层的完全解析

飞机发射子弹在子弹层需要处理以下几个方面:

1.子弹的渲染效果

2.子弹的初始位置和飞行效果

3.子弹的管理和回收

4.子弹层提供的其他接口

这节,我们就从这四个方面来完全解析子弹层。


1.子弹的渲染效果

子弹的添加和渲染,我们采用CCSpriteBatchNode,因为批次渲染只要1次就可以完成了。

bool BulletLayer::init()
{
	bool bRet=false;
	do
	{
		CC_BREAK_IF(!CCLayer::init());

		CCTexture2D* texture = CCTextureCache::sharedTextureCache()->textureForKey("ui/shoot.png");
		bulletBatchNode = CCSpriteBatchNode::createWithTexture(texture);
		this->addChild(bulletBatchNode);

		bRet=true;
	} while (0);
	return bRet;
}

void BulletLayer::AddBullet(float dt)
{
	CCSprite* bullet = CCSprite::createWithSpriteFrameName("bullet1.png");
	bulletBatchNode->addChild(bullet); //这里就是把子弹添加到bulletBatchNode中
        //this->addChild(bullet);  换成这句就是普通的渲染
}

然后我们调用

this->schedule(schedule_selector(BulletLayer::AddBullet),0.01f); 

这里时间间隔设置为0.01秒,子弹看起来是柱状的,后续我们会详细分析。


2.子弹的初始位置

子弹的初始位置在飞机的机头位置,但是飞机在游戏的过程会随着玩家的触摸而不断的改变位置,因此,子弹的初始位置应该以飞机的实时位置为基准而进行添加。

	//子弹的初始位置
	CCPoint planePosition = PlaneLayer::sharedPlane->getChildByTag(AIRPLANE)->getPosition();
	CCPoint bulletPosition = ccp(planePosition.x, planePosition.y + PlaneLayer::sharedPlane->getChildByTag(AIRPLANE)->getContentSize().height/2);
	bullet->setPosition(bulletPosition);

3.子弹的飞行效果

子弹的飞行效果,就是X方向不变,Y方向移动。而且子弹一旦发射,就是一个独立的个体,不能再随着飞机的移动而移动。而且每颗子弹的初始Y也不一定一样,所以得先计算出每颗子弹的运动时间。

	float length=CCDirector::sharedDirector()->getWinSize().height+bullet->getContentSize().height/2-bulletPosition.y; //飞行距离,超出屏幕即结束
	float velocity=320/1; //飞行速度:320pixel/sec
	float realMoveDuration=length/velocity; //飞行时间

	CCFiniteTimeAction* actionMove=CCMoveTo::create(realMoveDuration,ccp(bulletPosition.x,CCDirector::sharedDirector()->getWinSize().height+bullet->getContentSize().height/2));
	CCFiniteTimeAction* actionDone=CCCallFuncN::create(this,callfuncN_selector(BulletLayer::bulletMoveFinished)); //回调一个子弹结束处理函数

	CCSequence* sequence=CCSequence::create(actionMove,actionDone,NULL);
	bullet->runAction(sequence);

4.子弹的管理和回收

我们利用cocos2d-x提供的一个数组类CCArray,来管理我们创建出来的一些精灵。而且在我们不需要的时候,可以从中删除它并且从屏幕上删除它。

需要注意的是,因为CCArray::create函数调用了autoRelease,所以我们必须在调用创建后,手动进行retain,以免超出使用范围后被释放,同时在析构函数中再进行release防止内存泄露。

(1)创建CCArray成员变量指针,用来管理子弹

	CCArray* m_pAllBullet;

(2)子弹层的构造函数和析构函数

BulletLayer::BulletLayer(void)
{
	bulletBatchNode=NULL;
	m_pAllBullet=CCArray::create();
	m_pAllBullet->retain();
}

BulletLayer::~BulletLayer(void)
{
	m_pAllBullet->release();
	m_pAllBullet=NULL;
}

(3)子弹的回收:子弹飞出屏幕后的调用函数

void BulletLayer::bulletMoveFinished(CCNode* pSender)
{
	CCSprite* bullet=(CCSprite*)pSender;
	this->bulletBatchNode->removeChild(bullet,true); //移除屏幕
	m_pAllBullet->removeObject(bullet); //移除CCArray
	
}


5.子弹层的其他接口

(1)开始发射子弹

//开始发射子弹
void BulletLayer::StartShoot(float delay)
{
	this->schedule(schedule_selector(BulletLayer::AddBullet),0.20f,kCCRepeatForever,delay);
}

(2)停止发射子弹

//停止发射子弹
void BulletLayer::StopShoot()  //卸载任务执行器
{
	this->unschedule(schedule_selector(BulletLayer::AddBullet));
}

(3)删除某颗子弹

//删除某颗子弹
void BulletLayer::RemoveBullet(CCSprite* bullet) //一旦子弹和敌机碰撞,我们就要删掉这个子弹
{
	if(bullet!=NULL)
	{
		this->bulletBatchNode->removeChild(bullet,true);
		this->m_pAllBullet->removeObject(bullet);
		
	}
}

子弹层已解析完毕,接着我们把子弹层加入GameLayer层的init函数中,并执行开始发射子弹,看看效果如何。

		//加入bulletLayer
		this->bulletLayer=BulletLayer::create();
		this->addChild(bulletLayer);
		this->bulletLayer->StartShoot();








你可能感兴趣的:(微信经典飞机大战)