Cocos通过动作(Action)让精灵动起来,把数个动作组成序列(Sequence)就能让精灵做出连续的动作,在动作中我们可以改变精灵的位置,旋转角度,缩放比例,等等

动作(Action)#

首先我们创建一个Action对象,同样使用create,这里我们还是使用HelloWorld场景里的那张图片

Copy
auto sprite = Sprite::create("sinnosuke.png");

setPosition之后我们加上一句

Copy
// 在2秒内:向右移动精灵50像素,向上移动精灵10像素
auto moveBy = MoveBy::create(2, Vec2(50, 10));
sprite->runAction(moveBy);

这个精灵就会平滑地根据我们输入的参数移动

如果把moveBy改成moveTo,那就会是另一种结果:

Copy
// 在2秒内:把精灵移动到坐标(50,10)
auto moveTo = MoveTo::create(2, Vec2(50, 10));
sprite->runAction(moveTo);

精灵直接移动到了(50,10)(锚点在其正中间)

By 和 To 的区别#

  • By算的是相对于节点对象的当前位置
  • To算的是绝对位置,不考虑当前节点对象在哪

动作组合#

你还可以把多个动作加入到一个序列(Sequence)里,让精灵按执行序列

Copy
auto moveBy = MoveBy::create(2, Vec2(50, 10));
auto moveTo = MoveTo::create(2, Vec2(50, 10));
auto delay = DelayTime::create(1);//设置一个一秒的延时,也加入序列中
auto seq = Sequence::create(moveBy, delay, moveTo, nullptr);
//做动作moveBy后,延时1秒,做动作moveTo
sprite->runAction(seq);

精灵就会按次序执行序列里的动作

序列我们之后再详细讲解

基本动作#

移动#

MoveTo ,MoveBy,使精灵在指定时间内移动到指定地点

Copy
auto sprite = Sprite::create("sinnosuke.png");
auto delay = DelayTime::create(1);

// 在2秒内:向右移动精灵50像素,向上移动精灵10像素
auto moveBy = MoveBy::create(2, Vec2(50, 10));
// 在2秒内:把精灵移动到坐标(50,10)
auto moveTo = MoveTo::create(2, Vec2(50, 10));

auto seq = Sequence::create(moveBy, delay, moveTo, nullptr);
sprite->runAction(seq);

效果如上图

旋转#

RotateToRotateBy,使精灵在指定时间内旋转到指定角度

Copy
auto sprite = Sprite::create("sinnosuke.png");
auto delay = DelayTime::create(1);

// 在2秒内:把精灵从原始位置顺时针旋转40度
auto rotateBy = RotateBy::create(2.0f, 40.0f);
// 在2秒内:把精灵从目前位置旋转到顺时针40度的位置
auto rotateTo = RotateTo::create(2.0f, 40.0f);

auto seq = Sequence::create(rotateBy, delay, rotateTo, nullptr);
sprite->runAction(seq);

你应该会看到这个图片转了一次就不动了,其实不是不动了

因为在第一个动作后你已经让图片转到了顺时针40度的位置,第二个动作的目标“把精灵从目前位置旋转到顺时针40度的位置”即为目前的位置,所以看上去就是不动了

建议你把两个动作先后顺序对调一下,运行看看,方便理解

缩放#

ScaleBy ScaleTo 在指定时间内完成指定比例缩放

Copy
auto sprite = Sprite::create("sinnosuke.png");

// Scale uniformly by 3x over 2 seconds
// 在2秒内:把精灵等比放大到3倍
auto scaleBy = ScaleBy::create(2.0f, 3.0f);

// Scale X by 5 and Y by 3x over 2 seconds
// 在2秒内:把精灵的x轴放大到3倍并把y轴放大到3倍
auto scaleBy = ScaleBy::create(2.0f, 3.0f, 3.0f);

// 在2秒内:把精灵缩放到:等比放大3倍的状态
auto scaleTo = ScaleTo::create(2.0f, 3.0f);

