飞机发射子弹在子弹层需要处理以下几个方面:
1.子弹的渲染效果
2.子弹的初始位置和飞行效果
3.子弹的管理和回收
4.子弹层提供的其他接口
这节,我们就从这四个方面来完全解析子弹层。
子弹的添加和渲染,我们采用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);
子弹的初始位置在飞机的机头位置,但是飞机在游戏的过程会随着玩家的触摸而不断的改变位置,因此,子弹的初始位置应该以飞机的实时位置为基准而进行添加。
//子弹的初始位置
CCPoint planePosition = PlaneLayer::sharedPlane->getChildByTag(AIRPLANE)->getPosition();
CCPoint bulletPosition = ccp(planePosition.x, planePosition.y + PlaneLayer::sharedPlane->getChildByTag(AIRPLANE)->getContentSize().height/2);
bullet->setPosition(bulletPosition);
子弹的飞行效果,就是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);
我们利用cocos2d-x提供的一个数组类CCArray,来管理我们创建出来的一些精灵。而且在我们不需要的时候,可以从中删除它并且从屏幕上删除它。
需要注意的是,因为CCArray::create函数调用了autoRelease,所以我们必须在调用创建后,手动进行retain,以免超出使用范围后被释放,同时在析构函数中再进行release防止内存泄露。
(1)创建CCArray成员变量指针,用来管理子弹
CCArray* m_pAllBullet;
BulletLayer::BulletLayer(void)
{
bulletBatchNode=NULL;
m_pAllBullet=CCArray::create();
m_pAllBullet->retain();
}
BulletLayer::~BulletLayer(void)
{
m_pAllBullet->release();
m_pAllBullet=NULL;
}
void BulletLayer::bulletMoveFinished(CCNode* pSender)
{
CCSprite* bullet=(CCSprite*)pSender;
this->bulletBatchNode->removeChild(bullet,true); //移除屏幕
m_pAllBullet->removeObject(bullet); //移除CCArray
}
(1)开始发射子弹
//开始发射子弹
void BulletLayer::StartShoot(float delay)
{
this->schedule(schedule_selector(BulletLayer::AddBullet),0.20f,kCCRepeatForever,delay);
}
//停止发射子弹
void BulletLayer::StopShoot() //卸载任务执行器
{
this->unschedule(schedule_selector(BulletLayer::AddBullet));
}
//删除某颗子弹
void BulletLayer::RemoveBullet(CCSprite* bullet) //一旦子弹和敌机碰撞,我们就要删掉这个子弹
{
if(bullet!=NULL)
{
this->bulletBatchNode->removeChild(bullet,true);
this->m_pAllBullet->removeObject(bullet);
}
}
//加入bulletLayer
this->bulletLayer=BulletLayer::create();
this->addChild(bulletLayer);
this->bulletLayer->StartShoot();