WorldClock.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. using System;
  2. using System.Collections.Generic;
  3. namespace DragonBones
  4. {
  5. /**
  6. * @language zh_CN
  7. * WorldClock 提供时钟支持,为每个加入到时钟的 IAnimatable 对象更新时间。
  8. * @see DragonBones.IAnimateble
  9. * @see DragonBones.Armature
  10. * @version DragonBones 3.0
  11. */
  12. public class WorldClock : IAnimateble
  13. {
  14. /**
  15. * @language zh_CN
  16. * 当前时间。 (以秒为单位)
  17. * @version DragonBones 3.0
  18. */
  19. public float time = DateTime.Now.Ticks / 100.0f / DragonBones.SECOND_TO_MILLISECOND;
  20. /**
  21. * @language zh_CN
  22. * 时间流逝速度,用于控制动画变速播放。 [0: 停止播放, (0~1): 慢速播放, 1: 正常播放, (1~N): 快速播放]
  23. * @default 1
  24. * @version DragonBones 3.0
  25. */
  26. public float timeScale = 1.0f;
  27. private readonly List<IAnimateble> _animatebles = new List<IAnimateble>();
  28. private WorldClock _clock = null;
  29. /**
  30. * @language zh_CN
  31. * 创建一个新的 WorldClock 实例。
  32. * 通常并不需要单独创建 WorldClock 实例,可以直接使用 WorldClock.clock 静态实例。
  33. * (创建更多独立的 WorldClock 实例可以更灵活的为需要更新的 IAnimateble 实例分组,用于控制不同组不同的播放速度)
  34. * @version DragonBones 3.0
  35. */
  36. public WorldClock()
  37. {
  38. }
  39. /**
  40. * @language zh_CN
  41. * 为所有的 IAnimatable 实例更新时间。
  42. * @param passedTime 前进的时间。 (以秒为单位,当设置为 -1 时将自动计算当前帧与上一帧的时间差)
  43. * @version DragonBones 3.0
  44. */
  45. public void AdvanceTime(float passedTime)
  46. {
  47. if (float.IsNaN(passedTime))
  48. {
  49. passedTime = 0.0f;
  50. }
  51. if (passedTime < 0.0f)
  52. {
  53. passedTime = DateTime.Now.Ticks / 100.0f / DragonBones.SECOND_TO_MILLISECOND - time;
  54. }
  55. if (timeScale != 1.0f)
  56. {
  57. passedTime *= timeScale;
  58. }
  59. if (passedTime < 0.0f)
  60. {
  61. time -= passedTime;
  62. }
  63. else
  64. {
  65. time += passedTime;
  66. }
  67. if (passedTime > 0.0f)
  68. {
  69. int i = 0, r = 0, l = _animatebles.Count;
  70. for (; i < l; ++i)
  71. {
  72. var animateble = _animatebles[i];
  73. if (animateble != null)
  74. {
  75. if (r > 0)
  76. {
  77. _animatebles[i - r] = animateble;
  78. _animatebles[i] = null;
  79. }
  80. animateble.AdvanceTime(passedTime);
  81. }
  82. else
  83. {
  84. r++;
  85. }
  86. }
  87. if (r > 0)
  88. {
  89. l = _animatebles.Count;
  90. for (; i < l; ++i)
  91. {
  92. var animateble = _animatebles[i];
  93. if (animateble != null)
  94. {
  95. _animatebles[i - r] = animateble;
  96. }
  97. else
  98. {
  99. r++;
  100. }
  101. }
  102. DragonBones.ResizeList(_animatebles, l - r, null);
  103. }
  104. }
  105. }
  106. /**
  107. * 是否包含 IAnimatable 实例
  108. * @param value IAnimatable 实例。
  109. * @version DragonBones 3.0
  110. */
  111. public bool Contains(IAnimateble value) {
  112. return _animatebles.Contains(value);
  113. }
  114. /**
  115. * @language zh_CN
  116. * 添加 IAnimatable 实例。
  117. * @param value IAnimatable 实例。
  118. * @version DragonBones 3.0
  119. */
  120. public void Add(IAnimateble value)
  121. {
  122. if (value != null && !_animatebles.Contains(value))
  123. {
  124. _animatebles.Add(value);
  125. value.clock = this;
  126. }
  127. }
  128. /**
  129. * @language zh_CN
  130. * 清除所有的 IAnimatable 实例。
  131. * @version DragonBones 3.0
  132. */
  133. public void Remove(IAnimateble value)
  134. {
  135. var index = _animatebles.IndexOf(value);
  136. if (index >= 0)
  137. {
  138. _animatebles[index] = null;
  139. value.clock = null;
  140. }
  141. }
  142. /**
  143. * @language zh_CN
  144. * 清除所有的 IAnimatable 实例。
  145. * @version DragonBones 3.0
  146. */
  147. public void Clear()
  148. {
  149. for (int i = 0, l = _animatebles.Count; i < l; ++i)
  150. {
  151. var animateble = _animatebles[i];
  152. _animatebles[i] = null;
  153. if (animateble != null)
  154. {
  155. animateble.clock = null;
  156. }
  157. }
  158. }
  159. /**
  160. * @inheritDoc
  161. */
  162. public WorldClock clock
  163. {
  164. get { return _clock; }
  165. set
  166. {
  167. if (_clock == value)
  168. {
  169. return;
  170. }
  171. var prevClock = _clock;
  172. _clock = value;
  173. if (prevClock != null)
  174. {
  175. prevClock.Remove(this);
  176. }
  177. if (_clock != null)
  178. {
  179. _clock.Add(this);
  180. }
  181. }
  182. }
  183. }
  184. }