// Scale X to 5 and Y to 3x over 2 seconds
// 在2秒内:把精灵缩放到:x轴放大到3倍,把y轴放大到3倍的状态
auto scaleTo = ScaleTo::create(2.0f, 3.0f, 3.0f);

通过对旋转的理解(主要是To和By的理解),上述代码不难看懂,这里不多给出运行效果了,感兴趣可以自己写个Sequence测试

淡入淡出#

FadeIn 淡入,FadeOut 淡出 (其实就是修改节点对象的透明度属性,FadeIn从完全透明到完全不透明,FadeOut 相反)

Copy
auto sprite = Sprite::create("sinnosuke.png");
auto delay = DelayTime::create(1);//设置一个一秒的延时,也加入序列中

auto fadeIn = FadeIn::create(1.0f);
auto fadeOut = FadeOut::create(2.0f);

auto seq = Sequence::create(delay, fadeOut, delay, fadeIn, nullptr);
sprite->runAction(seq);

也很简单,代码也给出了,可以自己运行看看

色彩混合#

使用 TintTo TintBy,将一个实现了 NodeRGB 协议的节点对象进行色彩混合

Copy
auto sprite = Sprite::create("sinnosuke.png");
auto delay = DelayTime::create(1);

// 指定RGB值为节点着色
auto tintTo = TintTo::create(2.0f, 120.0f, 232.0f, 254.0f);
// 指定RGB值为增量为节点着色
auto tintBy = TintBy::create(2.0f, 120.0f, 232.0f, 254.0f);

auto seq = Sequence::create(tintTo, delay, tintBy, nullptr);
sprite->runAction(seq);

变化如下:

此外还有帧动画和变速运动

帧动画使用 Animate 对象,通过每隔一个短暂时间进行图像替代的方式,实现一个动画效果

变速动作可以让节点对象具有加速度,用以模仿物理运动,降低性能损耗

序列(Sequence)#

顾名思义,序列就是多个动作按照特定顺序的一个排列(当然也能反向执行)

其实序列就是一种封装多个动作的对象,当这个对象执行时,被封装的动作会顺序执行

Sequence#

一个 Sequence 可以包含任何数量的动作对象,回调方法和其它序列,Cocos2d-x 允许把一个方法添加进去 CallFunc 对象,然后将 CallFunc 添加到 Sequence,这样,在执行序列的时候就能触发方法调用

Copy
auto mySprite = Node::create();

auto moveTo1 = MoveTo::create(2, Vec2(50,10));
auto moveBy1 = MoveBy::create(2, Vec2(100,10));
auto moveTo2 = MoveTo::create(2, Vec2(150,10));

auto delay = DelayTime::create(1);

mySprite->runAction(
    Sequence::create(
        moveTo1,
        delay,
        moveBy1,
        delay.clone(),
        moveTo2, nullptr
    )
);

Spawn#

Spawn 和 Sequence 非常相似,但 Spawn 同时执行所有的动作

Spawn 对象可以添加任意数量的动作,和其它 Spawn 对象,可能不同动作的执行时间不一致,在这种情况下,他们不会同时结束

Copy
auto myNode = Node::create();

auto moveTo1 = MoveTo::create(2, Vec2(50,10));
auto moveBy1 = MoveBy::create(2, Vec2(100,10));
auto moveTo2 = MoveTo::create(2, Vec2(150,10));

myNode->runAction(Spawn::create(moveTo1, moveBy1, moveTo2, nullptr));

克隆#

克隆(Clone) 的功能和字面含义一样,如果你对一个节点对象使用了 clone() 方法,你就获得了这个节点对象的拷贝

为什么要使用 clone() 方法? 因为当 Action 对象运行时会产生一个内部状态,记录着节点属性的改变,当你想将一个创建的动作,重复使用到不同的节点对象时,如果不用 clone() 方法,就无法确定这个动作的属性到底是怎样的(因为被使用过,产生了内部状态),这会造成难以预料的结果

