《Cocos2D-x权威指南》——3.4 布景层类

3.4 布景层类

布景层类CCLayer是CCNode类的子类,并且在此基础上实现触屏事件代理(TouchEventsDelegate)协议,可以实现CCNode类的功能,并且可以处理输入,包括触屏和加速度传感器。
每个游戏场景中可以有很多层,每一层负责各自的任务,如专门负责显示地图的背景、专门负责显示敌人、专门负责机关和专门负责主角等;每一层上可以放置不同的元素,包括文本、精灵图片和菜单等。通过层与层之间的组合关系,就可以构成游戏显示的界面UI,游戏中等。当然为了看到每一层的东西,可把一些层设置为透明或半透明的,这样就可以看到不同布景层叠加到一起的效果了。CCLayer类的继承关系如图3-12所示。

由图3-12可以看出CCLayer类继承自CCNode类,并且CCLayer类还遵照触屏代理协议、加速度传感器代理协议、键盘时间代理协议等协议。除此之外,CCLayer类还有子类,如图3-13所示。

这些子类的功能如表3-8所示。

首先来看CCLayer类的使用,然后再来看主要的子类使用。
3.4.1 CCLayer类的函数
CCLayer类的主要函数如表3-9所示。

来看Cocos2D-x的HelloWorld项目中的HelloWorldScene.cpp文件,scene函数定义CCLayer类并把它加入场景中,如代码清单3-16所示。
代码清单3-16 scene函数定义CCLayer类并把它加入场景中

CCScene* HelloWorld::scene()
{
    //新建场景类实例
    CCScene *scene = CCScene::create();

    //定义布景层
    HelloWorld *layer = HelloWorld::create();

    //将布景层加入场景
    scene->addChild(layer);

    //返回场景类
    return scene;
}

CCLayer类的init函数在创建布景层时被调用,如代码清单3-17所示。
代码清单3-17 CCLayer类的init函数

bool HelloWorld::init()
{
    if ( !CCLayer::init() )
    {
        return false;
    }
    CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
                                        "CloseNormal.png",
                                        "CloseSelected.png",
                                        this,
    menu_selector(HelloWorld::menuCloseCallback) );
    pCloseItem->setPosition( ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20) );
    CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
    pMenu->setPosition( CCPointZero );
    this->addChild(pMenu, 1);
    CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24);
    CCSize size = CCDirector::sharedDirector()->getWinSize();
    pLabel->setPosition( ccp(size.width / 2, size.height - 50) );
    this->addChild(pLabel, 1);
    CCSprite* pSprite = CCSprite::create("HelloWorld.png");
    pSprite->setPosition( ccp(size.width/2, size.height/2) );
    this->addChild(pSprite, 0);

    return true;
}

本书将在后面介绍具体显示在层次上的对象,目前只需要了解在init函数中定义要显示的对象并把它作为子类加入场景中。另外,关于触屏、键盘、加速度传感器等输入,将在后面的章节介绍。本节后面将介绍CCLayer类的子类。
3.4.2 颜色布景层类CCLayerColor
颜色布景层类CCLayerColor是CCLayer类的子类,包含CCLayer类的特性,并且有两个拓展功能:可以为布景层增添颜色,以及设置不透明度。
首先看CCLayerColor类的定义初始化,如代码清单3-18所示。这段代码是tests项目下LayerTest.cpp文件中LayerTest1的onEnter函数。

代码清单3-18 CCLayerColor类的定义初始化

void LayerTest1::onEnter()
{
    LayerTest::onEnter();

    setTouchEnabled(true);

    CCSize s = CCDirector::sharedDirector()->getWinSize();
    CCLayerColor* layer = CCLayerColor::create( ccc4(0xFF, 0x00, 0x00, 0x80), 200, 200); 

    layer->ignoreAnchorPointForPosition(false);
    layer->setPosition( CCPointMake(s.width/2, s.height/2) );
    addChild(layer, 1, kTagLayer);
}

create函数的第一个参数是颜色的ARGB值,使用ccc4定义,其中第一个参数是颜色a值,第二个参数是R值,第三个参数是G值,最后一个参数是B值。除此之外,create函数的后两个参数是布景层的宽和高。
另外,使用ignoreAnchorPointForPosition将忽略锚点置为false。由于默认设置是忽略锚点,也就是以左下角为锚点,可以让布景层考虑锚点的影响(关于锚点在之前已经介绍过),这时默认的锚点在中心。运行效果如图3-14所示。

