1. Sequence

动作序列。动作按参数顺序执行,动作总时长为每个动作的时长之和。

1.1 成员变量

    FiniteTimeAction *_actions[];
float _split; // 第一个action在Sequence的时间占比
int _last;

1.2 create方法

4种:

createWithTwoActions(FiniteTimeAction *actionOne, FiniteTimeAction *actionTwo) // 用两个action创建
create(FiniteTimeAction *action1, ...) // 用很多action创建,调用下面的方法
createWithVariableList(FiniteTimeAction *action1, va_list args)
create(const Vector<FiniteTimeAction*>& arrayOfActions) // 存储action的Vector容器作为参数

createWithTwoActions:

调用initWithTwoActions方法,两个action的时间之和作为Sequence的duration,并对两个action retain()。

createWithVariableList:

调用了createWithTwoActions方法,参数第一个action为参数action,参数第二个action为va_list args存储的变长参数。当只有一个action时,createWithTwoActions的第二个参数为ExtraAction。

Sequence* Sequence::createWithVariableList(FiniteTimeAction *action1, va_list args)
{
FiniteTimeAction *now;
FiniteTimeAction *prev = action1;
bool bOneAction = true; while (action1)
{
now = va_arg(args, FiniteTimeAction*);
if (now)
{
prev = createWithTwoActions(prev, now);
bOneAction = false;
}
else
{
// If only one action is added to Sequence, make up a Sequence by adding a simplest finite time action.
if (bOneAction)
{
prev = createWithTwoActions(prev, ExtraAction::create());
}
break;
}
} return ((Sequence*)prev);
}

create:

使用Vector存储action,调用init方法,递归地创建Sequence。

s1=a1+a2 s2=a3+s1 s3=a4+s2 s4=a5+s3 ... 最终获得的Sequence是一个action和sequence的组合。

1.3 startWithTarget

runAction时调用。

if (_duration > FLT_EPSILON)
_split = _actions[]->getDuration() > FLT_EPSILON ? _actions[]->getDuration() / _duration : ; ActionInterval::startWithTarget(target);
_last = -1;

_duration和action的duration要大于精度值FLT_EPSILON,第一个action的设置时间与序列总时间的商是_split,代表第一个action在序列上的时间占比。

_last是上次序列update时执行的action下标,0或1,-1代表还未update。

1.4 update

简而言之,update通过当前进度判断要执行哪个action,先计算好这个action的本次进度。如果本次是第一次执行第二个action,要先把第一个action update执行完成。接下来,执行这次的action update,执行后保存这次执行的下标,供下一帧判断。