我们来看示例,假如你有一个坐标位置是 (0,0) 的 heroSprite,执行这样一个动作:

Copy
MoveBy::create(10, Vec2(400,100));

你的 heroSprite 就在 10s 的时间中,从 (0,0) 移动到了 (400,100)heroSprite 有了一个新位置 (400,100),更重要的是动作对象也有了节点位置相关的内部状态了

现在假如你有一个坐标位置是 (200,200)的 emenySprite,你还使用这个相同的动作,emenySprite 就会移动到 (800,200)的坐标位置,并不是你想要的结果,因为第二次将这个动作应用的时候,它已经有内部状态了

使用 clone() 能避免这种情况,克隆获得一个新的动作对象,新的对象没有之前的内部状态

以下错误的用法:

Copy
auto heroSprite = Sprite::create("herosprite.png");
auto enemySprite = Sprite::create("enemysprite.png");

auto moveBy = MoveBy::create(10, Vec2(400,100));

heroSprite->runAction(moveBy);

enemySprite->runAction(moveBy);

使用 clone() 的正确情况:

Copy
auto heroSprite = Sprite::create("herosprite.png");
auto enemySprite = Sprite::create("enemysprite.png");

auto moveBy = MoveBy::create(10, Vec2(400,100));

heroSprite->runAction(moveBy);

enemySprite->runAction(moveBy->clone());

倒转#

倒转(Reverse) 的功能也和字面意思一样,调用 reverse() 可以让一系列动作按相反的方向执行,reverse() 不是只能简单的让一个 Action 对象反向执行,还能让 Sequence 和 Spawn 倒转

Copy
mySprite->runAction(mySpawn->reverse());

应用实例

Copy
auto mySprite = Sprite::create("mysprite.png");
mySprite->setPosition(50, 56);

auto moveBy = MoveBy::create(2.0f, Vec2(500,0));
auto scaleBy = ScaleBy::create(2.0f, 2.0f);
auto delay = DelayTime::create(2.0f);

auto delaySequence = Sequence::create(delay, delay->clone(), delay->clone(),
delay->clone(), nullptr);

auto sequence = Sequence::create(moveBy, delay, scaleBy, delaySequence, nullptr);

mySprite->runAction(sequence);

mySprite->runAction(sequence->reverse());

作者:zhxmdefj

出处:https://www.cnblogs.com/zhxmdefj/p/11701526.html

版权:本站使用「CC BY 4.0」创作共享协议,转载请在文章明显位置注明作者及出处。

 

Cocos2d-x入门之旅的更多相关文章

  1. Swift语言入门之旅

    Swift语言入门之旅  学习一门新的计算机语言,传统来说都是从编写一个在屏幕上打印"Hello world"的程序開始的.那在 Swift,我们使用一句话来实现它: printl ...

  2. cocos2d基础入门

    HelloCpp中Classes目录下放开发者自己的类: win32:平台相关,coco2d已默认创建:coco2d-x目录下,samples/cpp/HelloCpp/(工程根目录)图片放置位置:根 ...

  3. Cocos2d-x入门之旅[1]场景

    在游戏开发过程中,你可能需要一个主菜单,几个关卡和一个END的界面,如何组织管理这些东西呢? 和其他游戏引擎类似,Cocos也使用了场景(Scene) 这个概念 试想象一部电影或是番剧,你不难发现它是 ...

  4. Cocos2d-x入门之旅[4]场景

    我们之前讲了场景图(Scene Graph) 的概念,继续之前你先要知道 场景图决定了场景内节点对象的渲染顺序 渲染时 z-order 值大的节点对象会后绘制,值小的节点对象先绘制 HelloWorl ...

  5. IOS-swift5.1快速入门之旅

    快速之旅 传统表明,新语言中的第一个程序应在屏幕上打印“Hello,world!”字样.在Swift中,这可以在一行中完成: print("Hello, world!") // P ...

  6. 云原生 - 体验Istio的完美入门之旅(一)

    作者:justmine 头条号:大数据达摩院 微信公众号:大数据处理系统 创作不易,在满足创作共用版权协议的基础上可以转载,但请以超链接形式注明出处. 为了方便大家阅读,可以关注头条号或微信公众号,后 ...

  7. ROR入门之旅

    mac上为了不在登录画面看到其他账户,我禁用了root账户,而每次用Terminal的时候,先获得sudo账户的权限: sudo -s mac本身就安装有ruby ruby -v 查看当前安装的rub ...

  8. Vue入门之旅:一报错 Unknown ... make sure to provide the "name" option及error compiling template

    报错一: Unknown custom element: <custom-select> - did you register the component correctly? For r ...

  9. Cocos2d-x入门之旅[2]精灵

    精灵就是cocos是屏幕上移动的对象,能被我们控制,比如我们HelloWorld场景的这个图片就是精灵(Sprite) 怎么才算精灵?你能控制它的,就是一个精灵,否则就只是一个节点(Node) 准确的 ...

  10. Cocos2d-x入门之旅[3]动作

    Cocos通过动作(Action)可以让精灵动起来,把数个动作组成序列(Sequence)就能让精灵做出连续的动作,在动作中我们可以改变精灵的位置,旋转角度,缩放比例,等等 动作(Action) 首先 ...