另外,LayerTest.cpp文件中的LayerTest1的updateSize函数中,可以修改颜色布景层的大小,如代码清单3-19所示。
代码清单3-19 修改颜色布景层的大小

void LayerTest1::updateSize(CCPoint &touchLocation)
{
    CCSize s = CCDirector::sharedDirector()->getWinSize();

    CCSize newSize = CCSizeMake( fabs(touchLocation.x - s.width/2)2, fabs(touchLocation.y - s.height/2)2);

    CCLayerColor l = (CCLayerColor) getChildByTag(kTagLayer);

    l->setContentSize( newSize );
}

通过setContentSize可以设置颜色布景层的大小。对于CCLayerColor类来说,还有一个比较常用的函数setBlendFunc,可以让布景层的颜色产生渐变效果。比如,需要在整屏添加全屏的一些覆盖效果、全屏变黑或者全屏变暗时,都可以使用这个方法。代码清单3-20所示是tests项目LayerTestBlend类中的newBlend函数,也就是使用setBlendFunc的示例。
代码清单3-20 使用setBlendFunc的示例

void LayerTestBlend::newBlend(float dt)
{
     CCLayerColor layer = (CCLayerColor)getChildByTag(kTagLayer);

    GLenum src;
    GLenum dst;

    if( layer->getBlendFunc().dst == GL_ZERO )
    {
        src = GL_SRC_ALPHA;
        dst = GL_ONE_MINUS_SRC_ALPHA;
    }
    else
    {
        src = GL_ONE_MINUS_DST_COLOR;
        dst = GL_ZERO;
    }

    ccBlendFunc bf = {src, dst};
    layer->setBlendFunc( bf );
}

传入的参数是一个有起始效果和结束效果的参数,运行之后的效果如图3-15和图3-16所示。

CCLayerColor类作为一个带颜色的布景层,在开发中可以给我们做特效带来方便。下一节介绍多层布景层类。
3.4.3 多层布景层类CCLayerMultiplex
在游戏开发中,一般会把游戏分为两部分:一部分是游戏界面部分,也就是常说的UI部分(User Interface,用户界面);另一部分就是游戏本身部分。有时UI有很多页面,在页面中用的图也并不是很多,不需要使用切换场景,只需把不同页面做成不同的布景层,然后切换布景层。那么这就需要一个“管理者”来管理这些界面,这时候就要使用CCLayerMultiplex类。
在很多游戏中都需要在不同的界面中使用相同的几个变量,如果不这样做,就需要做大量的保存工作。
tests项目中MenuTest.cpp的MenuTestScene类的runThisTest函数中有CCLayerMultiplex类的定义初始化方法,如代码清单3-21所示。
代码清单3-21 CCLayerMultiplex类的定义初始化

void MenuTestScene::runThisTest()
{
    CCLayer* pLayer1 = new MenuLayerMainMenu();
    CCLayer* pLayer2 = new MenuLayer2();
    CCLayer* pLayer3 = new MenuLayer3();
    CCLayer* pLayer4 = new MenuLayer4();
    CCLayer* pLayer5 = new MenuLayerPriorityTest();

    CCLayerMultiplex* layer = CCLayerMultiplex::create(pLayer1, pLayer2, pLayer3, pLayer4, pLayer5, NULL);
    addChild(layer, 0); 

    pLayer1->release();
    pLayer2->release();
    pLayer3->release();
    pLayer4->release();
    pLayer5->release();

    CCDirector::sharedDirector()->replaceScene(this);
}

首先定义并初始化每个布景层类,然后将这些布景层实例以参数形式传给CCLayerMultiplex的create函数,最后以NULL(空)结束。
这里在传入参数之后将这些布景层实例的指针释放,是为了防止内存泄露。至于Cocos2D-x的内存管理,本书将会在后面的章节介绍。
然后把CCLayerMultiplex实例作为子节点传入场景中,最后运行场景。代码清单3-22所示是切换布景层的switchTo函数使用方法。
代码清单3-22 switchTo函数使用方法

void MenuLayerPriorityTest::menuCallback(CCObject* pSender)
{
    ((CCLayerMultiplex*)m_pParent)->switchTo(0);
}

由于这个函数被CCLayerMultiplex实例的子布景,即初始化CCLayerMultiplex传入的布景类实例调用,所以它的m_pParent父节点就是CCLayerMultiplex实例本身。获得CCLayerMultiplex实例指针后,调用switchTo函数就可以转换到相应的子布景中。关于子布景中显示的菜单,下一节将会介绍。
3.4.4 菜单类CCMenu
游戏中常用的菜单如图3-17所示,其中菜单项可以是图片、系统字,或者自定义的字体。

