猴子原创,欢迎转载。转载请注明: 转载自Cocos2D开发网--Cocos2Dev.com,谢谢!
原文地址: http://www.cocos2dev.com/?p=379
FPS游戏中用的最多的就是子弹了,这几天有不少人问我游戏中如何设计子弹?大量子弹显示的时候,游戏会不会卡?
今天有点时间,我针对这两个问题,简单的写了一个子弹的发射。
效果图:
![](https://img-my.csdn.net/uploads/201302/04/1359971517_4890.jpg)
首先我们来理下如何设计的思路。
一、首先一个简单的关系:子弹肯定是由武器发射的,武器是由人物操作的。
二、也就是说子弹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.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);
- }
- }
- }
//
// 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.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)
- {
- }
//
// 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)
{
}
好了,一个简单的点击屏幕发射子弹就出来了。这里只是提供了一个思路,具体的开发就自己去做了。