转载请说明出处:http://blog.csdn.net/notbaron/article/details/38376659
上篇回顾
上篇中,蛤蟆学习了如何使用ActionManager来控制精灵动作。我们可以随时随地的控制精灵的停止、开始。
这次蛤蟆将学习如何让精灵按指定的曲线运行。
理论介绍
其实按路线运行,说的简单一点就是路线上的几个关键点。我们需要将这些关键点弄成一个数组。然后就可以直接调用函数来实现了。因为cocos2d-x中本身就带有这种函数。
首先我们先介绍下基数样条。基数样条是一连串单独的曲线,这些曲线连接起来形成一条较大的曲线。 样条由点的数组和张力参数指定。(张力应该是0和1之间,但是这不是必须的)。
然后我们介绍下贝塞尔曲线,贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。于1962,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由Paul de Casteljau于1959年运用de Casteljau演算法开发,以稳定数值的方法求出贝兹曲线。做为混迹于IT行业的小伙伴必须得知道这个哦。虽然蛤蟆不是计算机专业的(蛤蟆学机械设计的,对于编程纯属好奇),也是知道这个线的。因为这个线我记得我们老师上计算机图形学的第一节课就讲到了。我们只需记住一点,贝塞尔曲线至少需要4个点,由于精灵的一开始位置就占了一个点,所以再需要3个点即可。
CatmullRom样条,这个蛤蟆查不到资料,大家目前记住这个是一个将所有点连在一起的曲线即可,至于这个样条曲线有什么特性,我们以后有机会慢慢道来。
接下去我们看下,这个类的继承关系。
接下去我们谈论让精灵沿着这三种曲线运动的三个动作类主要(因为By可以改成To就变成另外的动作了)是:
CardinalSplineBy,CatmullRomBy,BezierTo 。类的继承关系如下图,注意哦,CatmullRomby其实是CardinalSplineBy的儿子,而CardinalSplineBy 又是CardinalSplineTo的儿子。
而BezierTo却是 BezierBy的儿子。说明 by和 to不一定谁是谁的儿子,具体情况得具体分析。类继承如下图:
具体步骤
我们还是使用HelloWolrd项目。依旧是在
bool HelloWorld::init()函数中加入代码:
代码如下:
auto s = Director::getInstance()->getWinSize();
auto array =PointArray::create(20);
array->addControlPoint(Vec2(10,10));
array->addControlPoint(Vec2(s.width/2-30,10));
array->addControlPoint(Vec2(s.width/2-30,s.height-80));
array->addControlPoint(Vec2(10,s.height-80));
array->addControlPoint(Vec2(10,10));
auto action1 =CardinalSplineBy::create(3, array, 1);
auto reverse1 = action1->reverse();
auto array1 =PointArray::create(20);
array1->addControlPoint(Vec2(10, 10));
array1->addControlPoint(Vec2(s.width/2-30, 10));
array1->addControlPoint(Vec2(s.width/2-30, s.height-80));
array1->addControlPoint(Vec2(10, s.height-80));
array1->addControlPoint(Vec2(10, 10));
auto action2 =CatmullRomBy::create(3,array1);
auto reverse2 = action1->reverse();
ccBezierConfig bezier;
bezier.controlPoint_1 = Vec2(10,s.height/2);
bezier.controlPoint_2 = Vec2(300,-s.height/2);
bezier.endPosition = Vec2(300,100);
auto bezierForward =BezierBy::create(3, bezier);
auto bezierBack = bezierForward->reverse();
auto grossini =Sprite::create("grossini.png");
addChild(grossini,0, 2);
grossini->setPosition(Vec2( origin.x+30, origin.y+30));
grossini->runAction(Sequence::create(action1,reverse1,action2,reverse2,bezierForward,bezierBack,nullptr));
代码解释
OK,现在蛤蟆来解释下代码:
auto s = Director::getInstance()->getWinSize(); //获取窗口大小
auto array =PointArray::create(20); //创建一个array数组。(这个ARRAY 会被VECTOR代替传说,不过现在还是可以的。如果哪天不能用了,蛤蟆出来告诉大家的。)
array->addControlPoint(Vec2(10,10));//增加一个点
array->addControlPoint(Vec2(s.width/2-30,10)); //增加一个点
array->addControlPoint(Vec2(s.width/2-30,s.height-80)); //增加一个点
array->addControlPoint(Vec2(10,s.height-80)); //增加一个点
array->addControlPoint(Vec2(10,10)); //增加一个点
auto action1 =CardinalSplineBy::create(3, array, 1);//增加动画, 第一参数表示时间,第二个参数是数组名,第三个参数是 张力。此处设置为1,,表示张力很大,动起来就是沿着正方形来的。
auto reverse1 = action1->reverse();//创建一个相反的动画
auto action2 =CatmullRomBy::create(3,array) ;//增加动画, 第一参数表示时间,第二个参数是数组名。这个CatmullRom不需要设置张力
auto reverse2 = action1->reverse();//创建一个相反的动画
ccBezierConfig bezier; //创建一个贝塞尔配置变量
bezier.controlPoint_1 = Vec2(10,s.height/2); //创建一个贝塞尔配置变量
bezier.controlPoint_2 = Vec2(300,-s.height/2); //创建一个贝塞尔配置变量
bezier.endPosition = Vec2(300,100); //创建一个贝塞尔配置变量
auto bezierForward =BezierBy::create(3, bezier); //创建一个贝塞尔配置变量
auto bezierBack = bezierForward->reverse();//创建一个贝塞尔配置变量
auto grossini =Sprite::create("grossini.png");
addChild(grossini,0, 2);
grossini->setPosition(Vec2( origin.x+30, origin.y+30));
grossini->runAction(Sequence::create(action1,reverse1,action2,reverse2,bezierForward,bezierBack,nullptr)); //启动精灵运行,按顺序运行基数样条,基数样条返回,CatmullRom, CatmullRom返回,贝塞尔曲线,贝塞尔曲线返回。
总结
本次,蛤蟆记录了曲线使用的3个方法,大家有兴趣可以择一深入之。当然啦,深入学习之后不要忘记告诉蛤蟆哈。沿着曲线运动是不是让人觉得有一种丈二和尚摸不着头的感觉。