一个游戏中可以有很多个场景,每个场景里面又可能包含有多个图层,这里的图层一般就是CCLayer对象。CCLayer本身几乎没什么功能,对比CCNode,CCLayer可用于接收触摸和加速计输入。其实,cocos2d对图层并没有严格的要求,图层不一定要使用CCLayer类,它也可以是一个简单的CCNode,为什么呢?我们新建一个图层不就是为了能够容纳更多的子节点么,CCNode也可以添加子节点啊。所以,如果你的图层不需要接收触摸和加速计输入,就尽量使用CCNode表示图层,CCLayer因为能够接收触摸和加速计输入会增加不必要的开销。移动、缩放、旋转整个图层,图层上的所有节点也会跟着一起移动、缩放、旋转。

常用设置

1.接收触摸输入

CCLayer默认情况是不接收触摸输入的,需要显示地设置isTouchEnabled为YES

  1. self.isTouchEnabled = YES;

设置isTouchEnabled为YES后,就会调用图层相应的方法来处理触摸输入:

这些都是在CCStandardTouchDelegate协议中定义的方法

1> 当单指接触到屏幕时

  1. - (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

2> 当手指在屏幕上移动时

  1. - (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

3> 当单指离开屏幕时

  1. - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

4> 当触摸被取消时

  1. - (void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

很少会发生触摸被取消的情况,所以大多数情况下可忽略,或用ccTouchesEnded代替,因为ccTouchesCancelled和ccTouchesEnded类似

大部分情况下,我们需要知道触摸发生在什么位置。这里的触摸事件是由UIKit框架接收的,因此需要把触摸位置转换为OpenGL坐标。

比如在手指移动过程中:

  1. - (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  2. // 获取触摸对象
  3. UITouch *touch = [touches anyObject];
  4. // 获取触摸在UIView视图上的位置
  5. CGPoint uiPoint = [touch locationInView:touch.view];
  6. // 转换为OpenGL坐标
  7. CGPoint glPoint = [[CCDirector sharedDirector] convertToGL:uiPoint];
  8. }

下面利用一个小例子来综合使用上述的方法,假设图层上有个精灵,我手指触摸到哪,这个精灵的位置就在哪

首先在图层初始化的时候添加精灵

  1. // 图层的init方法
  2. -(id) init
  3. {
  4. if( (self=[super init])) {
  5. // 初始化一个精灵
  6. CCSprite *lufy = [CCSprite spriteWithFile:@"lufy.png"];
  7. CGSize size = [[CCDirector sharedDirector] winSize];
  8. lufy.position =  ccp(size.width * 0.5f, size.height * 0.5f);
  9. // 添加精灵,并设置标记
  10. [self addChild: lufy z:0 tag:kLufyTag];
  11. self.isTouchEnabled = YES;
  12. }
  13. return self;
  14. }

接下来是在图层中接收触摸输入

  1. // 计算触摸在图层中的位置(OpenGL坐标)
  2. - (CGPoint)locationInLayer:(NSSet *)touches {
  3. // 获取触摸对象
  4. UITouch *touch = [touches anyObject];
  5. // 获取触摸在UIView视图上的位置
  6. CGPoint uiPoint = [touch locationInView:touch.view];
  7. // 转换为OpenGL坐标
  8. CGPoint glPoint = [[CCDirector sharedDirector] convertToGL:uiPoint];
  9. return glPoint;
  10. }
  11. // 由于ccTouchesBegan、ccTouchesMoved、ccTouchesEnded中的做法都是一样,所以抽成一个方法
  12. - (void)dealTouches:(NSSet *)touches {
  13. // 计算触摸的位置
  14. CGPoint point = [self locationInLayer:touches];
  15. // 根据标记获取精灵
  16. CCSprite *lufy = (CCSprite *)[self getChildByTag:kLufyTag];
  17. // 设置精灵的位置
  18. lufy.position = point;
  19. }
  20. - (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  21. [self dealTouches:touches];
  22. }
  23. - (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  24. [self dealTouches:touches];
  25. }
  26. - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  27. [self dealTouches:touches];
  28. }

图层的触摸输入暂时讲到这里,其他高级的用法在后面会提及

2.接收加速计输入

CCLayer默认情况是不接收加速计输入的,需要显示地设置isAccelerometerEnabled为YES

  1. self.isAccelerometerEnabled = YES;

设置isAccelerometerEnabled为YES后,就会调用图层相应的方法来处理加速计输入:

这是在UIAccelerometerDelegate协议中定义的方法

  1. - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
  2. // typedef double UIAccelerationValue;
  3. UIAccelerationValue x =  acceleration.x;
  4. UIAccelerationValue y =  acceleration.y;
  5. UIAccelerationValue z =  acceleration.z;
  6. // x,y,z代表三维中任意方向的加速度
  7. }

CCLayerColor

有时候,我们想给整个图层设置一种背景颜色,那么就需要用到CCLayerColor了,CCLayerColor是CCLayer的子类

  1. // 红色:#ffff0000
  2. ccColor4B color = ccc4(255, 0, 0, 255);
  3. // 初始化一个颜色图层
  4. CCLayerColor *layerColor = [CCLayerColor layerWithColor:color];
  5. // 添加到场景中
  6. [scene addChild:layerColor];

效果图:

CCLayerGradient

CCLayerGradient是CCLayerColor的子类,可以给图层设置渐变色

  1. // 红色:#ffff0000
  2. ccColor4B red = ccc4(255, 0, 0, 255);
  3. // 蓝色:#ff0000ff
  4. ccColor4B blue = ccc4(0, 0, 255, 255);
  5. // 初始化一个渐变图层,从红色渐变到蓝色
  6. CCLayerGradient *layerGradient = [CCLayerGradient layerWithColor:red fadingTo:blue];
  7. // 添加到场景中
  8. [scene addChild:layerGradient];

效果图:

CCLayerMultiplex

CCLayerMultiplex继承自CCLayer,称为"多重图层"。它可以包含多个CCLayer对象,但在任意时刻只可以有一个CCLayer处于活动状态,用switchTo:和switchToAndReleaseMe:方法可以让某个图层处于活动状态,区别在于switchToAndReleaseMe:方法会先释放当前处于活动状态的图层,再让参数中要求的图层处于活动状态

  1. // 创建2个图层
  2. CCLayer *layer1 = [CCLayer node];
  3. CCLayer *layer2 = [CCLayer node];
  4. // 创建一个多重图层,包含了layer1和layer2
  5. CCLayerMultiplex *plex = [CCLayerMultiplex layerWithLayers:layer1, layer2, nil];
  6. // 让layer1处于活动状态(layer2还在内存中)
  7. [plex switchTo:0];
  8. // 让layer2处于活动状态(layer1还在内存中)
  9. [plex switchTo:1];
  10. // 释放当前处于活动状态的layer2(layer2从内存中移除),然后让layer1处于活动状态
  11. [plex switchToAndReleaseMe:0];

图层之间的切换是没有过渡效果的

六、CCLayer的更多相关文章

  1. cocos2D(六)----CCLayer

    一个游戏中能够有非常多个场景,每一个场景里面又可能包括有多个图层,这里的图层一般就是CCLayer对象.CCLayer本身差点儿没什么功能.对照CCNode,CCLayer可用于接收触摸和加速计输入. ...

  2. CCScene,CCLayer,CCSprite,CCDirector

    一.CCScene : 游戏中不同的画面可以用不同的场景展示出来,大致的可以分为以下的几类场景: 1. 展示类场景.游戏开场画面,游戏简介,胜利以及失败提示,帮助. 2. 选择类场景.主菜单,游戏设置 ...

  3. 如何一步一步用DDD设计一个电商网站(六)—— 给购物车加点料,集成售价上下文

    阅读目录 前言 如何在一个项目中实现多个上下文的业务 售价上下文与购买上下文的集成 结语 一.前言 前几篇已经实现了一个最简单的购买过程,这次开始往这个过程中增加一些东西.比如促销.会员价等,在我们的 ...

  4. MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息

    MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二 ...

  5. 【原】AFNetworking源码阅读(六)

    [原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...

  6. CRL快速开发框架系列教程六(分布式缓存解决方案)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  7. 【微信小程序开发•系列文章六】生命周期和路由

    这篇文章理论的知识比较多一些,都是个人观点,描述有失妥当的地方希望读者指出. [微信小程序开发•系列文章一]入门 [微信小程序开发•系列文章二]视图层 [微信小程序开发•系列文章三]数据层 [微信小程 ...

  8. 我的MYSQL学习心得(六) 函数

    我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  9. 我的MYSQL学习心得(十六) 优化

    我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

随机推荐

  1. lock关键字理解

    >可以把lock关键字可以看成 try{ Monitor.Enter(x); //.. } finally{ Monitor.Exit(x); } 这样子的结构,当然使用lock关键字更方便 & ...

  2. BZOJ3206 [Apio2013]道路费用

    首先我们强制要求几条待定价的边在MST中,建出MST 我们发现这个MST中原来的边是一定要被选上的,所以可以把点缩起来,搞成一棵只有$K$个点的树 然后$2^K$枚举每条边在不在最终的MST中,让在最 ...

  3. Log4J实用配置指南

    转自:http://www.cnblogs.com/licheng/archive/2008/08/23/1274566.html 1         概述 本文档是针对Log4j日志工具的使用指南. ...

  4. Kafka简要图解

    LinkedIn贡献的分布式消息系统 - 请参考这里 kafka集群:producer写入消息,consumer读取消息 消息分为不同主题,每个主题可以分为多个partition(并行),每个part ...

  5. [Js]跟随鼠标移动的div

    例子:鼠标移动到一块东西上,出现提示文本框,并且提示文本框跟着鼠标的位置动 document.onmouseover=function(ev){ var oEvent=ev||event; var b ...

  6. for update造成的Oracle锁表与解锁

    我遇到的情况: 当使用select语句查询表时,后面跟着for update , select * from table for update 当修改表中数据,但是没有commit就关掉PL/SQL, ...

  7. 精华 ionic入门之色彩、图标、边距和界面组件:列表

    目录:色彩.图标和边距色彩图标内边距界面组件:列表列表:.list成员容器:.item.item: 嵌入文本.item : 嵌入图标.item : 嵌入头像.item : 嵌入缩略图.item : 嵌 ...

  8. C#操作Access数据库(创建&修改结构)

    本文转自:http://www.cnblogs.com/liyugang/archive/2012/11/17/2775393.html 想要在程序中控制Access,不是数据,而是Access数据库 ...

  9. iOS开发中关于nslog的几种流行做法小结

    不管哪种方法,都必须在PCH文件中做下宏定义 DEBUG和RELEASE要分开,RELEASE时log打印要取消 方法一:简单直接,用几行代码搞定,简洁但功能少 #ifdef DEBUG #defin ...

  10. 记录一些容易忘记的属性 -- NSTimer

    使定时器停止的方法: 1. //将定时器的启动时间设置为很久以后的将来,到这个时间,定时器才会开始工作            [_timer setFireDate:[NSDate distantFu ...