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

经常使用设置

1.接收触摸输入

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





[java] ​​view plain​ ​​​copy​



  1. self.isTouchEnabled = YES;  

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


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

1> 当单指接触到屏幕时





[java] ​​view plain​ ​​​copy​



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



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





[java] ​​view plain​ ​​​copy​



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



3> 当单指离开屏幕时





[java] ​​view plain​ ​​​copy​



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



4> 当触摸被取消时





[java] ​​view plain​ ​​​copy​



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

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


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

比方在手指移动过程中:





[java] ​​view plain​ ​​​copy​



  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] ​​view plain​ ​​​copy​



  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] ​​view plain​ ​​​copy​



  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] ​​view plain​ ​​​copy​



  1. self.isAccelerometerEnabled = YES;  

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


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





[java] ​​view plain​ ​​​copy​



  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] ​​view plain​ ​​​copy​



  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的子类,能够给图层设置渐变色





[java] ​​view plain​ ​​​copy​



  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:方法会先释放当前处于活动状态的图层,再让參数中要求的图层处于活动状态





[java] ​​view plain​ ​​​copy​



  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];