CCMenu是一个菜单项的容器,用来装载各种菜单项。代码清单3-23就是一个定义CCMenu类实例的过程,是tests项目中MenuTest.cpp的MenuLayer2的构造函数。
代码清单3-23 定义CCMenu类实例

MenuLayer2::MenuLayer2()
{
    for( int i=0;i < 2;i++ )
    {
        CCMenuItemImage* item1 = CCMenuItemImage::create(s_PlayNormal, s_PlaySelect, this, menu_selector(MenuLayer2::menuCallback));
        CCMenuItemImage* item2 = CCMenuItemImage::create(s_HighNormal, s_HighSelect, this, menu_selector(MenuLayer2::menuCallbackOpacity) );
        CCMenuItemImage* item3 = CCMenuItemImage::create(s_AboutNormal, s_AboutSelect, this, menu_selector(MenuLayer2::menuCallbackAlign) );

        item1->setScaleX( 1.5f );
        item2->setScaleX( 0.5f );
        item3->setScaleX( 0.5f );

        CCMenu* menu = CCMenu::create(item1, item2, item3, NULL);

        CCSize s = CCDirector::sharedDirector()->getWinSize();
        menu->setPosition(ccp(s.width/2, s.height/2));
        menu->setTag( kTagMenu );

        addChild(menu, 0, 100+i);

        m_centeredMenu = menu->getPosition();
    }

    m_alignedH = true;
    alignMenusH();
}

首先定义菜单项(关于菜单项,本书会在后面的章节中做讲解),然后用它们定义初始化菜单CCMenu实例,最后将CCMenu实例加入CCLayer中显示出来,效果如图3-18所示。
菜单类还提供了alignItemsVertically和align-ItemsHorizontally等函数。如代码清单3-24所示,tests项目中MenuTest.cpp的MenuLayer2的构造函数alignMenusH就是alignItems-Horizontally水平对齐两种方法对比,一种是alignItems-Horizontally水平对齐,底下是alignItemsHorizontallyWithPadding留空间水平对齐,效果对比请见之前的图3-18。
代码清单3-24 对齐方法对比函数

void MenuLayer2::alignMenusH()
{
    for(int i=0;i<2;i++)
    {
        CCMenu menu = (CCMenu)getChildByTag(100+i);
        menu->setPosition( m_centeredMenu );
        if(i==0)
        {
            // TIP: if no padding, padding = 5
            menu->alignItemsHorizontally();
            CCPoint p = menu->getPosition();
            menu->setPosition( ccpAdd(p, CCPointMake(0,30)) );

        }
        else
        {
            // TIP: but padding is configurable
            menu->alignItemsHorizontallyWithPadding(40);
            CCPoint p = menu->getPosition();
            menu->setPosition( ccpSub(p, CCPointMake(0,30)) );
        }
    }
}

使用方法比较简单,直接调用就可以。下一节介绍Cocos2D-x中的UI控件。
3.4.5 控件类及其子类
在应用的开发中,无论是Android操作系统还是iOS操作系统,其开发框架都提供了控件,包括按键、拖动滑块等,这样提高了开发效率。对于游戏的开发,UI的开发同样需要控件来提高开发效率。对Cocos2D-x来说,从2.0版本开始提供了很多控件类来帮助我们更好地开发UI。
1 . 拖动滑块的控件类CCControlSlider
首先来看拖动滑块的控件类CCControlSlider。tests项目中ControlExtensionTest\CCControl-SliderTest目录下CCControlSliderTest.cpp中的代码如代码清单3-25所示。
代码清单3-25 定义并初始化CCControlSliderTest类实例

bool CCControlSliderTest::init()
{
    if (CCControlScene::init())
    {
        CCSize screenSize = CCDirector::sharedDirector()->getWinSize();
        //定义标签的代码,考虑到篇幅而被省略
       ...
        //定义CCControlSlider
        CCControlSlider *slider = CCControlSlider::create("extensions/sliderTrack.png","extensions/sliderProgress.png" ,"extensions/sliderThumb.png");
        slider->setAnchorPoint(ccp(0.5f, 1.0f));
        slider->setMinimumValue(0.0f); // 设置范围最小值
        slider->setMaximumValue(5.0f); // 设置范围最大值
        slider->setPosition(ccp(screenSize.width / 2.0f, screenSize.height / 2.0f));
        //添加回调函数,当滑块被拖动时被调用
        slider->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlSliderTest::valueChanged), CCControlEventValueChanged);
        addChild(slider);
        return true;
    }
    return false;
}
void CCControlSliderTest::valueChanged(CCObject *sender, CCControlEvent controlEvent)
{
    CCControlSlider pSlider = (CCControlSlider)sender;
m_pDisplayValueLabel->setString(CCString::createWithFormat("Slider value = %.02f", pSlider->getValue())->getCString());
}

