轉載自Cocos2D開發網–Cocos2Dev.com
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;
classBullet;
classGameScene : publicCCLayer {
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;
voidinitData();
};
#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;
}
boolGameScene::init(){
if(!CCLayer::init()) {
return false;
}
initData();
return true;
}
voidGameScene::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);
}
voidGameScene::registerWithTouchDispatcher(void){
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
}
boolGameScene::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
//每次點擊添加一個新×××
m_bullet->addNewBullet();
return true;
}
voidGameScene::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
}
voidGameScene::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
}
voidGameScene::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent)
{
}