前言:

介绍cocos2d-x中的动作、特效。

动作:

动作(action)包括基本动作和基本动作的组合,这些基本动作有缩放、移动、旋转等,而且这些动作变化的速度也可以设定。

动作类是 Action。它的类图如下:

Action有3个子类,FiniteTimeAction 是一种受时间限制的动作,Follow 是一种允许精灵跟随另一个精灵的动作,Speed是在一个动作运行时改变其运动速率。

瞬时动作:

瞬时动作就是不等待立即执行的动作,瞬时动作的基类是ActionInstant。瞬时动作 ActionInstant 类图如下:

代码示例:

 #ifndef __HELLOWORLD_SCENE_H__
 #define __HELLOWORLD_SCENE_H__

 #include "cocos2d.h"
 #include "Action.h"

 typedef enum
 {
     PLACE_TAG = ,
     FLIPX_TAG,
     FLIPY_TAG,
     HIDE_SHOW_TAG,
     TOGGLE_TAG,
     OTHER_ACTION,
     All_TAG_NUM
 }ActionTypes;

 class HelloWorld : public cocos2d::Layer
 {
 public:
     // there's no 'id' in cpp, so we recommend returning the class instance pointer
     static cocos2d::Scene* createScene();

     // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
     virtual bool init();  

     // a selector callback
     void menuCloseCallback(cocos2d::Ref* pSender);

     void menuItemCallback_01(cocos2d::Ref* pSender);
     void menuItemCallback_02(cocos2d::Ref* pSender);
     void menuItemCallback_03(cocos2d::Ref* pSender);
     void menuItemCallback_04(cocos2d::Ref* pSender);
     void menuItemCallback_05(cocos2d::Ref* pSender);
     void menuItemCallback_06(cocos2d::Ref* pSender);

     // implement the "static create()" method manually
     CREATE_FUNC(HelloWorld);
 };

 #endif // __HELLOWORLD_SCENE_H__

