• 周四. 4 月 23rd, 2026

物嫩软件资讯网

软件资讯来物嫩

射击游戏

admin@wunen

6 月 7, 2025

本文我们将介绍如何去开发一个横向滚屏的射击类游戏




1.在代码中重建背景




我们在项目中新建一个节点ParallaxBackground,头文件很简单




/*




* ParallaxBackground.h




*




*  Created on: 2012-9-18




*      Author: Panda




*/








#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 /* PARALLAXBACKGROUND_H_ */




我在这里设置了对CCSpriteBatchNode节点的引用。我们将在代码里经常调用这个节点。调用一个保存在成员变量里的节点比通过getNodeByTag方法来调用要来的快。如果你在每一帧中都这样做的话,你就可以省下几个CPU处理周期。当然,如果你需要保存几十甚至上百个这样的成员变量的话,那就不值得这样做了。




/*




* ParallaxBackground.cpp




*




*  Created on: 2012-9-18




*      Author: Panda




*/








#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);




}








}




首先,我把game-art.png这张纹理贴图集加到CCTextureCache中。实际上,我已经在GameScene类中加载了这张纹理贴图集,为什么还要再加载一遍呢?原因是我需要用到CCTexture2D对象以生成CCSpriteBatchNode,而把相同一张贴图再次添加到CCTextureCache中是唯一一个获取已被缓存的贴图的方法。这个操作不会将贴图再次加载;CCTextureCache这个单例知道这个贴图已被加载过,会直接调用已被缓存的版本,这个操作速度很快。你可能会觉得奇怪,为什么没有一个像getTextureByName这样的方法来调用已经被缓存的贴图。不过现在确实是没有这样的方法可用。




———————–




创建和设置完CCSpriteBatchNode以后,接下去的步骤是把7个单独的背景图片加载进来.




//动态生成文件名




CCString *file = CCString::createWithFormat(“bg%i.png”, i);




//通过使用精灵的frameName,我创建了一个普通的CCSprite,然后把它放在屏幕的中央




CCSprite *sprite = CCSprite::createWithSpriteFrameName(




file->getCString());




sprite->setPosition(CCPointMake(size.width/2,size.height/2));




接下来讲解移动背景条纹 也就是void ParallaxBackground::update(ccTime time)中的代码








每一个条纹背景图片的X轴位置的值在每一帧调用更新方法时都会被减去一些,使它们从右向左移动。




移动的多少取决于预先定义的scrollSpeed(滚动速度)变量加上精灵的zOrder属性值,乘上delta这个值可以让滚动的速度独立于帧率。




因为delta只是两次调用更新方法之间所经过的时间,比如当前的帧率是60帧每秒,那么delta就等于1/60秒,也就是0.167秒,乘上这样的值图片就会运动的很慢,所以我又乘上20让移动的速度变得快一些。




靠近屏幕的图片会滚动地快一些,因为zOrder的值越靠近屏幕越大。








因为ParallaxBackground这个类继承自CCNode,所以我只需要通过以下代码将ParallaxBackground添加到MainScene层当中去




MainScene.cpp的代码




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;




}








影响视差速度的因素








在我们的游戏中,相同颜色的条纹需要用相同的速度移动,并且条纹应该重复出现以防止出现后面的纯色背景




第一个改变是与滚动速度有关的,我使用了Vector来存储各个条纹图片的移动速度。




ParallaxBackground头文件




/*




* ParallaxBackground.h




*




*  Created on: 2012-9-18




*      Author: Panda




*/








#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<float> speedFactors;








virtual bool init();




void update(ccTime time);CREATE_FUNC(ParallaxBackground)




;




};








#endif /* PARALLAXBACKGROUND_H_ */




/*




* ParallaxBackground.cpp




*




*  Created on: 2012-9-18




*      Author: Panda




*/








#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);




}








}




代码完成  不多解释  很容易看懂




——————————-




设置背景的无限滚动




我在CCSpriteBatchNodo中又添加了一组7个背景条纹图片,当然,他们的设置和之前不同




for (int i = 0; i < numSprites; i++) {





CCString *file = CCString::createWithFormat(“bg%i.png”, i);




CCSprite *sprite = CCSprite::createWithSpriteFrameName(




file->getCString());




sprite->setAnchorPoint(CCPointMake(0,0));




// 将新的背景图片放置在屏幕的右端 -1是为了方式出现接合处出现黑线




sprite->setPosition(CCPointMake(size.width-1,0));




//将精灵平行翻转过来与第一组图片相连接




sprite->setFlipX(true);




batchnode->addChild(sprite, i);




}




void ParallaxBackground::update(ccTime time) {





CCSize size = CCDirector::sharedDirector()->getWinSize();




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);




if (point.x < -size.width) {





//          -2是为了方式出现接合处出现黑线 为什么要再向左移动2个像素呢?




//          因为原先被水平翻转过的背景图片已经向左移




//          动了1个像素,每次重新放置背景图片以后我们需要将它向左移动2个像素才能




//          和左边的背景图片保持1个像素的重叠。




point.x += size.width*2-2;




}




sprite->setPosition(point);




}








}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注