飞机发射子弹在子弹层需要处理以下几个方面:
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();