要定义拖动滑块对象,首先调用create函数,参数为图片路径,分别是滑块滑道图片路径、滑块滑动后覆盖滑道图片路径和滑块图片路径;之后设置锚点,并设置范围最小值和设置范围最大值,设置位置后给拖动注册拖动事件接受函数。在拖动事件中,可以通过pSlider->getValue())->getCString()来获取目前所在位置的值,运行效果如图3-19所示。

2 . 颜色选择盘类CCControlColourPicker
颜色选择盘类CCControlColourPicker的定义和初始化如代码清单3-26所示。代码在tests项目中ControlExtensionTest\ CCControl-ColourPickerTest目录下的CCControlColourPicker-Test.cpp文件中。
代码清单3-26 CCControlColourPicker类的定义和初始化

bool CCControlColourPickerTest::init()
{
    if (CCControlScene::init())
    {
        CCSize screenSize = CCDirector::sharedDirector()->getWinSize();

        CCNode *layer  = CCNode::create();
        layer->setPosition(ccp (screenSize.width / 2, screenSize.height / 2));
        addChild(layer, 1);

        double layer_width = 0;

        //定义并初始化颜色选择盘
        CCControlColourPicker *colourPicker = CCControlColourPicker::create();
        colourPicker->setColor(ccc3(37, 46, 252));
        colourPicker->setPosition(ccp (colourPicker->getContentSize().width / 2, 0));
        //添加到层次中
        layer->addChild(colourPicker);
        //注册事件
        colourPicker->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlColourPickerTest::colourValueChanged), CCControlEventValueChanged);
        //以下定义其他控件的代码省略
       ...
        return true;
    }
    return false;

}
void CCControlColourPickerTest::colourValueChanged(CCObject *sender, CCControlEvent controlEvent)
{
    CCControlColourPicker pPicker = (CCControlColourPicker)sender;
    m_pColorLabel->setString(CCString::createWithFormat("#%02X%02X%02X",pPicker->getColorValue().r, pPicker->getColorValue().g, pPicker->getColorValue().b)->getCString());
}

首先定义CCControlColourPicker,直接调用create函数就可以。这里需要把tests\Resources\extensions目录下和CCControlColour-Picker相关的文件复制到Resources\extensions目录,然后定义初始颜色,加入父节点中,并注册回调函数。回调函数通过pPicker->getColorValue().g, pPicker->getColorValue().b)->getCString()获得相应的颜色值字符串。运行效果如图3-20所示。

3 . 开关按钮类CCControlSwitch
开关按钮类CCControlSwitch的定义和初始化如代码清单3-27所示。代码在tests项目中的ControlExtensionTest\ CCControlSwitchTest目录下的CCControlSwitchTest.cpp中。
代码清单3-27 CCControlSwitch的定义和初始化

bool CCControlSwitchTest::init()
{
    if (CCControlScene::init())
    {
        //定义其他控件,代码省略
       ...
        // 定义开关控件
        CCControlSwitch *switchControl = CCControlSwitch::create
            (
                CCSprite::create("extensions/switch-mask.png"),
                CCSprite::create("extensions/switch-on.png"),
                CCSprite::create("extensions/switch-off.png"),
                CCSprite::create("extensions/switch-thumb.png"),
                CCLabelTTF::create("On", "Arial-BoldMT", 16),
                CCLabelTTF::create("Off", "Arial-BoldMT", 16)
            );
        switchControl->setPosition(ccp (layer_width + 10 + switchControl->getContentSize().width / 2, 0));
        layer->addChild(switchControl);
        switchControl->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlSwitchTest::valueChanged), CCControlEventValueChanged);
        //定义其他控件,代码省略
        ...
        return true;
    }
    return false;
}

要定义开关对象,首先调用create函数,参数为图片路径和上面的文字标签。图片路径分别是背景图片路径、开状态背景图片路径、关状态背景图片路径和开关背景图片路径,文字标签是开文字标签、关文字标签。设置位置加入布景层后定义回调函数。运行效果如图3-21所示。

