Cocos2d-x 游戏中子弹的设计(一)

发表于2016-01-31
评论1 764浏览
  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)  
{   
}  
  好了,一个简单的点击屏幕发射子弹就出来了。这里只是提供了一个思路,具体的开发就自己去做了。

  加入GAD的核心用户QQ群:484290331,各类活动奖励任你拿,最新资讯任你读,众多教学任你免费学,如此好地方赶紧加入吧!另VR专属群:476511561,专业VR技术分享,专业导师指导为你答疑解惑,大型小型活动奖励等你拿,免费学习赚奖励的天地,欢迎你加入哟!

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论