豪华版飞机大战系列(五)

在介绍了前面的几篇后,对于源码会在下一篇中上传,需要源码的可以在下一篇中看到下载链接,开源才是王道,分享才能成长。

这篇继续介绍下游戏中的子弹层的渲染,也就是BulletSprite的介绍。

对于子弹层的渲染有两种机制,一种是直接从缓存中进行精灵创建,创建后的精灵直接添加并使用,第二种机制为将创建的精灵加入到SpriteBatchNode中,这样进行渲染效率更高。对于这样渲染的机制我在这里稍微提一下,

普通的渲染机制为:准备,渲染,清除。准备,渲染,清除。…

批次渲染机制为:准备,渲染,渲染…渲染,清除

看以看到上面两种区别,批次渲染中只进行一次准备一次清除,要节省好多硬件消耗,这是游戏优化的一个重要指标。

对与文件中的两种渲染机制我都进行了实现,最终运行时我用的还是批次渲染,可以考到最终的编译为BulletSprite2.cpp,而不是BulletSprite.cpp。

好啦,说了这么多,该上代码了。

看一下BulletSprite.h头文件的内容:

#include "cocos2d.h"
USING_NS_CC;


class BulletSprite : public cocos2d::Layer
{
public:
    BulletSprite();
~BulletSprite();
    virtual bool init();  
    CREATE_FUNC(BulletSprite);


Animation* f_createAnimate(int count,int fps);//创建子弹运行的动画
void removeBullet( Node* pNode );//移除超出屏幕可视范围的子弹或者碰撞后的子弹清除
void ShootBullet(float dt);//发射子弹,在其中进行子弹的渲染和子弹的飞行动作


public:
Vector vecBullet;//子弹容器
SpriteBatchNode* bulletBatchNode;//批次渲染节点
};

```

函数都有详细说明,不做过多解释,下面看BulletSprite2.cpp的内容:
#include "BulletSprite.h"
#include "PlaneLayer.h"
BulletSprite::BulletSprite() {
}
BulletSprite::~BulletSprite() {
}
bool BulletSprite::init() {
bool bRet = false;
do {
CC_BREAK_IF(!Layer::init());
Texture2D* texture = TextureCache::sharedTextureCache()->textureForKey("bullet.png");
//创建BatchNode节点
bulletBatchNode = SpriteBatchNode::createWithTexture(texture);
this->addChild(bulletBatchNode);
//每隔0.2S调用一次发射子弹函数
this->schedule(schedule_selector(BulletSprite::ShootBullet),0.2f);
bRet = true;
} while (0);
return bRet;
}
void BulletSprite::ShootBullet(float dt) {
Size winSize = Director::getInstance()->getWinSize();
auto PlanePos = PlaneLayer::sharedPlane->getChildByTag(AIRPLANE)->getPosition();
//从缓存中创建子弹
auto spritebullet = Sprite::createWithSpriteFrameName("bullet_1.png");
//将创建好的子弹添加到BatchNode中进行批次渲染
bulletBatchNode->addChild(spritebullet);
//将创建好的子弹添加到容器
vecBullet.pushBack(spritebullet);
Point bulletPos = (Point(PlanePos.x,
PlanePos.y
+ PlaneLayer::sharedPlane->getChildByTag(AIRPLANE)->getContentSize().height
/ 2 + 20));
spritebullet->setPosition(bulletPos);
spritebullet->setScale(0.4f);


float flyLen = winSize.height - PlanePos.y;
float flyVelocity = 320 / 1;//运行速度,可以自己控制,每秒所走的像素
float realFlyDuration = flyLen / flyVelocity;//实际飞行的时间


//子弹运行的距离和时间,从飞机处开始运行到屏幕顶端
auto actionMove = MoveTo::create(realFlyDuration,
Point(bulletPos.x, winSize.height));
//子弹执行完动作后进行函数回调,调用移除子弹函数
auto actionDone = CallFuncN::create(
CC_CALLBACK_1(BulletSprite::removeBullet, this));


Sequence* sequence = Sequence::create(actionMove, actionDone, NULL);
spritebullet->runAction(sequence);


}
/**
 * 移除子弹,将子弹从容器中移除,同时也从SpriteBatchNode中移除
 */
void BulletSprite::removeBullet(Node* pNode) {
if (NULL == pNode) {
return;
}
Sprite* bullet = (Sprite*) pNode;
this->bulletBatchNode->removeChild(bullet, true);
vecBullet.eraseObject(bullet);
}


/**
 * 从缓存中获取子弹动画图片后创建子弹动画,最终返回创建好的动画
 */
Animation* BulletSprite::f_createAnimate(int count, int fps) {
char buff;
Animation *panimation = Animation::create();
panimation->setDelayPerUnit(1.0 / fps);
for (int id = 1; id <= count; id++) {
sprintf(buff, "bullet_%d.png", id);
panimation->addSpriteFrame(
SpriteFrameCache::getInstance()->getSpriteFrameByName(buff));
}
return panimation;
}

```


上面函数中注释的都比较详细,关键要注意批次渲染机制的运用,这是游戏优化的一大提高点。

介绍了这么多还没有开始介绍游戏主要逻辑层,我都等不及了,在下一篇中会进行游戏源码的上传,需要的可以看下一篇的介绍。

这篇就介绍到这里,下一篇也是最后一篇,介绍游戏主要逻辑层的实现。

第一篇在哪里呢

http://www.cocoachina.com/bbs/read.php?tid=217400

最后子弹的动画没有调用吗?

目测没有调用:3:

3.+不是自动批次渲染吗?

这个地方在我的mac上编译不过,我发了个帖子,请问楼主能够帮我看看么?多谢。我该如何修改?

init is a protected member of cocos2d::Sprite

good,帅气分享

在这个游戏里面小猪是跟着飞机移动的,要是飞机移动而小猪延时移动要怎么做?直接添加延迟感觉小猪并没有多少效果啊

阿斯顿飞过后