猴子原创,欢迎转载。转载请注明: 转载自Cocos2D开发网--Cocos2Dev.com,谢谢!
原文地址: http://www.cocos2dev.com/?p=379
FPS游戏中用的最多的就是子弹了,这几天有不少人问我游戏中如何设计子弹?大量子弹显示的时候,游戏会不会卡?
今天有点时间,我针对这两个问题,简单的写了一个子弹的发射。
效果图:
首先我们来理下如何设计的思路。
一、首先一个简单的关系:子弹肯定是由武器发射的,武器是由人物操作的。
二、也就是说子弹Bullet类只负责创建一个新子弹、子弹的移动和子弹的消失、碰撞。
Bullet类提供给外界接口:增加一个新子弹(以及子弹的速度)。
三、武器weapon类给负责调用Bullet类创建一个新子弹。同时,weapon类也要负责计算发射子弹的速度,以及增加新子弹的时间间隔。
weapon类提供外界借口:开枪(发射子弹)。
四、人物类调用weap类的开枪接口。
OK,简单的整理了下(其实也挺简单的,是吧)。下面开始重要的实现,子弹的实现:
子弹bullet类的职能很单一,只负责创建一个新子弹、子弹的移动和子弹的消失、碰撞。
直接上代码吧:
Bullet.h // // Bullet.h // FireDemo // // Created by LiuYanghui on 13-2-4. // // #ifndef __FireDemo__Bullet__ #define __FireDemo__Bullet__ #include "cocos2d.h" USING_NS_CC; class Bullet : public CCLayer { public: Bullet(); ~Bullet(); CREATE_FUNC(Bullet); virtual bool init(); void addNewBullet();//增加一个新子弹 private: CCSize winSize; CCArray* m_allBulletArray;//保存所有已存在的子弹对象 CCSpriteBatchNode* m_bulletSprite;//使用BatchNode构建所有的子弹,减少gl绘画次数 void initData(); void moveBullet(float dt);//移动子弹 }; #endif /* defined(__FireDemo__Bullet__) */
Bullet.cpp
// // Bullet.cpp // FireDemo // // Created by LiuYanghui on 13-2-4. // // #include "Bullet.h" #define MOVE_SPEED 100 //子弹的速度 #define REMOVE_POSY -768 //子弹消失的位置,根据自己项目定 Bullet::Bullet(){ } Bullet::~Bullet(){ m_allBulletArray->release(); } bool Bullet::init(){ if (!CCLayer::init()) { return false; } initData(); return true; } void Bullet::initData(){ winSize = CCDirector::sharedDirector()->getWinSize(); //创建对象数组,保存已存在的子弹 m_allBulletArray = CCArray::create(); m_allBulletArray->retain(); //子弹贴图 m_bulletSprite = CCSpriteBatchNode::create("bullet.png"); m_bulletSprite->setPosition(CCPointZero); addChild(m_bulletSprite); //更新子弹速度 schedule(schedule_selector(Bullet::moveBullet)); } //增加一个新子弹 void Bullet::addNewBullet(){ //构建一个子弹,添加到BatchNode中。 CCSprite* newBullet = CCSprite::createWithTexture(m_bulletSprite->getTexture()); newBullet->setPosition(CCPointZero); m_bulletSprite->addChild(newBullet); //添加子弹到已存在子弹数组 m_allBulletArray->addObject(newBullet); } //移动子弹 void Bullet::moveBullet(float dt){ //遍历更新每个子弹的位置 for (int i = 0; i < m_allBulletArray->count(); ++i) { //获取一个子弹对象 CCSprite* bullet = (CCSprite*)m_allBulletArray->objectAtIndex(i); //更新位置 bullet->setPositionY(bullet->getPositionY()-MOVE_SPEED*dt); //如果已到达消失位置,就移除该子弹 if (bullet->getPositionY() <= REMOVE_POSY) { m_allBulletArray->removeObjectAtIndex(i); m_bulletSprite->removeChild(bullet, true); } } }
子弹生成了,现在写个简单的调用场景吧。
GameScene.h
// // GameScene.h // FireDemo // // Created by LiuYanghui on 13-2-4. // // #ifndef __FireDemo__GameScene__ #define __FireDemo__GameScene__ #include "cocos2d.h" USING_NS_CC; class Bullet; class GameScene : public CCLayer { public: GameScene(); ~GameScene(); CREATE_FUNC(GameScene); static CCScene* scene(); virtual bool init(); virtual void registerWithTouchDispatcher(void); virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent); private: CCSize winSize; Bullet* m_bullet; void initData(); }; #endif /* defined(__FireDemo__GameScene__) */
GameScene.cpp
// // GameScene.cpp // FireDemo // // Created by LiuYanghui on 13-2-4. // // #include "GameScene.h" #include "Bullet.h" GameScene::GameScene(){ } GameScene::~GameScene(){ } CCScene* GameScene::scene(){ CCScene* scene = CCScene::create(); GameScene* layer = GameScene::create(); scene->addChild(layer); return scene; } bool GameScene::init(){ if (!CCLayer::init()) { return false; } initData(); return true; } void GameScene::initData(){ winSize = CCDirector::sharedDirector()->getWinSize(); CCSprite* mainBg = CCSprite::create("bg.jpg"); mainBg->setPosition(ccp(winSize.width*.5,winSize.height*.5)); addChild(mainBg); CCSprite* tank = CCSprite::create("tank.png"); tank->setPosition(ccp(winSize.width*.5,winSize.height*.8)); addChild(tank); //创建子弹对象 m_bullet = Bullet::create(); m_bullet->setPosition(winSize.width*.5,winSize.height*.8); addChild(m_bullet); setTouchEnabled(true); } void GameScene::registerWithTouchDispatcher(void){ CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true); } bool GameScene::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) { //每次点击添加一个新子弹 m_bullet->addNewBullet(); return true; } void GameScene::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) { } void GameScene::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) { } void GameScene::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent) { }
好了,一个简单的点击屏幕发射子弹就出来了。这里只是提供了一个思路,具体的开发就自己去做了。