【Cocos2d-X开发学习笔记】第05期:渲染框架之布景层类(CCLayer)的使用
本系列学习教程使用的是cocos2d-x-2.1.4版本(截至目前为止最新稳定版) ,PC开发环境Windows7,C++开发环境VS2010
图层也是渲染框架中很重要的内容。场景类用来划分游戏的状态,图层就用来划分游戏画面。通常图层的尺寸
会与屏幕的尺寸一致。它将会覆盖整个显示名目。所以所图层几乎包含了所有游戏内容。相比场景类,它为玩家呈现
了丰富的游戏画面。每个游戏场景中可以有很多层,每一层负责各自的任务,如专门负责显示地图的背景、专门负责
显示敌人、专门负责机关和专门负责主角等;每一层上可以放置不同的元素,包括文本、精灵图片和菜单等。通过层
与层之间的组合关系就可以构成游戏显示的界面UI,游戏中等。当然为了看到每一层的东西,可把一些层设置为透明
或半透明的,这样就可以看到不同布景层加到一起的效果了。
一、布景层类(CCLayer)
布景层类CCLayer是CCNode类的子类,并且在此基础上实现触屏事件代理(TouchEventsDelegate)协议,可以
实现CCNode类的功能,并且可以处理输入,包括触屏和加速传感器。 CCLayer类包含了三个功能。
<1> 接受用户操作,比如触屏、重力加速度计的信息。
<2> 作为游戏内容元素的容器,用于显示游戏画面、承载精灵类、字体文本等对象。
<3> 填充背景游戏背景颜色。
CCLayer类的继承关系如下图所示。
由图可以看出CCLayer类继承自CCNode类,并且CCLayer类还遵照触屏代理协议、加速度传感器代理协议、键
盘时间代理协议等协议。除此之外,CCLayer类还有子类,如下图所示。
这些子类的功能如下图所示。
首先来看看CCLayer类的使用,然后再来看主要的子类的使用。
1、CCLayer类的主要函数如下图所示。
2、CCLayer类的使用
新建一个Cocos2D-X的项目,然后在新建项目的HelloWorldScene.cpp文件中,scene函数定义CCLayer类并把它
加入场景中,代码如下所示。
CCScene* HelloWorld::scene()
{
// 新建场景类实例
CCScene * scene = CCScene::create(); //定义布景层
HelloWorld *layer = HelloWorld::create(); // 将布景层加入场景中
scene->addChild(layer); // 返回场景类
return scene;
}
CCLayer类的init函数在创建布景层时被调用,如下代码所示。
bool HelloWorld::init()
{
if(! CCLayer::init())
{
return false;
} // 创建一个菜单按钮子项
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback)); // 设置菜单按钮的位置
pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20)); // 创建一个包含关闭按钮的菜单
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero); // 添加菜单到图层中
this->addChild(pMenu, 1); // 得到尺寸大小
CCSize size = CCDirector::sharedDirector()->getWinSize(); // 创建图片精灵
CCSprite* pSprite = CCSprite::create("HelloWorld.png"); // 设置图片精灵的位置
pSprite->setPosition(ccp(size.width/2, size.height/2)); // 把图片精灵放置在图层中
this->addChild(pSprite, 0); return true;
}
我们会在后面学习具体显示在层次上的对象,目前只需要了解在init函数中定义要显示的对象并把它作为子类加入
场景中。另外,关于触屏、键盘、加速度传感器等输入,我们也会在后面学习到。接下来,让我们一起学习CCLayer
类的子类。
二、颜色布景层类(CCLayerColor)
颜色布景层类CCLayerColor是CCLayer类的子类,包含CCLayer类的特性,并且有两个扩展功能:可以为布景层
增添颜色,以及设置不透明度。
我们新建一个Coco2D-X的项目,然后在看CCLayerColor类的定义初始化,如下代码所示。这段代码在下
HelloWorldScene.cpp文件中HelloWorld的init函数。
bool HelloWorld::init()
{
bool bRet = false;
do
{
CC_BREAK_IF(! CCLayer::init()); // Create a "close" menu item with close icon, it's an auto release object.
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
CC_BREAK_IF(! pCloseItem); // Place the menu item bottom-right conner.
pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20)); // Create a menu with the "close" menu item, it's an auto release object.
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
CC_BREAK_IF(! pMenu); // Add the menu to HelloWorld layer as a child layer.
this->addChild(pMenu, 1); // Get window size and place the label upper.
CCSize size = CCDirector::sharedDirector()->getWinSize(); CCLayerColor* layer = CCLayerColor::create(ccc4(0xFF,0x00,0x00,0x80),200,200);
layer->ignoreAnchorPointForPosition(false);
layer->setPosition(CCPointMake(size.width/2,size.height/2));
addChild(layer,1); bRet = true;
} while (0); return bRet;
}
我们主要看的是这几句代码:
CCLayerColor* layer = CCLayerColor::create(ccc4(0xFF,0x00,0x00,0x80),200,200);
layer->ignoreAnchorPointForPosition(false);
layer->setPosition(CCPointMake(size.width/2,size.height/2));
addChild(layer,1);
create函数的第一个参数是颜色的ARGB值,使用ccc4定义,其中第一个参数是颜色A值,第二个参数是R值,第
三个参数是G值,最后一个参数是B值。除此之外,create函数后两个参数是布景层的宽和高。
另外,使用ignoreAnchorPointForPosition将忽略锚点置为false。由于默认设置是忽略锚点,也就是以左下角为锚
点,可以让布景层考虑锚点的影响(关于锚点在之前已经学习过),这时默认的锚点在中心。
运行效果图如下图所示。
还有一个比较常用的函数setBlendFunc,可以让布景层的颜色产生渐变的效果。比如,需要在整屛添加全屏的一
些覆盖效果、全屏变黑或者全屏变暗时,都可以使用这个方法。下面让我们通过示例来学习这个函数的用法。
<1> 新建一个Coco2D-X的项目,我们取名为MyLayerBlend。首先在HelloWorldScene.h头文件中添加一个函数。
void newBlend(float dt);
<2> 然后在HelloWorldScene.cpp文件的init函数中修改如下所示代码。
bool HelloWorld::init()
{
bool bRet = false;
do
{
CC_BREAK_IF(! CCLayer::init()); // Create a "close" menu item with close icon, it's an auto release object.
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
CC_BREAK_IF(! pCloseItem); // Place the menu item bottom-right conner.
pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20)); // Create a menu with the "close" menu item, it's an auto release object.
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
CC_BREAK_IF(! pMenu); // Add the menu to HelloWorld layer as a child layer.
this->addChild(pMenu); // Get window size and place the label upper.
CCSize size = CCDirector::sharedDirector()->getWinSize(); CCLayerColor* layer1 = CCLayerColor::create( ccc4(255, 255, 255, 80) ); CCSprite* sister1 = CCSprite::create("grossinis_sister1.png");
CCSprite* sister2 = CCSprite::create("grossinis_sister2.png"); addChild(sister1,1);
addChild(sister2,1);
addChild(layer1, 100,1); sister1->setPosition( ccp( size.width*1/3, size.height/2) );
sister2->setPosition( ccp( size.width*2/3, size.height/2) ); schedule( schedule_selector(HelloWorld::newBlend), 1.0f); bRet = true;
} while (0); return bRet;
}
这里用了一个定时器schedule来切换渐变的效果。
<3> 最后在newBlend函数中添加如下所示代码。
void HelloWorld::newBlend(float dt)
{
CCLayerColor *layer = (CCLayerColor*)getChildByTag(1); GLenum src;
GLenum dst; if( layer->getBlendFunc().dst == GL_ZERO )
{
src = GL_SRC_ALPHA;
dst = GL_ONE_MINUS_SRC_ALPHA;
}
else
{
src = GL_ONE_MINUS_DST_COLOR;
dst = GL_ZERO;
} ccBlendFunc bf = {src, dst};
layer->setBlendFunc( bf );
}
传入的参数是一个有起始效果和结束效果的参数。
<4> 运行效果图。
三、多层布景层类(CCLayerMultiplex)
在游戏开发中,一般会把游戏分为两部分:一部分是游戏界面部分,也就是常说的UI部分;另一部分就是游戏本
身的部分。有时UI有很多页面,在页面中用的图也并不是很多,不需要使用切换场景,只需把不同页面做成不同的布
景层,然后切换布景层。那么这就需要一个“管理者”来管理这些界面,这时候就要使用CCLayerMultiplex类。
在很多游戏中都需要在不同的界面中使用相同的几个变量,如果不这样做,就需要做大量的保存工作。
在 tests项目中MenuTest.cpp的MenuTestScene类的runThisTest函数中有CCLayerMultiplex类的定义初始化方
法,如下代码所示。
void MenuTestScene::runThisTest()
{
CCLayer* pLayer1 = new MenuLayerMainMenu();
CCLayer* pLayer2 = new MenuLayer2();
CCLayer* pLayer3 = new MenuLayer3();
CCLayer* pLayer4 = new MenuLayer4();
CCLayer* pLayer5 = new MenuLayerPriorityTest();
CCLayer* pLayer6 = new BugsTest();
CCLayer* pLayer7 = new RemoveMenuItemWhenMove(); CCLayerMultiplex* layer = CCLayerMultiplex::create(pLayer1, pLayer2, pLayer3, pLayer4, pLayer5, pLayer6, pLayer7, NULL);
addChild(layer, 0); pLayer1->release();
pLayer2->release();
pLayer3->release();
pLayer4->release();
pLayer5->release();
pLayer6->release();
pLayer7->release(); CCDirector::sharedDirector()->replaceScene(this);
}
首先定义并初始化每个布景层类,然后将这些布景层实例以参数形式传给CCLayerMultiplex的create函数,最后以NULL(空)结束。
这里在传入参数之后将这些布景层实例的指针释放,是为了防止内存泄露。至于Cocos2D-X的内存管理,我们会
在后面学习到。
然后把CCLayerMultiplex实例作为子节点传入场景中,最后运行场景。如下代码所示是切换布景层的switchTo函数
使用方法。
void MenuLayerPriorityTest::menuCallback(CCObject* pSender)
{
((CCLayerMultiplex*)m_pParent)->switchTo(0);
// [[CCDirector sharedDirector] popScene];
}
由于这个函数被CCLayerMultiplex实例的子布景,即初始化CCLayerMultiplex传入的布景类实例调用,所以它的
m_pParent父节点就是CCLayerMultiplex实例本身。获得CCLayerMultiplex实例指针后,调用switchTo函数就可以转
换到相应的子布景中。
【Cocos2d-X开发学习笔记】第05期:渲染框架之布景层类(CCLayer)的使用的更多相关文章
- 驱动开发学习笔记. 0.05 linux 2.6 platform device register 平台设备注册 2/2 共2篇
驱动开发读书笔记. 0.05 linux 2.6 platform device register 平台设备注册 2/2 共2篇 下面这段摘自 linux源码里面的文档 : 内核版本2.6.22Doc ...
- 驱动开发学习笔记. 0.07 Uboot链接地址 加载地址 和 链接脚本地址
驱动开发学习笔记. 0.07 Uboot链接地址 加载地址 和 链接脚本地址 最近重新看了乾龙_Heron的<ARM 上电启动及 Uboot 代码分析>(下简称<代码分析>) ...
- 【前端】移动端Web开发学习笔记【2】 & flex布局
上一篇:移动端Web开发学习笔记[1] meta标签 width设置的是layout viewport 的宽度 initial-scale=1.0 自带 width=device-width 最佳实践 ...
- 【前端】移动端Web开发学习笔记【1】
下一篇:移动端Web开发学习笔记[2] Part 1: 两篇重要的博客 有两篇翻译过来的博客值得一看: 两个viewport的故事(第一部分) 两个viewport的故事(第二部分) 这两篇博客探讨了 ...
- android开发学习笔记000
使用书籍:<疯狂android讲义>——李刚著,2011年7月出版 虽然现在已2014,可我挑来跳去,还是以这本书开始我的android之旅吧. “疯狂源自梦想,技术成就辉煌.” 让我这个 ...
- 高性能Cordova App开发学习笔记
高性能Cordova App开发学习笔记 文件结构 添加插件 构建准备 各个www的作用,prepare命令会将hello\www的内容会拷贝到platform下的wwww目录,知道该改哪里了吧?如果 ...
- Rest API 开发 学习笔记(转)
Rest API 开发 学习笔记 概述 REST 从资源的角度来观察整个网络,分布在各处的资源由URI确定,而客户端的应用通过URI来获取资源的表示方式.获得这些表徵致使这些应用程序转变了其状态.随着 ...
- 步步为营 SharePoint 开发学习笔记系列总结
转:http://www.cnblogs.com/springyangwc/archive/2011/08/03/2126763.html 概要 为时20多天的sharepoint开发学习笔记系列终于 ...
- Kinect开发学习笔记之(一)Kinect介绍和应用
Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...
随机推荐
- style中position的属性值具体解释
Position的英文原意是指位置.职位.状态.也有安置的意思.在CSS布局中,Position发挥着非常关键的数据,非常多容器的定位是用Position来完毕. Position属性有四个可选值,它 ...
- Google maps API开发
原文:Google maps API开发 Google maps API开发(一) 最近做一个小东西用到google map,突击了一下,收获不小,把自己学习的一些小例子记录下来吧 一.加载Googl ...
- RethinkDB创始人教你如何打造一个伟大的互联网产品
关于作者 我叫Slava Akhmechet,本人是 RethinkDB 的创始人之一,RethinkDB是开源,分布式数据库,旨在帮助开发人员与运营商在打造实时应用时处理无结构数据 如何打造一个伟大 ...
- Js创建对象的做法
1.对象工具包 <html> <head> <meta http-equiv="Content-Type" content="text/ht ...
- mysql设置root的密码
mysql -u root mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass');
- 项目笔记---CSharp图片处理
原文:项目笔记---CSharp图片处理 项目笔记---CSharp图片处理 最近由于项目上需要对图片进行二值化处理,就学习了相关的图片处理上的知识,从开始的二值化的意义到动态阀值检测二值化等等,并用 ...
- Linux Kernel的Makefile与Kconfig文件的语法
https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt Introduction ------------ The c ...
- QT自动补全设置
在工具 -> 选项 -> 环境 -> 键盘 中,找到TextEditor -> CompleteThis,修改后面的快捷键就好了 我将它修改为Alt + /
- CSS3教程:box-sizing属性的理解border、padding与容器宽度的关系
说到 IE 的 bug,一个臭名昭著的例子是它对于“盒模型”的错误解释:在 IE5.x 以及 Quirks 模式的 IE6/7 中,将 border 与 padding 都包含在 width 之内.这 ...
- js 文字预写匹配
效果图: demo如下: <!DOCTYPE html> <html> <head> <title>文字预写</title> </he ...