经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 游戏设计 » 查看文章
Cocos2d-x 学习笔记(11.6) Sequence
来源:cnblogs  作者:深潮  时间:2019/7/30 9:22:05  对本文有异议

1. Sequence

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

1.1 成员变量

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

1.2 create方法

4种:

  1. createWithTwoActions(FiniteTimeAction *actionOne, FiniteTimeAction *actionTwo) // 用两个action创建
  2. create(FiniteTimeAction *action1, ...) // 用很多action创建,调用下面的方法
  3. createWithVariableList(FiniteTimeAction *action1, va_list args)
  4. 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。

  1. Sequence* Sequence::createWithVariableList(FiniteTimeAction *action1, va_list args)
  2. {
  3. FiniteTimeAction *now;
  4. FiniteTimeAction *prev = action1;
  5. bool bOneAction = true;
  6. while (action1)
  7. {
  8. now = va_arg(args, FiniteTimeAction*);
  9. if (now)
  10. {
  11. prev = createWithTwoActions(prev, now);
  12. bOneAction = false;
  13. }
  14. else
  15. {
  16. // If only one action is added to Sequence, make up a Sequence by adding a simplest finite time action.
  17. if (bOneAction)
  18. {
  19. prev = createWithTwoActions(prev, ExtraAction::create());
  20. }
  21. break;
  22. }
  23. }
  24. return ((Sequence*)prev);
  25. }

create:

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

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

1.3 startWithTarget

runAction时调用。

  1. if (_duration > FLT_EPSILON)
  2. _split = _actions[0]->getDuration() > FLT_EPSILON ? _actions[0]->getDuration() / _duration : 0;

    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执行完成。

  1. 1 void Sequence::update(float t)
  2. 2 {
  3. 3 int found = 0; // 当前action下标
  4. 4 float new_t = 0.0f; // 当前action进度
  5. 5
  6. 6 if( t < _split ) // 正在执行第一个action
  7. 7 {
  8. 8 // action[0]
  9. 9 found = 0; // 改变下标
  10. 10 if( _split != 0 ) // 第一个action设置的时间不为0
  11. 11 new_t = t / _split; // 计算第一个action进度
  12. 12 else
  13. 13 new_t = 1; // 第一个action设置的时间为0,则完成第一个action
  14. 14
  15. 15 }
  16. 16 else // 正在执行第二个action
  17. 17 {
  18. 18 // action[1]
  19. 19 found = 1; // 改变下标
  20. 20 if ( _split == 1 ) // 第二个action时间为0时
  21. 21 new_t = 1; // 完成第二个action
  22. 22 else
  23. 23 new_t = (t-_split) / (1 - _split ); // 计算第二个action进度
  24. 24 }
  25. 25
  26. 26 if ( found==1 ) // 正在执行第二个Action
  27. 27 {
  28. 28 if( _last == -1 ) // 如果上一次update没有执行第一个action
  29. 29 {
  30. 30 // action[0] was skipped, execute it.
  31. 31 _actions[0]->startWithTarget(_target); // 初始化第一个action
  32. 32 if (!(sendUpdateEventToScript(1.0f, _actions[0])))
  33. 33 _actions[0]->update(1.0f); // 直接完成第一个action
  34. 34 _actions[0]->stop();
  35. 35 }
  36. 36 else if( _last == 0 ) // 上次update执行的是第一个action,本次update执行第二个,说明第一个执行完成
  37. 37 {
  38. 38 // switching to action 1. stop action 0.
  39. 39 if (!(sendUpdateEventToScript(1.0f, _actions[0])))
  40. 40 _actions[0]->update(1.0f); // 让第一个执行完成
  41. 41 _actions[0]->stop();
  42. 42 }
  43. 43 }
  44. 44 else if(found==0 && _last==1 ) // 基本不会发生的情况
  45. 45 {
  46. 46 // Reverse mode ?
  47. 47 // FIXME: Bug. this case doesn't contemplate when _last==-1, found=0 and in "reverse mode"
  48. 48 // since it will require a hack to know if an action is on reverse mode or not.
  49. 49 // "step" should be overridden, and the "reverseMode" value propagated to inner Sequences.
  50. 50 if (!(sendUpdateEventToScript(0, _actions[1])))
  51. 51 _actions[1]->update(0);
  52. 52 _actions[1]->stop();
  53. 53 }
  54. 54 // Last action found and it is done.
  55. 55 if( found == _last && _actions[found]->isDone() )
  56. 56 {
  57. 57 return;
  58. 58 }
  59. 59
  60. 60 if( found != _last ) // 正常执行到新的action
  61. 61 {
  62. 62 _actions[found]->startWithTarget(_target); // 新action初始化
  63. 63 }
  64. 64 if (!(sendUpdateEventToScript(new_t, _actions[found])))
  65. 65 _actions[found]->update(new_t); // 执行
  66. 66 _last = found; // 记录这次执行的action下标
  67. 67 }

原文链接:http://www.cnblogs.com/deepcho/p/cocos2dx-action-sequence.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号