且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

《Cocos2D权威指南》——3.4 CCLayer层类

更新时间:2022-09-20 22:11:45

3.4 CCLayer层类

一个CCLayer是屏幕上可绘制的区域,可以是半透明的,这样就可以看到CCScene下面的其他层。在游戏编程的过程中,开发者大部分时间都需要跟层打交道。如图3-5所示,一个游戏场景包含3个层,背景层、动画层和菜单层。

《Cocos2D权威指南》——3.4 CCLayer层类

CCLayer直接继承自CCNode,作为精灵节点和其他节点的容器,它同时可以接收触摸输入和加速计输入的信息,前提是上述接收功能已经启用。
3.4.1 CCLayer类的作用
CCLayer类的作用主要有三个。
(1)其他子节点的容器和组织者
例如对一个层使用动作,那么所有在这个层上的物体都会受到影响。这意味着同一层的所有物体可以一起移动、旋转和缩放。
如果这些物体都是同一个层的子节点,就可以通过改变层的属性或者在层上执行动作,从而影响层上所有子节点。
(2)接收触摸事件
设置isTouchEnabled为YES,可以让层接收触摸事件。示例代码如下:
self.isTouchEnabled = YES;
该属性***在init方法中设置。可以在任何时间将其设置为NO或者YES。
一旦启用isTouchEnabled属性,将会开始调用许多与接收触摸输入相关的方法。这些事件包括:当新的触摸事件开始时,当手指在触摸屏上移动时,以及当用户手指离开屏幕以后。
第6章将详细描述在Cocos2D中如何处理多点触摸事件。
(3)接收加速计事件
和触摸输入一样,加速计必须在启用以后才能接收加速计事件。示例代码如下:

self.isAccelerometerEnabled = YES;

同样地,层里需要加入一个特定的方法来接收加速计事件。下面是第2章中处理加速计事件的示例代码:

-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{
    float deceleration = 0.4f;
    float sensitivity = 6.0f;
    float maxVelocity = 100;
    _playerVelocity.x = _playerVelocity.x * deceleration + acceleration.x * sensitivity;
    if (_playerVelocity.x > maxVelocity) {
        _playerVelocity.x = maxVelocity;
    }else if(_playerVelocity.x < -maxVelocity){
        _playerVelocity.x = -maxVelocity;
    }
}

通过加速参数决定任意三个方向的加速度值。
第6章详细阐述在Cocos2D中如何处理加速计事件。
除了接收触摸事件和加速计事件,CCLayer还可以接收鼠标事件和键盘事件,当然对于iPhone开发来说没什么实际作用,不用花更多的时间来了解。
注意 CCLayer还有一个子类CCLayerMultipex,可以容纳多个层,但每次只可激活其中的一个。通常不鼓励使用CCLayerMultipex。
3.4.2 CCLayerColor色彩层
CCLayerColor是一个透明的、可以按照RGB设置填充颜色的层,是实现CCRGBAProtocol协议的CCLayer子类。它继承了CCNode所有属性和方法,同时还可以接收触摸事件和加速计事件。
1 . CCLayerColor类的属性
CCLayerColor具有如下属性:
color:色彩,其变量类型是ccColor3B(由3字节组成的色彩信息)。
opacity:透明度,其变量类型是Glubyte。
blendFunc:混合模式,其变量类型是ccBlendFunc。
2 . CCLayerColor类的方法
CCLayerColor的方法如下。
(1)–(id)initWithColor:(ccColor4B)color
该方法初始化一个带有色彩的CCLayer,其宽度和高度是窗口的宽度和高度。
(2)- (id) initWithColor:(ccColor4B) color

width: (GLfloat) w
       height:(GLfloat) h

该方法初始化一个带有色彩的CCLayer,并以点值指定宽度和高度。
(3)+ (id) layerWithColor: (ccColor4B)color
创建一个带有色彩的CCLayer,其宽度和高度是窗口的宽度和高度。示例代码如下:

CCLayerColor* layer1 = [CCLayerColor layerWithColor: ccc4(255, 255, 255, 80)];
(4)+ (id) layerWithColor:     (ccColor4B) color
       width: (GLfloat) w
       height:(GLfloat) h

该方法创建一个带有色彩的CCLayer,并以点值指定宽度和高度。示例代码如下:

CCLayerColor* layer1 = [CCLayerColor layerWithColor: ccc4(255, 255, 0, 80)
                            width: 100 
                            height: 300];

(5)-(void)changeWidth: (GLfloat) wheight: (GLfloat) h
该方法修改层的宽度和高度。示例代码如下:

[layerl changeWidth:newSize.width height:newSize.height];

在实际的使用中,我们可以用setContentSize方法替代该方法。
3.4.3 CCLayerGradient渐变色层
CCLayerColor有一个子类CCLayerGradient,可以在背景上绘制渐变色。CCLayerGradient继承了CCLayerColor的所有特性,增加了渐变方向、插值模式等属性。以下代码初始化带有特定渐变效果的色彩层。示例代码如下:

self = [super initWithColor:ccc4(238,238,238,255) fadingTo:ccc4(250,250,250,235) alongVector:ccp(0,-1)];

注意 扩展阅读:在结束本节的学习之前,需要对初始化方法有更清楚的认识。细心的读者可能已经发现,在Cocos2D中,每个初始化方法都分别提供了实例方法和类方法,那么它们在实际使用中的区别是什么呢?
在Xcode中打开安装Cocos2D时的模板cocos2d-ios工程,找到CCLayer.m文件,在CCLayerColor的实现代码中查看以下代码:

+ (id) layerWithColor:(ccColor4B)color width:(GLfloat)w  height:(GLfloat) h
{
    return [[[self alloc] initWithColor:color width:w height:h] autorelease];
}

很容易发现,类方法(静态方法)调用了实例方法来初始化对象,并创建一个自动释放内存的对象。也就是说,类方法把两步合成一步,它们在实际使用的区别也在于此。对于开发者来说,一般情况下只需直接使用类方法来创建对象即可。这里其实就是工厂方法模式,它可以为对象的创建提供一个简单一致的接口。为了简便起见,我们在后续章节中将不再对两者之间的区别重复说明。
3.4.4 CCMenu菜单类
Cocos2D中提供了内置的菜单系统,用来创建游戏中的各种菜单,包括主菜单、游戏设置等,而实现菜单系统的就是CCMenu类及其子类。学习本节内容时,请在Cocos2D模板的示例项目cocos2d-ios.xcodeproj中打开MenuTest.m,查看相关示例代码。
CCMenu继承自CCLayer,是一个菜单管理选择画面层,该画面以Menu对象为集合类,由MenuItem类实例组成各种按钮。CCMenu类提供的方法主要用来按横向、竖向或者多行列排序展示MenueItem的类实例。同时,CCMenu只支持CCMenuItem节点作为它的子节点。
注意 CCMenuItem是基础类,不能直接用来创建菜单,它的作用主要是设置按钮状态以及处理回调方法。需要使用CCMenuItem的子类来创建定制菜单项。
CCMenuItem类的子类如下:
(1)CCMenuItemLabel
CCMenuItemLabel内置Label对象,将一个基本的Label转变成为一个菜单项,增加选中时的文字放大效果。它支持三种标签类:CCLabelBMFont、CCLabelAtlas和CCLabelTTF。示例代码如下:

// Label Item (CCLabelBMFont)
CCLabelBMFont *label1 = [CCLabelBMFont labelWithString:@"Setting" fntFile:@"font1.fnt"];
    CCMenuItemLabel *item1 = [CCMenuItemLabel itemWithLabel:label1 target:self selector:@"menuCallBackSetting"];

(2)CCMenuItemAtlasFont
CCMenuItemAtlasFont直接继承自CCMenuItemLabel,将一个CCLabelAtlas转变为一个菜单项,增加选中时的文字放大效果。示例代码如下:

// Label Item (CCLabelAtlas)
CCLabelAtlas *labelAtlas = [CCLabelAtlas labelAtlasWithString:@"0123456789" charMapFile:@"fps_images.png" itemWidth:16 itemHeight:24 startCharMap:'.'];
    CCMenuItemLabel *item2 = [CCMenuItemLabel itemWithLabel:labelAtlas target:self selector:@selector(menuCallbackFun:)];
        item2.disabledColor = ccc3(10,20,39);
        item2.color = ccc3(10,220,255);

(3)CCMenuItemFont
CCMenuItemFont直接继承自CCMenuItemLabel,可以创建直接设置字体的菜单项(内部实现时依然用到Label对象)。示例代码如下:

[CCMenuItemFont setFontSize:30];
[CCMenuItemFont setFontName: @"Courier New"];
// Font Item
CCMenuItem *item3 = [CCMenuItemFont itemWithString: @"new items" target: self selector:@selector(menuCallbackNew:)];

以上三种字体型菜单项都是通过Label类及其派生类完成视觉呈现,借用父类CCMenuItem实现菜单项的回调方法。
(4)CCMenuItemSprite
CCMenuItemSprite内置三个CCNode对象,分别表示未选中、选中和禁止三个状态的图像,选中时没有特别的视觉效果。示例代码如下:

// Font Item
CCSprite *labelNormal = [CCSprite spriteWithFile:@"menuitem.png" rect:CGRectMake(0,30*2,120,30)];
    CCSprite *labelSelected = [CCSprite spriteWithFile:@"menuitem.png" rect:CGRectMake(0,30*1,120,30)];
    CCSprite *labelDisabled = [CCSprite spriteWithFile:@"menuitem.png" rect:CGRectMake(0,30*0,120,30)];
    CCMenuItemSprite *item4 = [CCMenuItemSprite itemWithNormalSprite:labelNormal selectedSprite:labelSelected disabledSprite:labelDisabled target:self selector:@selector(menuCallback:)];

(5)CCMenuItemImage
CCMenuItemImage继承自CCMenuItemSprite,包含三个对象,分别表示未选中、选中和禁止三个状态的图像。示例代码如下:

// Image Item
    CCMenuItem *item5 = [CCMenuItemImage itemWithNormalImage:"button1.png" selectedImage:@"button2.png" disabledImage:@"button3.png" target:self selector:@selector(menuCallback2:)];

(6)CCMenuItemToggle
CCMenuItemToggle支持内部一个MenuItem数组负责展示不同的状态,实现状态切换。示例代码如下:

CCMenuItemToggle *item1 = [CCMenuItemToggle itemWithTarget:self selector:@selector(menuCallback:) items:
                       [CCMenuItemFont itemWithString: @"On"],
                       [CCMenuItemFont itemWithString: @"Off"],
                       nil];

注意 从Cocos2D v2.0 开始,之前的itemFrom…方法全部更改为itemWith…方法。
如果想查看菜单的具体效果,可以运行Cocos2D官方模板项目cocos2d-ios.xcodeproj中的MenuTest测试,建议大家仔细分析MenuTest.m中的实现代码。