HelloWorldScene.h

 #include "HelloWorldScene.h"

 USING_NS_CC;

 Scene* HelloWorld::createScene()
 {
     // 'scene' is an autorelease object
     auto scene = Scene::create();

     // 'layer' is an autorelease object
     auto layer = HelloWorld::create();

     // add layer as a child to scene
     scene->addChild(layer);

     // return the scene
     return scene;
 }

 // on "init" you need to initialize your instance
 bool HelloWorld::init()
 {
     //////////////////////////////
     // 1. super init first
     if ( !Layer::init() )
     {
         return false;
     }

     Size visibleSize = Director::getInstance()->getVisibleSize();
     Point origin = Director::getInstance()->getVisibleOrigin();

     /////////////////////////////
     // 2. add a menu item with "X" image, which is clicked to quit the program
     //    you may modify it.

     // add a "close" icon to exit the progress. it's an autorelease object
     auto closeItem = MenuItemImage::create(
                                            "CloseNormal.png",
                                            "CloseSelected.png",
                                            CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));

     closeItem->setPosition(Point(origin.x + visibleSize.width - closeItem->getContentSize().width/ ,
                                 origin.y + closeItem->getContentSize().height/));

     // create menu, it's an autorelease object
     auto menu = Menu::create(closeItem, NULL);
     menu->setPosition(Point::ZERO);
     );

     /////////////////////////////
     // 3. add your codes below...

     Sprite* spbkground = Sprite::create("Demo1/Background480x800.png");
     // position the sprite on the center of the screen
     spbkground->setPosition(Point(visibleSize.width /  + origin.x, visibleSize.height /  + origin.y));
     // add the sprite as a child to this layer
     );

     ///////////////////////
     auto label_1 = Label::createWithBMFont("Demo1/fonts/fnt2.fnt", "01 label");
     auto label_2 = Label::createWithBMFont("Demo1/fonts/fnt2.fnt", "02 label");
     auto label_3 = Label::createWithBMFont("Demo1/fonts/fnt2.fnt", "03 label");
     auto label_4 = Label::createWithBMFont("Demo1/fonts/fnt2.fnt", "04 label");
     auto label_5 = Label::createWithBMFont("Demo1/fonts/fnt2.fnt", "05 label");
     auto label_6 = Label::createWithBMFont("Demo1/fonts/fnt2.fnt", "06 label");

     MenuItemLabel* muLab1 = MenuItemLabel::create(label_1, CC_CALLBACK_1(HelloWorld::menuItemCallback_01, this));
     MenuItemLabel* muLab2 = MenuItemLabel::create(label_2, CC_CALLBACK_1(HelloWorld::menuItemCallback_02, this));
     MenuItemLabel* muLab3 = MenuItemLabel::create(label_3, CC_CALLBACK_1(HelloWorld::menuItemCallback_03, this));
     MenuItemLabel* muLab4 = MenuItemLabel::create(label_4, CC_CALLBACK_1(HelloWorld::menuItemCallback_04, this));
     MenuItemLabel* muLab5 = MenuItemLabel::create(label_5, CC_CALLBACK_1(HelloWorld::menuItemCallback_05, this));
     MenuItemLabel* muLab6 = MenuItemLabel::create(label_6, CC_CALLBACK_1(HelloWorld::menuItemCallback_06, this));

     muLab1->setTag(PLACE_TAG);
     muLab2->setTag(FLIPX_TAG);
     muLab3->setTag(FLIPY_TAG);
     muLab4->setTag(HIDE_SHOW_TAG);
     muLab5->setTag(TOGGLE_TAG);
     muLab6->setTag(OTHER_ACTION);

     Menu* mu = Menu::create(muLab1, muLab2, muLab3, muLab4, muLab5, muLab6,NULL);
     mu->alignItemsVertically();
     mu->setPosition(Point(origin.x + visibleSize.width / , origin.y + visibleSize.height/));

     this->addChild(mu);
     return true;
 }

 void HelloWorld::menuCloseCallback(Ref* pSender)
 {
 #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
     MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
     return;
 #endif

     Director::getInstance()->end();

 #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
     exit();
 #endif
 }

 void HelloWorld::menuItemCallback_01(cocos2d::Ref* pSender)
 {
     MenuItem* muItem = (MenuItem*)pSender;
     auto sc = Scene::create();
     auto SecondLayer = CActionTest::create();
     SecondLayer->setTag(muItem->getTag());
     sc->addChild(SecondLayer);
     auto reScene = TransitionSlideInL::create(1.0f, sc);
     Director::getInstance()->replaceScene(reScene);

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

 void HelloWorld::menuItemCallback_02(cocos2d::Ref* pSender)
 {
     MenuItem* muItem = (MenuItem*)pSender;
     auto sc = Scene::create();
     auto SecondLayer = CActionTest::create();
     SecondLayer->setTag(muItem->getTag());
     sc->addChild(SecondLayer);
     auto reScene = TransitionSlideInR::create(1.0f, sc);
     Director::getInstance()->replaceScene(reScene);

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

 void HelloWorld::menuItemCallback_03(cocos2d::Ref* pSender)
 {
     MenuItem* muItem = (MenuItem*)pSender;
     auto sc = Scene::create();
     auto SecondLayer = CActionTest::create();
     SecondLayer->setTag(muItem->getTag());
     sc->addChild(SecondLayer);
     auto reScene = TransitionSlideInB::create(1.0f, sc);
     Director::getInstance()->replaceScene(reScene);

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

 void HelloWorld::menuItemCallback_04(cocos2d::Ref* pSender)
 {
     MenuItem* muItem = (MenuItem*)pSender;
     auto sc = Scene::create();
     auto SecondLayer = CActionTest::create();
     SecondLayer->setTag(muItem->getTag());
     sc->addChild(SecondLayer);
     auto reScene = TransitionSlideInT::create(1.0f, sc);
     Director::getInstance()->replaceScene(reScene);

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

 void HelloWorld::menuItemCallback_05(cocos2d::Ref* pSender)
 {
     MenuItem* muItem = (MenuItem*)pSender;
     auto sc = Scene::create();
     auto SecondLayer = CActionTest::create();
     SecondLayer->setTag(muItem->getTag());
     sc->addChild(SecondLayer);
     auto reScene = TransitionPageTurn::create(1.0f, sc, true);
     Director::getInstance()->replaceScene(reScene);

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

 void HelloWorld::menuItemCallback_06(cocos2d::Ref* pSender)
 {
     MenuItem* muItem = (MenuItem*)pSender;
     auto sc = Scene::create();
     auto SecondLayer = CActionTest::create();
     SecondLayer->setTag(muItem->getTag());
     sc->addChild(SecondLayer);
     auto reScene = TransitionPageTurn::create(1.0f, sc, true);
     Director::getInstance()->replaceScene(reScene);

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

HelloWorldScene.cpp

 #ifndef __ACTION_SCENE_H__
 #define __ACTION_SCENE_H__
 #include "cocos2d.h"
 #include "HelloWorldScene.h"
 class CActionTest : public cocos2d::Layer
 {
 public:
     CActionTest();
     ~CActionTest();

     static cocos2d::Scene* createScene();
     CREATE_FUNC(CActionTest);

     /// 初始化层 调用
     virtual bool init();
     /// 进入层时调用
     virtual void onEnter();
     /// 进入层而且过渡动画结束时调用
     virtual void onEnterTransitionDidFinish();
     /// 退出层时 调用
     virtual void onExit();
     /// 退出层 而且开始过渡动画时调用
     virtual void onExitTransitionDidStart();
     /// 层对象被清除时调用
     virtual void cleanup();

     void menuItemCallback_back(cocos2d::Ref* pSender);
     void menuItemCallback_Action(cocos2d::Ref* pSender);

 protected:
     cocos2d::Sprite*   spPlane;   // 飞机 精灵
     bool               bShow; // 隐藏标识
 };

 #endif  // __ACTION_SCENE_H__

Action.h

 #include "Action.h"

 USING_NS_CC;

 CActionTest::CActionTest()
 {
     spPlane = NULL;
     bShow = TRUE;

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

 CActionTest::~CActionTest()
 {

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

 Scene* CActionTest::createScene()
 {
     Scene* sc = Scene::create();
     auto myLayer = CActionTest::create();
     sc->addChild(myLayer);

     return sc;
 }

 bool CActionTest::init()
 {
     if (!Layer::init())
     {
         return false;
     }

     //// 层的初始化
     Size sz = Director::getInstance()->getVisibleSize();
     Point origion = Director::getInstance()->getVisibleOrigin();

     Sprite* spBkground = Sprite::create("Demo1/Background480x800.png");
     spBkground->setPosition(Point(origion.x + sz.width / , origion.y + sz.height / ));
     this->addChild(spBkground);

     MenuItemImage* muBack = MenuItemImage::create("Demo1/Back-up.png",
         "Demo1/Back-down.png",
         CC_CALLBACK_1(CActionTest::menuItemCallback_back, this));
     muBack->setPosition(Point(origion.x+, origion.y+sz.height-));

     MenuItemImage* muGo = MenuItemImage::create("Demo1/Go-up.png",
         "Demo1/Go-down.png",
         CC_CALLBACK_1(CActionTest::menuItemCallback_Action, this));
     muGo->setPosition(Point(origion.x + , origion.y + ));

     Menu* mu = Menu::create(muBack, muGo, NULL);
     mu->setPosition(Point::ZERO);
     this->addChild(mu);

     spPlane = Sprite::create("Demo1/Plane.png");
     spPlane->setPosition(Point(origion.x + sz.width / , origion.y + sz.height / ));
     );

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
     return true;
 }

 /// 进入层时调用
 void CActionTest::onEnter()
 {
     Layer::onEnter();

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

 /// 进入层而且过渡动画结束时调用
 void CActionTest::onEnterTransitionDidFinish()
 {
     Layer::onEnterTransitionDidFinish();

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

 /// 退出层时 调用
 void CActionTest::onExit()
 {
     Layer::onExit();

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

 /// 退出层 而且开始过渡动画时调用
 void CActionTest::onExitTransitionDidStart()
 {
     Layer::onExitTransitionDidStart();

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

 /// 层对象被清除时调用
 void CActionTest::cleanup()
 {
     Layer::cleanup();

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

 void CActionTest::menuItemCallback_back(cocos2d::Ref* pSender)
 {
     auto sc = HelloWorld::createScene();
     auto reScene = TransitionShrinkGrow::create(1.0f, sc);
     Director::getInstance()->replaceScene(reScene);

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

 void CActionTest::menuItemCallback_Action(cocos2d::Ref* pSender)
 {
     log("function:%s, line:%d, Tag=%d", __FUNCTION__, __LINE__, this->getTag());

     Size sz = Director::getInstance()->getVisibleSize();
     Point pt = Point(CCRANDOM_0_1() * sz.width, CCRANDOM_0_1() * sz.height);
     ccBezierConfig  bezier;

     switch (this->getTag())
     {
     case PLACE_TAG:
         spPlane->runAction(Place::create(pt));
         log("PLACE_TAG,Position. x=%f, y=%f", pt.x, pt.y);
         break;

     case FLIPX_TAG:
         spPlane->runAction(FlipX::create(true));
         break;

     case FLIPY_TAG:
         spPlane->runAction(FlipY::create(true));
         break;

     case HIDE_SHOW_TAG:
         if (bShow)
         {
             spPlane->runAction(Hide::create());
             bShow = false;
         }
         else
         {
             spPlane->runAction(Show::create());
             bShow = true;
         }
         break;

     case TOGGLE_TAG:
         spPlane->runAction(ToggleVisibility::create());
         break;

     case OTHER_ACTION:
 //        spPlane->runAction(MoveTo::create(3.0f, Point(0, 0)));
 //        spPlane->runAction(MoveBy::create(1.0f, Point(200, 200)));
 //        spPlane->runAction(JumpTo::create(3.0f, Point(100, 300),100, 10));
 //        spPlane->runAction(JumpBy::create(3.0f, Point(100, 300), 400, 8));
         //bezier.controlPoint_1 = Point(100, sz.height);
         //bezier.controlPoint_2 = Point(100, -sz.height / 2);
         //bezier.endPosition = Point(300, 600);
         //spPlane->runAction(BezierTo::create(3.0f, bezier));

        // spPlane->runAction(ScaleTo::create(2.0f, 1.3));
 //        spPlane->runAction(ScaleBy::create(2.0f, 0.5));
 //         spPlane->runAction(RotateTo::create(3.0f, 181)); ///旋转角度超过180度,旋转方向会变
 //         spPlane->runAction(RotateTo::create(3.0f, 81)); ///旋转角度超过180度,旋转方向会变
         //        spPlane->runAction(RotateBy::create(3.0f, -100));
 //        spPlane->runAction(Blink::create(3.0f, 5));  // 闪烁
 //        spPlane->runAction(TintTo::create(2.0f, 255, 0, 0));
 //        spPlane->runAction(TintBy::create(2.0f, 255, 0, 0));  /// 这个 渲染,好像 颜色不正确
 //        spPlane->runAction(FadeTo::create(2.0f, 90));
         //spPlane->setOpacity(50);
         //spPlane->runAction(FadeIn::create(2.0f));
         spPlane->runAction(FadeOut::create(3.0f));
         break;

     default:
         break;
     }

     log("function:%s, line:%d", __FUNCTION__, __LINE__);
 }

Action.cpp

关键代码分析1:

  auto sc = Scene::create();       /// 生成新场景
  auto SecondLayer = CActionTest::create();
  SecondLayer->setTag(muItem->getTag());
  sc->addChild(SecondLayer);   ///将 CActionTest 层添加到 新场景
  auto reScene = TransitionSlideInR::create(1.0f, sc);  /// 生成 过渡场景(过渡动画)
  Director::getInstance()->replaceScene(reScene);  /// 场景替换

此处没有调用CAction::createScene()直接创建场景和层,而是采用上面的方法。主要是为了给场景传递参数。

(当然,你重写一个 带参数的 createScene(int Tag) ,将参数传入,也是可行的)

关键代码分析2:

/// 执行一个Place动作,Place动作是将精灵等Node对象移动到pt点。

spPlane->runAction(Place::create(pt));

//// 执行一个 FlipX 动作,FlipX 动作是将精灵等Node对象 水平方向翻转

spPlane->runAction(FlipX::create(true));

关键代码分析3:

Point pt = Point(CCRANDOM_0_1() * sz.width, CCRANDOM_0_1() * sz.height);

CCRANDOM_0_1() 宏 可以产生 0~1 之间的随机数。

间隔动作:

间隔动作执行完成需要一定的时间,可以设置 duration 属性来设置动作的执行时间。间隔动作基类是 ActionInterval。间隔动作ActionInterval类图如下:

上面的源码示例中,有用到 间隔动作。

关键代码分析:

 //        spPlane->runAction(MoveTo::create(3.0f, Point(0, 0)));
 //        spPlane->runAction(MoveBy::create(1.0f, Point(200, 200)));
 //        spPlane->runAction(JumpTo::create(3.0f, Point(100, 300),100, 10));
 //        spPlane->runAction(JumpBy::create(3.0f, Point(100, 300), 400, 8));
         //bezier.controlPoint_1 = Point(100, sz.height);
         //bezier.controlPoint_2 = Point(100, -sz.height / 2);
         //bezier.endPosition = Point(300, 600);
         //spPlane->runAction(BezierTo::create(3.0f, bezier));

        // spPlane->runAction(ScaleTo::create(2.0f, 1.3));
 //        spPlane->runAction(ScaleBy::create(2.0f, 0.5));
 //         spPlane->runAction(RotateTo::create(3.0f, 181)); ///旋转角度超过180度,旋转方向会变
 //         spPlane->runAction(RotateTo::create(3.0f, 81)); ///旋转角度超过180度,旋转方向会变
         //        spPlane->runAction(RotateBy::create(3.0f, -100));
 //        spPlane->runAction(Blink::create(3.0f, 5));  // 闪烁
 //        spPlane->runAction(TintTo::create(2.0f, 255, 0, 0));
 //        spPlane->runAction(TintBy::create(2.0f, 255, 0, 0));  /// 这个 渲染,好像 颜色不正确
 //        spPlane->runAction(FadeTo::create(2.0f, 90));
         //spPlane->setOpacity(50);
         //spPlane->runAction(FadeIn::create(2.0f));
         spPlane->runAction(FadeOut::create(3.0f));

间隔动作中很多类是 XxxTo 和 XxxBy 的命名。

XxxTo是指运动到指定的位置,这个位置是 绝对的。

XxxBy是指运动到相对于本身的位置,这个位置是相对的位置。

cocos2d-x实战 C++卷 学习笔记--第7章 动作、特效(一)的更多相关文章

  1. cocos2d-x实战 C++卷 学习笔记--第4章 字符串 __String类

    前言: <cocos2d-x实战C++卷>学习笔记.(cocos2d-x 是3.0版本) 介绍 cocos2d-x 通用的字符串类  __String . 使用cocos2d::__Str ...

  2. cocos2d-x实战 C++卷 学习笔记--第6章 场景与层

    前言: 一个场景(Scene)是由多个层(Layer)组成,而且层的个数要至少是1,不能为0. 场景切换 场景切换相关函数 1)void  runWithScene(Scene*  scene) 该函 ...

  3. cocos2d-x实战 C++卷 学习笔记--第4章 使用菜单

    前言: 菜单中包含菜单项,菜单项类是 MenuItem ,每个菜单项都有三个基本状态:正常.选中和禁止. (MenuItem)菜单分类: (文本菜单)MenuItemLabel : MenuItemA ...

  4. cocos2d-x实战 C++卷 学习笔记--第4章 win32平台下中文乱码问题

    前言: 将GBK编码的字符串转为UTF-8编码.(通俗点说就是解决中文乱码问题) 简要介绍: 在Win32平台下通过 log 输出中文字符时,会出现中文乱码问题.同样的代码在 ios 和 Androi ...

  5. cocos2d-x实战 C++卷 学习笔记--第5章 精灵

    前言: 精灵类是Sprite类.它的子类有PhysicsSprite 和 Skin. PhysicsSprite 是物理引擎精灵类,而Skin是皮肤精灵类,用于骨骼动画. 创建Sprite精灵对象 创 ...

  6. cocos2d-x实战 C++卷 学习笔记--第4章 使用标签

    前言: 介绍cocos2d-x中 标签类. cocos2d-x中 标签类 主要有三种:LabelTTF, LabelAtlas, 和 LabelBMFont.此外,在Cocos2d-x 3.x之后推出 ...

  7. Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-2-driver

    1>使用的driver 1〉generic 使用带有SSH的现有VM/主机创建机器. 如果你使用的是机器不直接支持的provider,或者希望导入现有主机以允许Docker Machine进行管 ...

  8. Docker技术入门与实战 第二版-学习笔记-8-网络功能network-3-容器访问控制和自定义网桥

    1)容器访问控制 容器的访问控制,主要通过 Linux 上的 iptables防火墙来进行管理和实现. iptables是 Linux 上默认的防火墙软件,在大部分发行版中都自带. 容器访问外部网络 ...

  9. Spring实战第八章学习笔记————使用Spring Web Flow

    Spring实战第八章学习笔记----使用Spring Web Flow Spring Web Flow是一个Web框架,它适用于元素按规定流程运行的程序. 其实我们可以使用任何WEB框架写流程化的应 ...

随机推荐

  1. hdoj 4325 Flowers【线段树+离散化】

    Flowers Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  2. class-dump 复制到/usr/bin目录不可写,Operation not permitted 解决办法

    许多升级了OSX 10.11的朋友在配置class-dump的时候,会发现书上推荐的class-dump存放目录/usr/bin不再可写,如下所示: Operation not permitted 把 ...

  3. C#下实现软件欢迎界面

    找到几种简约的欢迎界面的制作方法,存此记录. 方法一:双线程,用第二个线程启动欢迎界面 原文:http://www.cnblogs.com/xiaoshatian/archive/2010/09/07 ...

  4. 取消jQuery validate验证

    有时候当我们在编辑页面点保存后加上了validate错误验证后又想用表单提交的方式返回界面没有清除验证就返回不了 加上这句话就清除验证了      注意:remove()是删除了相关标签  我这需求是 ...

  5. MySQL的安装——源码方式(实验环境下测试用,真实环境请忽略此文)

    #虚拟机是最初的的系统,我们在虚拟机里安装scp [root@serv01 ~]# yum install /usr/bin/scp -y #安装过程略 #我们拷贝MySQL的源码包到目标机的/roo ...

  6. 【54】让自己熟悉包括TR1在内的标准程序库

    1.C++0X,不确定哪一年出来,意指200X版的C++ 2.C++标准程序库的主要机能有:STL,iostreams,locals等. 3.TR1:Technical Report 1,只是一份规范 ...

  7. 【07】为多态基类声明virtual析构方法

    1.考虑下面的需要,需要一个工厂方法.工厂方法的规则是:在堆上分配一个子类对象,并返回父类指针.使用完毕,delete父类指针.如果父类的析构方法不是virtual,将直接调用父类的析构方法,导致局部 ...

  8. Tomcat 生产服务器性能优化

    虑一下这种场景,你开发了一个应用,它有十分优秀的布局设计,最新的特性以及其它的优秀特点.但是在性能这方面欠缺,不管这个应用如何都会遭到客户拒绝.客户总是期望它们的应用应该有更好的性能.如果你在产品中使 ...

  9. sphinx配置文件继承

    # # Minimal Sphinx configuration sample (clean, simple, functional) # source mysql { type = mysql #数 ...

  10. Docker intercontainer 网络解释

    https://segmentfault.com/a/1190000000669312