4 . 按钮类CCControlButton
按钮类CCControlButton的定义和初始化如代码清单3-28所示。代码是tests项目中ControlExtensionTest \ CCControlButtonTest目录下CCControlButtonTest.cpp中的CCControlButtonTest_Event的init函数。
代码清单3-28 CCControlButton的定义和初始化

bool CCControlButtonTest_Event::init()
{
    if (CCControlScene::init())
    {
       //定义其他控件,代码省略
       ...
        //定义并初始化按钮
        CCControlButton *controlButton = CCControlButton::create(titleButton, backgroundButton);
        controlButton->setBackgroundSpriteForState(backgroundHighlightedButton, CCControlStateHighlighted);
        controlButton->setTitleColorForState(ccWHITE, CCControlStateHighlighted);

        controlButton->setAnchorPoint(ccp(0.5f, 1));
        controlButton->setPosition(ccp(screenSize.width / 2.0f, screenSize.height / 2.0f));
        addChild(controlButton, 1);
        //定义其他控件,代码省略
        ...
        //加入回调函数
        controlButton->addTargetWithActionForControlEvent(this, cccontrol_selector(CCControlButtonTest_Event::touchDownAction), CCControlEventTouchDown);
        controlButton->addTargetWithActionForControlEvent(this, cccontrol_selector(CCControlButtonTest_Event::touchDragInsideAction), CCControlEventTouchDragInside);
        controlButton->addTargetWithActionForControlEvent(this, cccontrol_selector(CCControlButtonTest_Event::touchDragOutsideAction), CCControlEventTouchDragOutside);
        controlButton->addTargetWithActionForControlEvent(this, cccontrol_selector(CCControlButtonTest_Event::touchDragEnterAction), CCControlEventTouchDragEnter);
        controlButton->addTargetWithActionForControlEvent(this, cccontrol_selector(CCControlButtonTest_Event::touchDragExitAction), CCControlEventTouchDragExit);
        controlButton->addTargetWithActionForControlEvent(this, cccontrol_selector(CCControlButtonTest_Event::touchUpInsideAction), CCControlEventTouchUpInside);
        controlButton->addTargetWithActionForControlEvent(this, cccontrol_selector(CCControlButtonTest_Event::touchUpOutsideAction), CCControlEventTouchUpOutside);
        controlButton->addTargetWithActionForControlEvent(this, cccontrol_selector(CCControlButtonTest_Event::touchCancelAction), CCControlEventTouchCancel);
        return true;
    }
    return false;
}

要定义按钮对象,首先调用create函数。该函数传入的参数可以是图片的路径,也可以是精灵对象。两个参数代表的分别是按钮标题字和背景。之后可以设置按钮的参数,包括设置按钮位置和加入定义的回调函数等。这里的回调函数可以有多个,根据需要的操作定义,包括按下、拖动和抬起等。运行效果如图3-22所示。

本节介绍了Cocos2D-x的布景层类和它的子类,下节开始介绍精灵类及其子类。

时间: 2024-10-16 06:00:40

《Cocos2D-x权威指南》——3.4 布景层类的相关文章

《Cocos2D-x权威指南》——导读

前言 为什么要写这本书 在大学期间,我开始对移动游戏开发感兴趣,于是开始学习移动开发方面的相关知识,包括J2ME和Android等技术.现在,开始的好奇心和兴趣成就了我引以为豪的事业.在大四的时候,我到了天津猛犸实习,从J2ME平台到Android平台,从Android平台到iOS平台,我不仅接触了不同平台的开发,更学会了游戏开发的技巧和思想.如果说编程是一门艺术,那么游戏开发就是艺术中的艺术.作为一名游戏开发程序员,不仅要拥有熟练的编程技巧,还要对美术.策划和游戏有深入的理解.游戏程序员最重要

《Cocos2D-x权威指南》——3.3 场景类

3.3 场景类 CCScene类是CCNode的子类.和CCNode相比,它只是添加了一个特性,那就是拥有自己的锚点,位置在屏幕的正中央.除此之外,它目前还没有额外的功能,只是一个抽象的概念. 3.1节中介绍CCNode类时,把屏幕上所有显示对象的父节点设置为我们定义的节点,这个父节点的角色一般由场景承担.CCScene类的继承关系如图3-9所示. 可以看到,CCScene类有CCTransitionScene(切换场景类),并且CCTransitionScene类有很多子类,这些类都用于切换场

