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

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

动作(Action)

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

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

setPosition之后我们加上一句

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

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

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

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

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

By 和 To 的区别

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

动作组合

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

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);

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

序列我们之后再详细讲解

基本动作

移动

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

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,使精灵在指定时间内旋转到指定角度

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 在指定时间内完成指定比例缩放

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 相反)

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 协议的节点对象进行色彩混合

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,这样,在执行序列的时候就能触发方法调用

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

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

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

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,执行这样一个动作:

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

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

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

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

以下错误的用法:

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() 的正确情况:

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 对象反向执行,还能让 SequenceSpawn 倒转

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

应用实例

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());

原文地址:https://www.cnblogs.com/zhxmdefj/p/11701526.html

时间: 2024-07-30 13:25:45

Cocos2d-x入门之旅[3]动作的相关文章

cocos2d基础入门

HelloCpp中Classes目录下放开发者自己的类: win32:平台相关,coco2d已默认创建:coco2d-x目录下,samples/cpp/HelloCpp/(工程根目录)图片放置位置:根目录下/Resources目录下;什么是场景:场景是占据屏幕的界面:什么是锚点:锚点如何设置: CCSprite * leftdoor = CCSprite::create("loading/door.png"); leftdoor->setAnchorPoint(ccp(1,0.5

【笨木头Unity】入门之旅010(完结):Demo之四处找死(五)_UI

UI是游戏里必不可少的元素,在Unity里添加UI是比较轻松的事情,但要玩好它,可就不那么轻松了. 没关系,先入门. 笨木头花心贡献,啥?花心?不,是用心. 转载请注明,原文地址:http://www.benmutou.com/archives/2196 文章来源:笨木头与游戏开发 1.创建UI 很早之前也介绍过怎么创建UI,这里简单再回顾一下. 在Hierarchy窗口中点击右键,依次选择[UI]-[Text]. 我们会看到窗口中,多了一个Canvas和Text: 2.让UI跟随物体移动 由于

Swift语言入门之旅 (翻译自《The Swift Programming Language》电子书)

关于Swift Swift是为IOS和OSX应用制定的新编程语言,吸取C和Objective-C语言的精粹,但不损失与C语言的兼容性.Swift采用安全编程模型.加入了各种现代编程语言特性,使得该语言更易被掌握.更具扩展性,用起来更有趣.Swift语言的奠基石是已经成熟的.并为大家所喜爱的Cocoa和Cocoa Touch框架,新语言使大家可以尽情畅想新软件开发的机遇. Swift沉积了多年的研发成果,苹果公司为提供高效Swift语言编译器.调试器和基础架构打下了坚实基础.我们使用Automat

Apache Solr初学者教程(入门之旅)

Apache Solr初学者教程(入门之旅) 写在前面:本文涉及solr入门的各方面,请逐行阅读,相信能帮助你对solr有个清晰全面的了解和使用. 在Apache Solr初学者教程的这个例子中,我们将讨论有关如何安装最新版本的Apache Solr,并告诉你如何配置它.此外,我们将告诉你如何进行使用solr的样本数据文件索引.Apache Solr支持不同格式,包括各种数据库,PDF文件,XML文件,CSV文件等等.在这个例子中,我们的索引将研究如何索引数据从一个CSV文件. 我们首选的这个例

Swift语言入门之旅

学习一门新的计算机语言,传统来说都是从编写一个在屏幕上打印"Hello world"的程序开始的.那在 Swift,我们使用一句话来实现它: println("Hello, world") 如果你编写过C或者Objective-C语言,Swift中的这个语法看起来便很熟悉,这句话却是一个完整的程序 .你无须为了得到输入/输出或字符串处理去导入一个独立的功能库.编写全局代码通常用于程序的进入 点.你不需要写一个main函数,你也不需要为每个语句写个逗号作为结尾. 这个

Cocos2d Lua 入门小例子 一个记忆力游戏

1.游戏说明 一个"记忆"类的比赛游戏.你和电脑对战,轮到谁的回合,谁翻两张牌,如果两张牌一样,就消掉这两张牌,得2分,可以继续翻牌,如果两张牌不一样,就换一个人.直到最后,看谁的得分高. 游戏设计思想可以看这篇文章<Cocos2d 游戏状态机> 2. Lua 简单面向对象 我们知道Lua是脚本语言,不是真正面向对象语言.但是面向对象好像能让代码结构更加合理,Javascript, Lua都可以模拟出面向对象.Lua面向对象还有超多种方式实现,这里当然不一一介绍.简单来看个

【笨木头Unity】入门之旅006:Demo之四处找死(一)_场景和主角

终于把一些基本的东西介绍完了,我不想再介绍无聊的菜单和快捷键了,这些东西大家自己在折腾的过程中慢慢熟悉就好. 有什么不懂的就问度娘,不喜欢度娘的,可以找谷歌. 这次,我们来开始一个很简单的Demo,我突然想到一个游戏,又或者只能叫做Demo. 一个人物,可以四处走动,地图上有很多暗雷,踩到之后会随机产生一些效果(比如加血.掉血.增加防御.小若失去吐槽能力等等). 人物身上当然得有一些UI,这些UI会跟随着人物一起走动. 虽然是个小Demo,但,入门所需的各种操作应该都涉及到了,包括:人物走动(不

小白的Grunt入门之旅

前段时间说要学习grunt很久了,可是这两周不是在做项目就是在去做项目的路上.现在终于可以好好得去入门了.边学边写,就把这个过程说一下吧. 首先,Grunt 依赖 Node.js 所以先要安装node.这里附上node的安装方法:http://jingyan.baidu.com/article/b0b63dbfca599a4a483070a5.html 安装 Grunt 实际上,安装的并不是 Grunt,而是 Grunt-cli,也就是命令行的 Grunt,这样你就可以使用 grunt 命令来执

gym强化学习入门demo——随机选取动作 其实有了这些动作和反馈值以后就可以用来训练DNN网络了

# -*- coding: utf-8 -*- import gym import time env = gym.make('CartPole-v0') observation = env.reset() print(observation) print("env actionspace:") print(env.action_space) print("env observationspace:") print(env.observation_space) pri