随机推荐

  1. TCP的ACK原理和延迟确认机制

    某天晚上睡觉前突然想到 tcp的ACK确认是单独发的还是和报文一起发的,下面看一下别人的解答 一.ACK定义TCP协议中,接收方成功接收到数据后,会回复一个ACK数据包,表示已经确认接收到ACK确认号 ...

  2. 《Python基础教程》第四章:字典

    字典中的值没有特殊的顺序 电话号码(以及其他可能以0开头的数字)应该表示为数字字符串,而不是整数 dict函数可以通过序列对建立字典 clear方法清除字典中所有的项.这是个原地操作,无返回值 get ...

  3. js创建对象的几种方式(工厂模式、构造函数模式、原型模式)

    普通方法创建对象 var obj = { name:"猪八戒", sayname:function () { alert(this.name); } } var obj1 = { ...

  4. 如何开始使用Laravel

    访问http://www.golaravel.com/download/,下载v5.2.15 解压 复制到项目目录 3.然后访问 http://localhost/LaravelTest/server ...

  5. XML -- XML基础知识

    1.XML的结构 XML的结构采用的是树结构,树结构就是一种一对多的关系结构. XML必定有一个根节点.因为,在解析这个XML时,需要有个起始位置进行遍历解析,这个跟节点就是起始位置. 2.XML的元 ...

  6. CDOJ 1269 ZhangYu Speech 数组处理

    ZhangYu Speech Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submi ...

  7. C库函数-fgets()

    函数声明:char *fgets(char *str,int n,FILE *stream) 函数介绍:从指定的stream流中读取一行,并把它存储在str所指向的字符串中.当读取到(n-1)个字符时 ...

  8. C++回调函数、静态函数、成员函数踩过的坑。

    C++回调函数.静态函数.成员函数踩过的坑. 明确一点即回调函数需要是静态函数.原因: 普通的C++成员函数都隐含了一个this指针作为参数,这样使得回调函数的参数和成员函数参数个数不匹配. 若不想使 ...

  9. Latex里引用多个公式,如何将公式合并?

    如果是想要的效果:(1)-(3),怎么操作?类似于用\cite引用多个文献那样吗? 1. \eqref{lable 1, lable 2, label 3}? 得到的结果:3个问号 ??? 2.\eq ...

  10. 「CF1105E」Helping Hiasat

    题目链接 戳我 \(Solution\) 将好友访问你的主页的状态用二进制存下来 其中若第\(i\)位是\(1\),则表示这个好友在第\(i\)个\(1\)操作后访问了你的主页,否则没访问. 所以如果 ...