《Cocos2D-x权威指南》——3.11 本章小结

3.11 本章小结 本章介绍了Cocos2D-x的一些基本的类,包括CCNode类,它是一个没有贴图的类:后面介绍了构成游戏的CCScene类和CCLayer类,并且介绍了布景层类的子类:然后介绍了CCSprite类和它的相关类,并介绍了渲染节点的关键类CCCamera类:最后介绍了容器类和时间调度的内容.学完本章内容,可以根据示例和知识,自己写一些小程序.第4章将介绍动作类和动画方面的知识,你的"精灵"可以动起来了.

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

3.4 CCLayer层类 一个CCLayer是屏幕上可绘制的区域,可以是半透明的,这样就可以看到CCScene下面的其他层.在游戏编程的过程中,开发者大部分时间都需要跟层打交道.如图3-5所示,一个游戏场景包含3个层,背景层.动画层和菜单层. CCLayer直接继承自CCNode,作为精灵节点和其他节点的容器,它同时可以接收触摸输入和加速计输入的信息,前提是上述接收功能已经启用.3.4.1 CCLayer类的作用 CCLayer类的作用主要有三个. (1)其他子节点的容器和组织者 例如对一个层

《Cocos2D权威指南》——导读

前言 为什么要写这本书 2011年10月5日,秋风萧瑟,阴雨绵绵,在这颗蔚蓝色的美丽星球上,一代传奇伟人乔布斯在亲友的陪伴下安然离去,宛若流星划过天际,空留那辆银色的奔驰SL55AMG在落叶纷飞中孤独守候着曾经的主人.这个世界从此失去了一位引领科技创新的时代领袖. 从1976年在父母的车库中创业开始,乔布斯参与.开创并改变了几个行业-PC.电脑动画.数字音乐.移动互联网.他创办了苹果公司,中途又因某些原因被苹果驱逐.然而在苹果挣扎于濒死的边缘时,他又挺身而出将苹果救活,并把它推到无人可以企及的高

Ansible权威指南.

Linux/Unix技术丛书 Ansible权威指南 李松涛 魏 巍 甘 捷 著 图书在版编目(CIP)数据 Ansible权威指南 / 李松涛,魏巍,甘捷著. -北京:机械工业出版社,2016.11 (Linux/Unix技术丛书) ISBN 978-7-111-55329-8 I. A- II. ①李- ②魏- ③甘- III. 程序开发工具-指南 IV. TP311.561-62 中国版本图书馆CIP数据核字(2016)第258615号 Ansible权威指南 出版发行:机械工业出版社(北

《Windows 8 权威指南》——1.5 版本对比

1.5 版本对比 Windows 8 权威指南 当今电脑操作系统有许多的分支,总而言之分为三部分.其一是微软代表的Windows系统家族:其二是UNIX以及其分支Linux:其三就是苹果的Mac Os.本章我们主要对比一下Windows的几个版本之间的差别以及与Linux版本中最具代表性的Ubuntu的差别. 1.5.1 Ubuntu 12.04与Windows 8的对比 Ubuntu是目前最流行的Linux操作系统之一,最新的版本更新到了12.04.本节我们从以下几个方面来对比一下Window

《Netty权威指南》目录

<Netty权威指南>是全球第二本.中国第一本Netty教材,它由华为平台中间件资深架构设计师李林锋撰写,作者有6年多的NIO设计和开发实战经验,多次受邀进行Netty和 NIO编程培训. 本书基于最新的Netty5.0 版本撰写,从Netty开发环境的搭建,到第一个基于Netty的NIO服务端和客户端程序的开发,一步步的让读者从入门到精通,熟练的掌握基于Netty 的NIO开发,理解Netty的架构设计原理,可以对Netty进行深度的定制设计和开发. 本书共分为五部分:第一部分介绍 JAVA

快速阅读《POSTFIX权威指南》

今天,一直想系统了解一下POSTFIX,本想买本书,结果当当,京东都没有...唯一的一本<POSTFIX权威指南>还断货了. 那只好网上下载下来看了...ISHARE上就有,近三百页.今天看到快一百页了. 挺细致的. 有志于了解邮件系统的,推荐此书..因为它不只是单讲POSTFIX..... 关于MUA,MTA,MDA,全盖... ~~~~~~~~~~ 广告: 想要自己架设邮件服务器吗?如果sendmail让你头痛万分,现在你有更好的选择 -- Postfix.安全的结构设计与优异的可靠性,使