WorldClock.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /**
  2. * The MIT License (MIT)
  3. *
  4. * Copyright (c) 2012-2017 DragonBones team and other contributors
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  7. * this software and associated documentation files (the "Software"), to deal in
  8. * the Software without restriction, including without limitation the rights to
  9. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10. * the Software, and to permit persons to whom the Software is furnished to do so,
  11. * subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all
  14. * copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. using System;
  24. using System.Collections.Generic;
  25. namespace DragonBones
  26. {
  27. /// <summary>
  28. /// - Worldclock provides clock support for animations, advance time for each IAnimatable object added to the instance.
  29. /// </summary>
  30. /// <see cref="DragonBones.IAnimateble"/>
  31. /// <see cref="DragonBones.Armature"/>
  32. /// <version>DragonBones 3.0</version>
  33. /// <language>en_US</language>
  34. /// <summary>
  35. /// - WorldClock 对动画提供时钟支持,为每个加入到该实例的 IAnimatable 对象更新时间。
  36. /// </summary>
  37. /// <see cref="DragonBones.IAnimateble"/>
  38. /// <see cref="DragonBones.Armature"/>
  39. /// <version>DragonBones 3.0</version>
  40. /// <language>zh_CN</language>
  41. public class WorldClock : IAnimatable
  42. {
  43. /// <summary>
  44. /// - Current time. (In seconds)
  45. /// </summary>
  46. /// <version>DragonBones 3.0</version>
  47. /// <language>en_US</language>
  48. /// <summary>
  49. /// - 当前的时间。 (以秒为单位)
  50. /// </summary>
  51. /// <version>DragonBones 3.0</version>
  52. /// <language>zh_CN</language>
  53. public float time = 0.0f;
  54. /// <summary>
  55. /// - The play speed, used to control animation speed-shift play.
  56. /// [0: Stop play, (0~1): Slow play, 1: Normal play, (1~N): Fast play]
  57. /// </summary>
  58. /// <default>1.0</default>
  59. /// <version>DragonBones 3.0</version>
  60. /// <language>en_US</language>
  61. /// <summary>
  62. /// - 播放速度,用于控制动画变速播放。
  63. /// [0: 停止播放, (0~1): 慢速播放, 1: 正常播放, (1~N): 快速播放]
  64. /// </summary>
  65. /// <default>1.0</default>
  66. /// <version>DragonBones 3.0</version>
  67. /// <language>zh_CN</language>
  68. public float timeScale = 1.0f;
  69. private float _systemTime = 0.0f;
  70. private readonly List<IAnimatable> _animatebles = new List<IAnimatable>();
  71. private WorldClock _clock = null;
  72. /// <summary>
  73. /// - Creating a Worldclock instance. Typically, you do not need to create Worldclock instance.
  74. /// When multiple Worldclock instances are running at different speeds, can achieving some specific animation effects, such as bullet time.
  75. /// </summary>
  76. /// <version>DragonBones 3.0</version>
  77. /// <language>en_US</language>
  78. /// <summary>
  79. /// - 创建一个 WorldClock 实例。通常并不需要创建 WorldClock 实例。
  80. /// 当多个 WorldClock 实例使用不同的速度运行时,可以实现一些特殊的动画效果,比如子弹时间等。
  81. /// </summary>
  82. /// <version>DragonBones 3.0</version>
  83. /// <language>zh_CN</language>
  84. public WorldClock(float time = -1.0f)
  85. {
  86. this.time = time;
  87. this._systemTime = DateTime.Now.Ticks * 0.01f * 0.001f;
  88. }
  89. /// <summary>
  90. /// - Advance time for all IAnimatable instances.
  91. /// </summary>
  92. /// <param name="passedTime">- Passed time. [-1: Automatically calculates the time difference between the current frame and the previous frame, [0~N): Passed time] (In seconds)</param>
  93. /// <version>DragonBones 3.0</version>
  94. /// <language>en_US</language>
  95. /// <summary>
  96. /// - 为所有的 IAnimatable 实例更新时间。
  97. /// </summary>
  98. /// <param name="passedTime">- 前进的时间。 [-1: 自动计算当前帧与上一帧的时间差, [0~N): 前进的时间] (以秒为单位)</param>
  99. /// <version>DragonBones 3.0</version>
  100. /// <language>zh_CN</language>
  101. public void AdvanceTime(float passedTime)
  102. {
  103. if (float.IsNaN(passedTime))
  104. {
  105. passedTime = 0.0f;
  106. }
  107. var currentTime = DateTime.Now.Ticks * 0.01f * 0.001f;
  108. if (passedTime < 0.0f)
  109. {
  110. passedTime = currentTime - this._systemTime;
  111. }
  112. this._systemTime = currentTime;
  113. if (this.timeScale != 1.0f)
  114. {
  115. passedTime *= this.timeScale;
  116. }
  117. if (passedTime == 0.0f)
  118. {
  119. return;
  120. }
  121. if (passedTime < 0.0f)
  122. {
  123. this.time -= passedTime;
  124. }
  125. else
  126. {
  127. this.time += passedTime;
  128. }
  129. int i = 0, r = 0, l = _animatebles.Count;
  130. for (; i < l; ++i)
  131. {
  132. var animateble = _animatebles[i];
  133. if (animateble != null)
  134. {
  135. if (r > 0)
  136. {
  137. _animatebles[i - r] = animateble;
  138. _animatebles[i] = null;
  139. }
  140. animateble.AdvanceTime(passedTime);
  141. }
  142. else
  143. {
  144. r++;
  145. }
  146. }
  147. if (r > 0)
  148. {
  149. l = _animatebles.Count;
  150. for (; i < l; ++i)
  151. {
  152. var animateble = _animatebles[i];
  153. if (animateble != null)
  154. {
  155. _animatebles[i - r] = animateble;
  156. }
  157. else
  158. {
  159. r++;
  160. }
  161. }
  162. _animatebles.ResizeList(l - r, null);
  163. }
  164. }
  165. /// <summary>
  166. /// - Check whether contains a specific instance of IAnimatable.
  167. /// </summary>
  168. /// <param name="value">- The IAnimatable instance.</param>
  169. /// <version>DragonBones 3.0</version>
  170. /// <language>en_US</language>
  171. /// <summary>
  172. /// - 检查是否包含特定的 IAnimatable 实例。
  173. /// </summary>
  174. /// <param name="value">- IAnimatable 实例。</param>
  175. /// <version>DragonBones 3.0</version>
  176. /// <language>zh_CN</language>
  177. public bool Contains(IAnimatable value)
  178. {
  179. if (value == this)
  180. {
  181. return false;
  182. }
  183. IAnimatable ancestor = value;
  184. while (ancestor != this && ancestor != null)
  185. {
  186. ancestor = ancestor.clock;
  187. }
  188. return ancestor == this;
  189. }
  190. /// <summary>
  191. /// - Add IAnimatable instance.
  192. /// </summary>
  193. /// <param name="value">- The IAnimatable instance.</param>
  194. /// <version>DragonBones 3.0</version>
  195. /// <language>en_US</language>
  196. /// <summary>
  197. /// - 添加 IAnimatable 实例。
  198. /// </summary>
  199. /// <param name="value">- IAnimatable 实例。</param>
  200. /// <version>DragonBones 3.0</version>
  201. /// <language>zh_CN</language>
  202. public void Add(IAnimatable value)
  203. {
  204. if (value != null && !_animatebles.Contains(value))
  205. {
  206. _animatebles.Add(value);
  207. value.clock = this;
  208. }
  209. }
  210. /// <summary>
  211. /// - Removes a specified IAnimatable instance.
  212. /// </summary>
  213. /// <param name="value">- The IAnimatable instance.</param>
  214. /// <version>DragonBones 3.0</version>
  215. /// <language>en_US</language>
  216. /// <summary>
  217. /// - 移除特定的 IAnimatable 实例。
  218. /// </summary>
  219. /// <param name="value">- IAnimatable 实例。</param>
  220. /// <version>DragonBones 3.0</version>
  221. /// <language>zh_CN</language>
  222. public void Remove(IAnimatable value)
  223. {
  224. var index = _animatebles.IndexOf(value);
  225. if (index >= 0)
  226. {
  227. _animatebles[index] = null;
  228. value.clock = null;
  229. }
  230. }
  231. /// <summary>
  232. /// - Clear all IAnimatable instances.
  233. /// </summary>
  234. /// <version>DragonBones 3.0</version>
  235. /// <language>en_US</language>
  236. /// <summary>
  237. /// - 清除所有的 IAnimatable 实例。
  238. /// </summary>
  239. /// <version>DragonBones 3.0</version>
  240. /// <language>zh_CN</language>
  241. public void Clear()
  242. {
  243. for (int i = 0, l = _animatebles.Count; i < l; ++i)
  244. {
  245. var animateble = _animatebles[i];
  246. _animatebles[i] = null;
  247. if (animateble != null)
  248. {
  249. animateble.clock = null;
  250. }
  251. }
  252. }
  253. /// <summary>
  254. /// - Deprecated, please refer to {@link dragonBones.BaseFactory#clock}.
  255. /// </summary>
  256. /// <language>en_US</language>
  257. /// <summary>
  258. /// - 已废弃,请参考 {@link dragonBones.BaseFactory#clock}。
  259. /// </summary>
  260. /// <language>zh_CN</language>
  261. [System.Obsolete("")]
  262. /// <inheritDoc/>
  263. public WorldClock clock
  264. {
  265. get { return _clock; }
  266. set
  267. {
  268. if (_clock == value)
  269. {
  270. return;
  271. }
  272. if (_clock != null)
  273. {
  274. _clock.Remove(this);
  275. }
  276. _clock = value;
  277. if (_clock != null)
  278. {
  279. _clock.Add(this);
  280. }
  281. }
  282. }
  283. }
  284. }