本文主要是介绍Cocos2d-x3.0游戏实例之《别救我》第三篇——循环滚动背景(上),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
好,这篇我们来讲解无限循环滚动背景,这个知识已经被讲到烂了,我以前的文章也介绍过,所以就不那么详细地说明了。
笨木头花心贡献,啥?花心?不呢,是用心~
转载请注明,原文地址:http://www.benmutou.com/blog/archives/823
文章来源:笨木头与游戏开发
为什么是循环滚动背景?
用循环滚动背景,其实是因为我想偷懒,因为这样我只需要准备一张图片就可以了。
我们最终要创建这样的背景,如图:
背景是在滚动的,大家有没有看到?(小若:看你妹,这是jpg,不是gif)
大家是不是很在意下面的那多出来的一条锯齿?它可不是坐标错位了,这是一个伏笔(还伏笔,你以为写小说啊!)。
本篇教程会用到的图片资源到这里下载:http://yunpan.cn/QNXxe5fekPy4y 访问密码 8c82
创建2张连续的背景图片
要实现循环滚动的背景,需要2张相同的图片实现,图片首尾相接。
我们要创建一个新的类,叫做BackgroundLayer,用来实现滚动背景。
创建2张相同的背景图片,很简单,代码如下:
Size visibleSize = Director::getInstance()->getVisibleSize();
/* 背景图片 */
m_bg1 = Sprite::create("background.jpg");
m_bg1->setPosition(Point(visibleSize.width*0.5f, visibleSize.height*0.5f));
this->addChild(m_bg1);
m_bg2 = Sprite::create("background.jpg");
m_bg2->setPosition(Point(visibleSize.width*0.5f, -visibleSize.height*0.5f));
this->addChild(m_bg2);
m_bg1和m_bg2都是Sprite对象,因为后面要用到,所以直接作为类的成员属性,方便调用。
m_bg1是屏幕居中,m_bg2要紧接着m_bg1的下面,大家感受一下。
创建边缘锯齿
先跑一下题,我们把边缘锯齿也给添加好:
/* 创建边缘锯齿 */
auto border = Sprite::create("border.png");
Size borderSize = border->getContentSize();
auto border1 = createBorder(Point(borderSize.width*0.5f, borderSize.height*0.5f));
this->addChild(border1);
auto border2 = createBorder(Point(visibleSize.width- borderSize.width*0.5f, borderSize.height*0.5f));
border2->setFlippedX(true);
this->addChild(border2);
auto border3 = createBorder(Point(visibleSize.width*0.5f, visibleSize.height*0.15f));
borderSize = border3->getContentSize();
border3->setRotation(90.0f);
this->addChild(border3);
一共三个锯齿,左右各一个,下方一个。
createBorder是自定义函数,代码如下:
Sprite* BackgroundLayer::createBorder(Point pos)
{
auto border = Sprite::create("border.png");
Size borderSize = border->getContentSize();
auto body = PhysicsBody::createBox(borderSize);
body->setDynamic(false);
body->setCategoryBitmask(1);// 0001
body->setCollisionBitmask(1);// 0001
body->setContactTestBitmask(1);// 0001
border->setPhysicsBody(body);
border->setPosition(pos);
return border;
}
好,这个函数要稍微解释一下,这里使用PhysicsBody的createBox函数创建实体盒子刚体,因为边缘不是空心的。
然后调用了setDynamic函数,让刚体成为静态物体,也就是说,物理世界不会对它起产生影响了,它不会被撞飞,随你怎么撞,它都纹丝不动~
但是,它会对其他物理对象产生影响,比如有人撞了它,那个人就可能会反弹~
接着,有三个很特别的函数:setCategoryBitmask、setCollisionBitmask、setContactTestBitmask。
这三个函数是用于物体间的碰撞检测的,用来作为判断条件,要解释它们需要不小的篇幅,所以我就不解释了(小若:有没有墙?我想撞一下)。
本游戏在碰撞检测方面极其简单,所以不理解这三个函数都完全没有影响,因为游戏里的所有对象都能产生碰撞,没有什么特别的地方。
如果以后有机会,我再单独写一篇文章来介绍吧(或者大家百度一下)
目前的代码
好,来看看目前为止BackgroundLayer的代码,头文件如下:
#ifndef BackgroundLayer_H
#define BackgroundLayer_H
#include "cocos2d.h"
USING_NS_CC;
class BackgroundLayer :public Layer
{
public:
BackgroundLayer();
~BackgroundLayer();
CREATE_FUNC(BackgroundLayer);
virtualbool init();
private:
Sprite* m_bg1;
Sprite* m_bg2;
Sprite* createBorder(Point pos);
};
#endif
Cpp文件如下:
#include "BackgroundLayer.h"
BackgroundLayer::BackgroundLayer(){}
BackgroundLayer::~BackgroundLayer(){}
bool BackgroundLayer::init()
{
if(!Layer::init())
{
returnfalse;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
/* 背景图片 */
m_bg1 = Sprite::create("background.jpg");
m_bg1->setPosition(Point(visibleSize.width*0.5f, visibleSize.height*0.5f));
this->addChild(m_bg1);
m_bg2 = Sprite::create("background.jpg");
m_bg2->setPosition(Point(visibleSize.width*0.5f, -visibleSize.height*0.5f));
this->addChild(m_bg2);
/* 创建边缘锯齿 */
auto border = Sprite::create("border.png");
Size borderSize = border->getContentSize();
auto border1 = createBorder(Point(borderSize.width*0.5f, borderSize.height*0.5f));
this->addChild(border1);
auto border2 = createBorder(Point(visibleSize.width- borderSize.width*0.5f, borderSize.height*0.5f));
border2->setFlippedX(true);
this->addChild(border2);
auto border3 = createBorder(Point(visibleSize.width*0.5f, visibleSize.height*0.15f));
borderSize = border3->getContentSize();
border3->setRotation(90.0f);
this->addChild(border3);
returntrue;
}
Sprite* BackgroundLayer::createBorder(Point pos)
{
auto border = Sprite::create("border.png");
Size borderSize = border->getContentSize();
auto body = PhysicsBody::createBox(borderSize);
body->setDynamic(false);
body->setCategoryBitmask(1);// 0001
body->setCollisionBitmask(1);// 0001
body->setContactTestBitmask(1);// 0001
border->setPhysicsBody(body);
border->setPosition(pos);
return border;
}
先测试一下
我们来先测试一下代码的运行情况吧,我们给TollgateScene添加BackgroundLayer层,修改一下TollgateScene的scene函数:
Scene* TollgateScene::scene()
{
auto scene = Scene::createWithPhysics();
/* 这里省略了很多代码 */
/* 背景层 */
auto backgroundLayer = BackgroundLayer::create();
scene->addChild(backgroundLayer, 0);
auto layer = TollgateScene::create();
scene->addChild(layer, 10);
return scene;
}
OK,这样就可以了,再次运行代码,正常情况下,如图所示:
(小若:这就是一开始的那张图吧?连图片地址都一样好吧)
现在地图是不会滚动的,没意思,我们来开始滚床单…不,不好意思,习惯了(邪恶),是滚动背景才对。
51cto发博客有长度限制?好吧,这篇太长了,分两次发。
转载于:https://blog.51cto.com/benmutou/1408773
这篇关于Cocos2d-x3.0游戏实例之《别救我》第三篇——循环滚动背景(上)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!