射击游戏
2013-05-03 09:51
127 查看
本文我们将介绍如何去开发一个横向滚屏的射击类游戏
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);
}
}
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);
}
}
相关文章推荐
- 我的Unity 3D之旅——第一人称射击游戏(2)
- 射击闯关游戏,旧王已死、新王当立?
- 网页简单僵尸射击游戏开发1——游戏概述和html语言
- C#炮弹射击游戏
- 杨中科版C#射击游戏
- cocos2dx - 制作纵版射击游戏:喵星战争 (七)
- 飞行射击的最基本算法实现 躲子弹的游戏
- Unity3D (塔防游戏)射击 之 抛物线运动(模拟炮弹)
- 原生JS经典射击游戏-小蜜蜂
- cocos2d-x游戏实例(19)-纵版射击游戏(6)
- [Unity3D]手机3D游戏开发:FPS射击游戏中瞄准镜CrossHair的制作
- Unity3D上路_02-第一视角射击游戏
- 射击的乐趣:WIN32诠释打飞机游戏
- Java Swing打猎射击游戏编程代码下载
- 【Unity2D游戏实战 之 2D滚屏射击】1.背景滚动 (一)
- 如何使用cocos2d制作一个多向滚屏射击游戏-第二部分
- 基于C#弹幕类射击游戏的实现——(三)子弹的实现
- 练手项目:利用pygame库编写射击游戏