六、CCLayer
一个游戏中可以有很多个场景,每个场景里面又可能包含有多个图层,这里的图层一般就是CCLayer对象。CCLayer本身几乎没什么功能,对比CCNode,CCLayer可用于接收触摸和加速计输入。其实,cocos2d对图层并没有严格的要求,图层不一定要使用CCLayer类,它也可以是一个简单的CCNode,为什么呢?我们新建一个图层不就是为了能够容纳更多的子节点么,CCNode也可以添加子节点啊。所以,如果你的图层不需要接收触摸和加速计输入,就尽量使用CCNode表示图层,CCLayer因为能够接收触摸和加速计输入会增加不必要的开销。移动、缩放、旋转整个图层,图层上的所有节点也会跟着一起移动、缩放、旋转。
常用设置
1.接收触摸输入
CCLayer默认情况是不接收触摸输入的,需要显示地设置isTouchEnabled为YES
- self.isTouchEnabled = YES;
设置isTouchEnabled为YES后,就会调用图层相应的方法来处理触摸输入:
这些都是在CCStandardTouchDelegate协议中定义的方法
1> 当单指接触到屏幕时
- - (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
2> 当手指在屏幕上移动时
- - (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
3> 当单指离开屏幕时
- - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
4> 当触摸被取消时
- - (void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
很少会发生触摸被取消的情况,所以大多数情况下可忽略,或用ccTouchesEnded代替,因为ccTouchesCancelled和ccTouchesEnded类似
大部分情况下,我们需要知道触摸发生在什么位置。这里的触摸事件是由UIKit框架接收的,因此需要把触摸位置转换为OpenGL坐标。
比如在手指移动过程中:
- - (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
- // 获取触摸对象
- UITouch *touch = [touches anyObject];
- // 获取触摸在UIView视图上的位置
- CGPoint uiPoint = [touch locationInView:touch.view];
- // 转换为OpenGL坐标
- CGPoint glPoint = [[CCDirector sharedDirector] convertToGL:uiPoint];
- }
下面利用一个小例子来综合使用上述的方法,假设图层上有个精灵,我手指触摸到哪,这个精灵的位置就在哪
首先在图层初始化的时候添加精灵
- // 图层的init方法
- -(id) init
- {
- if( (self=[super init])) {
- // 初始化一个精灵
- CCSprite *lufy = [CCSprite spriteWithFile:@"lufy.png"];
- CGSize size = [[CCDirector sharedDirector] winSize];
- lufy.position = ccp(size.width * 0.5f, size.height * 0.5f);
- // 添加精灵,并设置标记
- [self addChild: lufy z:0 tag:kLufyTag];
- self.isTouchEnabled = YES;
- }
- return self;
- }

接下来是在图层中接收触摸输入
- // 计算触摸在图层中的位置(OpenGL坐标)
- - (CGPoint)locationInLayer:(NSSet *)touches {
- // 获取触摸对象
- UITouch *touch = [touches anyObject];
- // 获取触摸在UIView视图上的位置
- CGPoint uiPoint = [touch locationInView:touch.view];
- // 转换为OpenGL坐标
- CGPoint glPoint = [[CCDirector sharedDirector] convertToGL:uiPoint];
- return glPoint;
- }
- // 由于ccTouchesBegan、ccTouchesMoved、ccTouchesEnded中的做法都是一样,所以抽成一个方法
- - (void)dealTouches:(NSSet *)touches {
- // 计算触摸的位置
- CGPoint point = [self locationInLayer:touches];
- // 根据标记获取精灵
- CCSprite *lufy = (CCSprite *)[self getChildByTag:kLufyTag];
- // 设置精灵的位置
- lufy.position = point;
- }
- - (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
- [self dealTouches:touches];
- }
- - (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
- [self dealTouches:touches];
- }
- - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
- [self dealTouches:touches];
- }
图层的触摸输入暂时讲到这里,其他高级的用法在后面会提及
2.接收加速计输入
CCLayer默认情况是不接收加速计输入的,需要显示地设置isAccelerometerEnabled为YES
- self.isAccelerometerEnabled = YES;
设置isAccelerometerEnabled为YES后,就会调用图层相应的方法来处理加速计输入:
这是在UIAccelerometerDelegate协议中定义的方法
- - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
- // typedef double UIAccelerationValue;
- UIAccelerationValue x = acceleration.x;
- UIAccelerationValue y = acceleration.y;
- UIAccelerationValue z = acceleration.z;
- // x,y,z代表三维中任意方向的加速度
- }
CCLayerColor
有时候,我们想给整个图层设置一种背景颜色,那么就需要用到CCLayerColor了,CCLayerColor是CCLayer的子类
- // 红色:#ffff0000
- ccColor4B color = ccc4(255, 0, 0, 255);
- // 初始化一个颜色图层
- CCLayerColor *layerColor = [CCLayerColor layerWithColor:color];
- // 添加到场景中
- [scene addChild:layerColor];
效果图:

CCLayerGradient
CCLayerGradient是CCLayerColor的子类,可以给图层设置渐变色
- // 红色:#ffff0000
- ccColor4B red = ccc4(255, 0, 0, 255);
- // 蓝色:#ff0000ff
- ccColor4B blue = ccc4(0, 0, 255, 255);
- // 初始化一个渐变图层,从红色渐变到蓝色
- CCLayerGradient *layerGradient = [CCLayerGradient layerWithColor:red fadingTo:blue];
- // 添加到场景中
- [scene addChild:layerGradient];
效果图:

CCLayerMultiplex
CCLayerMultiplex继承自CCLayer,称为"多重图层"。它可以包含多个CCLayer对象,但在任意时刻只可以有一个CCLayer处于活动状态,用switchTo:和switchToAndReleaseMe:方法可以让某个图层处于活动状态,区别在于switchToAndReleaseMe:方法会先释放当前处于活动状态的图层,再让参数中要求的图层处于活动状态
- // 创建2个图层
- CCLayer *layer1 = [CCLayer node];
- CCLayer *layer2 = [CCLayer node];
- // 创建一个多重图层,包含了layer1和layer2
- CCLayerMultiplex *plex = [CCLayerMultiplex layerWithLayers:layer1, layer2, nil];
- // 让layer1处于活动状态(layer2还在内存中)
- [plex switchTo:0];
- // 让layer2处于活动状态(layer1还在内存中)
- [plex switchTo:1];
- // 释放当前处于活动状态的layer2(layer2从内存中移除),然后让layer1处于活动状态
- [plex switchToAndReleaseMe:0];
图层之间的切换是没有过渡效果的
六、CCLayer的更多相关文章
- cocos2D(六)----CCLayer
一个游戏中能够有非常多个场景,每一个场景里面又可能包括有多个图层,这里的图层一般就是CCLayer对象.CCLayer本身差点儿没什么功能.对照CCNode,CCLayer可用于接收触摸和加速计输入. ...
- CCScene,CCLayer,CCSprite,CCDirector
一.CCScene : 游戏中不同的画面可以用不同的场景展示出来,大致的可以分为以下的几类场景: 1. 展示类场景.游戏开场画面,游戏简介,胜利以及失败提示,帮助. 2. 选择类场景.主菜单,游戏设置 ...
- 如何一步一步用DDD设计一个电商网站(六)—— 给购物车加点料,集成售价上下文
阅读目录 前言 如何在一个项目中实现多个上下文的业务 售价上下文与购买上下文的集成 结语 一.前言 前几篇已经实现了一个最简单的购买过程,这次开始往这个过程中增加一些东西.比如促销.会员价等,在我们的 ...
- MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息
MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二 ...
- 【原】AFNetworking源码阅读(六)
[原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...
- CRL快速开发框架系列教程六(分布式缓存解决方案)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- 【微信小程序开发•系列文章六】生命周期和路由
这篇文章理论的知识比较多一些,都是个人观点,描述有失妥当的地方希望读者指出. [微信小程序开发•系列文章一]入门 [微信小程序开发•系列文章二]视图层 [微信小程序开发•系列文章三]数据层 [微信小程 ...
- 我的MYSQL学习心得(六) 函数
我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...
- 我的MYSQL学习心得(十六) 优化
我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...
随机推荐
- lock关键字理解
>可以把lock关键字可以看成 try{ Monitor.Enter(x); //.. } finally{ Monitor.Exit(x); } 这样子的结构,当然使用lock关键字更方便 & ...
- BZOJ3206 [Apio2013]道路费用
首先我们强制要求几条待定价的边在MST中,建出MST 我们发现这个MST中原来的边是一定要被选上的,所以可以把点缩起来,搞成一棵只有$K$个点的树 然后$2^K$枚举每条边在不在最终的MST中,让在最 ...
- Log4J实用配置指南
转自:http://www.cnblogs.com/licheng/archive/2008/08/23/1274566.html 1 概述 本文档是针对Log4j日志工具的使用指南. ...
- Kafka简要图解
LinkedIn贡献的分布式消息系统 - 请参考这里 kafka集群:producer写入消息,consumer读取消息 消息分为不同主题,每个主题可以分为多个partition(并行),每个part ...
- [Js]跟随鼠标移动的div
例子:鼠标移动到一块东西上,出现提示文本框,并且提示文本框跟着鼠标的位置动 document.onmouseover=function(ev){ var oEvent=ev||event; var b ...
- for update造成的Oracle锁表与解锁
我遇到的情况: 当使用select语句查询表时,后面跟着for update , select * from table for update 当修改表中数据,但是没有commit就关掉PL/SQL, ...
- 精华 ionic入门之色彩、图标、边距和界面组件:列表
目录:色彩.图标和边距色彩图标内边距界面组件:列表列表:.list成员容器:.item.item: 嵌入文本.item : 嵌入图标.item : 嵌入头像.item : 嵌入缩略图.item : 嵌 ...
- C#操作Access数据库(创建&修改结构)
本文转自:http://www.cnblogs.com/liyugang/archive/2012/11/17/2775393.html 想要在程序中控制Access,不是数据,而是Access数据库 ...
- iOS开发中关于nslog的几种流行做法小结
不管哪种方法,都必须在PCH文件中做下宏定义 DEBUG和RELEASE要分开,RELEASE时log打印要取消 方法一:简单直接,用几行代码搞定,简洁但功能少 #ifdef DEBUG #defin ...
- 记录一些容易忘记的属性 -- NSTimer
使定时器停止的方法: 1. //将定时器的启动时间设置为很久以后的将来,到这个时间,定时器才会开始工作 [_timer setFireDate:[NSDate distantFu ...