Sequence对嵌套其中的Sequence递归执行startWithTarget和update。递归退出的条件是found == _last && _actions[found]->isDone(),即最后一个action执行完成。

 void Sequence::update(float t)
{
int found = ; // 当前action下标
float new_t = 0.0f; // 当前action进度 if( t < _split ) // 正在执行第一个action
{
// action[0]
found = ; // 改变下标
if( _split != ) // 第一个action设置的时间不为0
new_t = t / _split; // 计算第一个action进度
else
new_t = ; // 第一个action设置的时间为0,则完成第一个action }
else // 正在执行第二个action
{
// action[1]
found = ; // 改变下标
if ( _split == ) // 第二个action时间为0时
new_t = ; // 完成第二个action
else
new_t = (t-_split) / ( - _split ); // 计算第二个action进度
} if ( found== ) // 正在执行第二个Action
{
if( _last == - ) // 如果上一次update没有执行第一个action
{
// action[0] was skipped, execute it.
_actions[]->startWithTarget(_target); // 初始化第一个action
if (!(sendUpdateEventToScript(1.0f, _actions[])))
_actions[]->update(1.0f); // 直接完成第一个action
_actions[]->stop();
}
else if( _last == ) // 上次update执行的是第一个action,本次update执行第二个,说明第一个执行完成
{
// switching to action 1. stop action 0.
if (!(sendUpdateEventToScript(1.0f, _actions[])))
_actions[]->update(1.0f); // 让第一个执行完成
_actions[]->stop();
}
}
else if(found== && _last== ) // 基本不会发生的情况
{
// Reverse mode ?
// FIXME: Bug. this case doesn't contemplate when _last==-1, found=0 and in "reverse mode"
// since it will require a hack to know if an action is on reverse mode or not.
// "step" should be overridden, and the "reverseMode" value propagated to inner Sequences.
if (!(sendUpdateEventToScript(, _actions[])))
_actions[]->update();
_actions[]->stop();
}
// Last action found and it is done.
if( found == _last && _actions[found]->isDone() )
{
return;
} if( found != _last ) // 正常执行到新的action
{
_actions[found]->startWithTarget(_target); // 新action初始化
}
if (!(sendUpdateEventToScript(new_t, _actions[found])))
_actions[found]->update(new_t); // 执行
_last = found; // 记录这次执行的action下标
}

Cocos2d-x 学习笔记(11.6) Sequence的更多相关文章

  1. Ext.Net学习笔记11:Ext.Net GridPanel的用法

    Ext.Net学习笔记11:Ext.Net GridPanel的用法 GridPanel是用来显示数据的表格,与ASP.NET中的GridView类似. GridPanel用法 直接看代码: < ...

  2. SQL反模式学习笔记11 限定列的有效值

    目标:限定列的有效值,将一列的有效字段值约束在一个固定的集合中.类似于数据字典. 反模式:在列定义上指定可选值 1. 对某一列定义一个检查约束项,这个约束不允许往列中插入或者更新任何会导致约束失败的值 ...

  3. golang学习笔记11 golang要用jetbrain的golang这个IDE工具开发才好

    golang学习笔记11   golang要用jetbrain的golang这个IDE工具开发才好  jetbrain家的全套ide都很好用,一定要dark背景风格才装B   从File-->s ...

  4. Spring MVC 学习笔记11 —— 后端返回json格式数据

    Spring MVC 学习笔记11 -- 后端返回json格式数据 我们常常听说json数据,首先,什么是json数据,总结起来,有以下几点: 1. JSON的全称是"JavaScript ...

  5. Python3+Selenium3+webdriver学习笔记11(cookie处理)

    #!/usr/bin/env python# -*- coding:utf-8 -*-'''Selenium3+webdriver学习笔记11(cookie处理)'''from selenium im ...

  6. 并发编程学习笔记(11)----FutureTask的使用及实现

    1. Future的使用 Future模式解决的问题是.在实际的运用场景中,可能某一个任务执行起来非常耗时,如果我们线程一直等着该任务执行完成再去执行其他的代码,就会损耗很大的性能,而Future接口 ...

  7. 《C++ Primer Plus》学习笔记11

    <C++ Primer Plus>学习笔记11 第17章 输入.输出和文件 <<<<<<<<<<<<<< ...

  8. SpringMVC:学习笔记(11)——依赖注入与@Autowired

    SpringMVC:学习笔记(11)——依赖注入与@Autowired 使用@Autowired 从Spring2.5开始,它引入了一种全新的依赖注入方式,即通过@Autowired注解.这个注解允许 ...

  9. Spring 源码学习笔记11——Spring事务

    Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...

随机推荐

  1. Lucene 全文检索入门

    博客地址:http://www.moonxy.com 一.前言 Lucene 是 apache 软件基金会的一个子项目,由 Doug Cutting 开发,是一个开放源代码的全文检索引擎工具包,但它不 ...

  2. 【Python爬虫】第四课(查询照片拍摄地址)

    首先,要能够查询到照片地址,查询的照片必须要开GPS拍,且上传时用原图…… 查询图片的exif信息,使用exifread包 import exifread img = exifread.process ...

  3. Mybatis源码解析,一步一步从浅入深(六):映射代理类的获取

    在文章:Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码中我们提到了两个问题: 1,为什么在以前的代码流程中从来没有addMapper,而这里却有getMapper? 2,UserDao ...

  4. 【深度学习】Focal Loss 与 GHM——解决样本不平衡问题

    Focal Loss 与 GHM Focal Loss Focal Loss 的提出主要是为了解决难易样本数量不平衡(注意:这有别于正负样本数量不均衡问题)问题.下面以目标检测应用场景来说明. 一些 ...

  5. Unity项目 - DeathtrapDungeon死亡地牢

    目录 游戏原型 项目演示 绘图资源 代码实现 注意事项 技术探讨 参考来源 游戏原型 死亡地牢是一款 2D-Roguelike 的地牢冒险游戏.手握利刃,斩杀怪物,在凶险的地牢内生存下去.但注意,敌人 ...

  6. 《图解HTTP》读后记

    看了一遍又一遍…………不如记一下 用做笔记的方式来看,发现了好多之前没发现的知识点.....感觉前几次看了跟没看一样... 1.1HTTP通常被译为超文本传输协议,但这种译法并不严谨.严谨的译名应该为 ...

  7. Python实战练习_贪吃蛇 (pygame的初次使用)

    正如标题所写的那样,我将一步步的完成本次实战练习——贪吃蛇.废话不多说,感兴趣的伙伴可以一同挑战一下. 首先说明本次实战中我的配备: 开发环境:python 3.7: 开发工具:pycharm2019 ...

  8. 解决CentOS6.x或RedHat Linux 6.x版本不能通过System eth0以固定IP访问外网的问题

    当你在VMware Workstation Pro中,打开从别人那里克隆来的系统,或者是开启迁移后的虚拟机系统时,VMware将会提示你:此虚拟机可能已被移动或 复制.为了配置特定的管理和网络功能.V ...

  9. Android导入Burp Suite证书抓包HTTPS

    需求 Android APP安全测试时,主要工作分为: APK安全 业务安全 APK安全这里不讨论,我说说业务安全,因为大部分的业务校验逻辑还是放在Servier端,这里就会涉及到网络通信了.因此网络 ...

  10. 记录ceph两个rbd删除不了的处理过程

    在一个使用的环境发现两个ceph的rbd删除不了,发现两个rbd都是由于残留了watch的信息.在此记录处理过程. 处理方法 [root@node- ~]# rbd -4cce-b39d-709e05 ...