博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CCLayer
阅读量:5953 次
发布时间:2019-06-19

本文共 4317 字,大约阅读时间需要 14 分钟。

hot3.png

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

常用设置

1.接收触摸输入

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

[java] 

  1. self.isTouchEnabled = YES;  

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

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

1> 当单指接触到屏幕时

[java] 

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

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

[java] 

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

3> 当单指离开屏幕时

[java] 

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

4> 当触摸被取消时

[java] 

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

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

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

比如在手指移动过程中:

[java] 

  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. }  

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

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

[java] 

  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.           

  12.         self.isTouchEnabled = YES;  

  13.     }  

  14.     return self;  

  15. }  

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

[java] 

  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.       

  10.     return glPoint;  

  11. }  

  12.   

  13. // 由于ccTouchesBegan、ccTouchesMoved、ccTouchesEnded中的做法都是一样,所以抽成一个方法  

  14. - (void)dealTouches:(NSSet *)touches {  

  15.     // 计算触摸的位置  

  16.     CGPoint point = [self locationInLayer:touches];  

  17.     // 根据标记获取精灵  

  18.     CCSprite *lufy = (CCSprite *)[self getChildByTag:kLufyTag];  

  19.     // 设置精灵的位置  

  20.     lufy.position = point;  

  21. }  

  22.   

  23. - (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {  

  24.     [self dealTouches:touches];  

  25. }  

  26.   

  27. - (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {  

  28.     [self dealTouches:touches];  

  29. }  

  30.   

  31. - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {  

  32.     [self dealTouches:touches];  

  33. }  

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

2.接收加速计输入

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

[java] 

  1. self.isAccelerometerEnabled = YES;  

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

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

[java] 

  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的子类

[java] 

  1. // 红色:#ffff0000  

  2. ccColor4B color = ccc4(25500255);  

  3. // 初始化一个颜色图层  

  4. CCLayerColor *layerColor = [CCLayerColor layerWithColor:color];  

  5. // 添加到场景中  

  6. [scene addChild:layerColor];  

效果图:

CCLayerGradient

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

[java] 

  1. // 红色:#ffff0000  

  2. ccColor4B red = ccc4(25500255);  

  3. // 蓝色:#ff0000ff  

  4. ccColor4B blue = ccc4(00255255);  

  5. // 初始化一个渐变图层,从红色渐变到蓝色  

  6. CCLayerGradient *layerGradient = [CCLayerGradient layerWithColor:red fadingTo:blue];  

  7. // 添加到场景中  

  8. [scene addChild:layerGradient];  

效果图:

CCLayerMultiplex

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

[java] 

  1. // 创建2个图层  

  2. CCLayer *layer1 = [CCLayer node];  

  3. CCLayer *layer2 = [CCLayer node];  

  4.   

  5. // 创建一个多重图层,包含了layer1和layer2  

  6.   

  7. CCLayerMultiplex *plex = [CCLayerMultiplex layerWithLayers:layer1, layer2, nil];  

  8.   

  9. // 让layer1处于活动状态(layer2还在内存中)  

  10. [plex switchTo:0];  

  11.   

  12. // 让layer2处于活动状态(layer1还在内存中)  

  13. [plex switchTo:1];  

  14.   

  15. // 释放当前处于活动状态的layer2(layer2从内存中移除),然后让layer1处于活动状态  

  16. [plex switchToAndReleaseMe:0];   

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

转载于:https://my.oschina.net/u/1244156/blog/200044

你可能感兴趣的文章
切图崽的自我修养-[ES6] 编程风格规范
查看>>
[React Native Android 安利系列]样式与布局的书写
查看>>
利用dxflib读写cad文件
查看>>
服务器迁移小记
查看>>
FastDFS存储服务器部署
查看>>
Android — 创建和修改 Fragment 的方法及相关注意事项
查看>>
流程控制: jQ Deferred 与 ES6 Promise 使用新手向入坑!
查看>>
swift基础之_swift调用OC/OC调用swift
查看>>
Devexpress 15.1.8 Breaking Changes
查看>>
推荐JS插件:imagesLoaded,监测图片加载情况并提供相应的事件(加载成功/失败)...
查看>>
Java B2B2C多用户商城 springcloud架构- common-service 项目构建过程(七)
查看>>
杨老师课堂之ArrayList集合常用方法解析
查看>>
ElasticSearch Client详解
查看>>
新零售讲堂之时代下的传统零售业,何去何从?
查看>>
c++读取和写入TXT文件的整理
查看>>
深入动态人脸识别小场景应用,2019年或将迎来爆发期
查看>>
Ionic2 下处理 Android 设备下返回按钮的事件
查看>>
linux安全问答(1)
查看>>
zabbix监控进程的CPU和内存占用量
查看>>
Error creating bean with name 'userServiceImpl': Injection of autowired dependencies failed
查看>>