|
本文我们将介绍如何去开发一个横向滚屏的射击类游戏 1.在代码中重建背景 我们在项目中新建一个节点ParallaxBackground,头文件很简单
5 P1 D3 c6 ~& @" Z+ k' Y #ifndef PARALLAXBACKGROUND_H_ #define PARALLAXBACKGROUND_H_ #include "cocos2d.h" USING_NS_CC; class ParallaxBackground :public CCNode{ public: ParallaxBackground(); virtual ~ParallaxBackground(); CCSpriteBatchNode *batchnode; //组成背景的精灵数 int numSprites; //移动速度 float scrollSpeed; virtual bool init(); void update(ccTime time); CREATE_FUNC(ParallaxBackground); }; - #endif 9 W% b5 f! R: [; p& D
我在这里设置了对CCSpriteBatchNode节点的引用。我们将在代码里经常调用这个节点。调用一个保存在成员变量里的节点比通过getNodeByTag方法来调用要来的快。如果你在每一帧中都这样做的话,你就可以省下几个CPU处理周期。当然,如果你需要保存几十甚至上百个这样的成员变量的话,那就不值得这样做了。 |
7 ^( X" {2 e% L& o
#include "ParallaxBackground.h" ParallaxBackground::ParallaxBackground() { // TODO Auto-generated constructor stub } ParallaxBackground::~ParallaxBackground() { // TODO Auto-generated destructor stub } bool ParallaxBackground::init() { bool bRet = false; do { CCSize size = CCDirector::sharedDirector()->getWinSize(); //获得纹理贴图集的2d贴图 CCTexture2D* tt2d = CCTextureCache::sharedTextureCache()->addImage( "game-art.png"); batchnode = CCSpriteBatchNode::createWithTexture(tt2d); this->addChild(batchnode); numSprites = 7; //将7个不同的条纹图片添加到批处理精灵对象中 for (int i = 0; i < numSprites; i++) { CCString *file = CCString::createWithFormat("bg%i.png", i); CCSprite *sprite = CCSprite::createWithSpriteFrameName( file->getCString()); sprite->setPosition(CCPointMake(size.width/2,size.height/2)); batchnode->addChild(sprite, i); } scrollSpeed = 1.0f; this->scheduleUpdate(); bRet = true; } while (0); return bRet; } void ParallaxBackground::update(ccTime time) { CCObject *object=NULL; CCARRAY_FOREACH(batchnode->getChildren(),object) { CCSprite *sprite=(CCSprite *)object; CCPoint point = sprite->getPosition(); point.x -= (scrollSpeed + sprite->getZOrder()) * (time * 20); sprite->setPosition(point); } - } ; c6 F! x* T) d7 G; o
首先,我把game-art.png这张纹理贴图集加到CCTextureCache中。实际上,我已经在GameScene类中加载了这张纹理贴图集,为什么还要再加载一遍呢?原因是我需要用到CCTexture2D对象以生成CCSpriteBatchNode,而把相同一张贴图再次添加到CCTextureCache中是唯一一个获取已被缓存的贴图的方法。这个操作不会将贴图再次加载;CCTextureCache这个单例知道这个贴图已被加载过,会直接调用已被缓存的版本,这个操作速度很快。你可能会觉得奇怪,为什么没有一个像getTextureByName这样的方法来调用已经被缓存的贴图。不过现在确实是没有这样的方法可用。 ----------------------- 创建和设置完CCSpriteBatchNode以后,接下去的步骤是把7个单独的背景图片加载进来.
6 h3 z- k- h' f- u6 b1 a, [//动态生成文件名 - CCString *file = CCString::createWithFormat("bg%i.png", i);
; X( f7 m) `0 v% R 0 F' m% F& K+ x: e) t
//通过使用精灵的frameName,我创建了一个普通的CCSprite,然后把它放在屏幕的中央 CCSprite *sprite = CCSprite::createWithSpriteFrameName( file->getCString()); - sprite->setPosition(CCPointMake(size.width/2,size.height/2));
9 D/ N- O% S: ?3 o6 V1 A& m8 A 接下来讲解移动背景条纹 也就是void ParallaxBackground::update(ccTime time)中的代码 每一个条纹背景图片的X轴位置的值在每一帧调用更新方法时都会被减去一些,使它们从右向左移动。
8 M* t7 v; t' X, E+ l 移动的多少取决于预先定义的scrollSpeed(滚动速度)变量加上精灵的zOrder属性值,乘上delta这个值可以让滚动的速度独立于帧率。
2 V: L: W; o9 Q 因为delta只是两次调用更新方法之间所经过的时间,比如当前的帧率是60帧每秒,那么delta就等于1/60秒,也就是0.167秒,乘上这样的值图片就会运动的很慢,所以我又乘上20让移动的速度变得快一些。3 W4 D, d' o, d6 ]1 F! r- h
靠近屏幕的图片会滚动地快一些,因为zOrder的值越靠近屏幕越大。 |
因为ParallaxBackground这个类继承自CCNode,所以我只需要通过以下代码将ParallaxBackground添加到MainScene层当中去 MainScene.cpp的代码 ) f9 c, e) V( Z. T
bool MainScene::init() { bool bRet = false; do { CCSpriteFrameCache *cache=CCSpriteFrameCache::sharedSpriteFrameCache(); cache->addSpriteFramesWithFile("game-art.plist"); ParallaxBackground *bg=ParallaxBackground::create(); this->addChild(bg,-1); // this->scheduleUpdate(); bRet = true; } while (0); return bRet; - } $ x$ V. H) c6 e. g+ P8 l
影响视差速度的因素 在我们的游戏中,相同颜色的条纹需要用相同的速度移动,并且条纹应该重复出现以防止出现后面的纯色背景 第一个改变是与滚动速度有关的,我使用了Vector来存储各个条纹图片的移动速度。 ParallaxBackground头文件 : }* l6 h* y6 z0 T& t$ L% H
#ifndef PARALLAXBACKGROUND_H_ #define PARALLAXBACKGROUND_H_ #include "cocos2d.h" #include "vector" using namespace std; USING_NS_CC; class ParallaxBackground: public CCNode { public: ParallaxBackground(); virtual ~ParallaxBackground(); CCSpriteBatchNode *batchnode; //组成背景的精灵数 int numSprites; //移动速度 float scrollSpeed; //各个条纹图片的移动速度] vector<<SPAN class=datatypes style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0px; BORDER-TOP: medium none; PADDING-LEFT: 0px; FONT-WEIGHT: bold; PADDING-BOTTOM: 0px; MARGIN: 0px; BORDER-LEFT: medium none; COLOR: rgb(46,139,87); PADDING-TOP: 0px; BORDER-BOTTOM: medium none">float> speedFactors; virtual bool init(); void update(ccTime time);CREATE_FUNC(ParallaxBackground) ; }; - #endif - J/ e6 F; ~! q! @; ?, K2 a
+ |" F# h8 J9 e7 a/ \- P; W' T( d
#include "ParallaxBackground.h" ParallaxBackground::ParallaxBackground() { // TODO Auto-generated constructor stub } ParallaxBackground::~ParallaxBackground() { // TODO Auto-generated destructor stub } bool ParallaxBackground::init() { bool bRet = false; do { CCSize size = CCDirector::sharedDirector()->getWinSize(); //获得纹理贴图集的2d贴图 CCTexture2D* tt2d = CCTextureCache::sharedTextureCache()->addImage( "game-art.png"); batchnode = CCSpriteBatchNode::createWithTexture(tt2d); this->addChild(batchnode); numSprites = 7; speedFactors.push_back(0.3f); speedFactors.push_back(0.5f); speedFactors.push_back(0.5f); speedFactors.push_back(0.8f); speedFactors.push_back(0.8f); speedFactors.push_back(1.2f); speedFactors.push_back(1.2f); for (int i = 0; i < numSprites; i++) { CCString *file = CCString::createWithFormat("bg%i.png", i); CCLog("file为%s", file->getCString()); CCSprite *sprite = CCSprite::createWithSpriteFrameName( file->getCString()); CCLog("sprite的长为%f,宽为%f", sprite->getContentSize().width, sprite->getContentSize().height); sprite->setPosition(CCPointMake(size.width/2,size.height/2)); batchnode->addChild(sprite, i); } scrollSpeed = 1.0f; this->scheduleUpdate(); bRet = true; } while (0); return bRet; } void ParallaxBackground::update(ccTime time) { CCObject *object = NULL; CCARRAY_FOREACH(batchnode->getChildren(),object) { CCSprite *sprite = (CCSprite *) object; CCPoint point = sprite->getPosition(); point.x -= (scrollSpeed + speedFactors.at(sprite->getZOrder())) * (time * 20); sprite->setPosition(point); } - }
) p+ n8 n7 @6 p/ x+ r% ?8 \4 a2 z# o 代码完成 不多解释 很容易看懂 |