Animation 如何使用core.async防止动画重叠?

Animation 如何使用core.async防止动画重叠?,animation,clojure,clojurescript,core.async,Animation,Clojure,Clojurescript,Core.async,我有一个循环处理角色的动画--设置图像只需按一个键并显示相应的图像 (defn main-animation-loop [] (go (while true (set-image! :normal) (<! (timeout 8000)) (set-image! :blink) (<! (timeout 150))))) (defn主动画循环[] (虽然是真的 (设置图像!:正常) ( 每隔一段时间,角色需要执行一

我有一个循环处理角色的动画--
设置图像只需按一个键并显示相应的图像

(defn main-animation-loop []
  (go (while true
        (set-image! :normal)
        (<! (timeout 8000))
        (set-image! :blink)
        (<! (timeout 150)))))
(defn主动画循环[]
(虽然是真的
(设置图像!:正常)
(
每隔一段时间,角色需要执行一些特殊动作。这应该能够中断主动画:

(defn dance! []
  (go (set-image! :look-left)
      (<! (timeout 1000))
      (set-image! :look-right)
      (<! (timeout 1000))
      (set-image! :wave)
      (<! (timeout 2000))))
(defn dance![]
(开始(设置图像!:向左看)
(

当舞蹈程序正在进行时,暂停主动画的好方法是什么?

在CSP风格的编程中,通常会将控制通道传递给事件循环,这样您至少可以告诉它们何时停止。在这种情况下,如果有一个控制通道转到
主动画循环
,并且您将其副本交给
dance!
,然后dance可以告诉
主动画循环
适当地暂停和取消暂停。或者停止它,然后再次启动它(如果其他人正在使用它,则通过相同的控制通道)

我使用这样的模式每次在事件循环中检查消息:

(go (while (not= control-chan
                 (second (async/alts! [control-chan (async/timeout arg)])))
           (do-stuff-here))
这将检查是超时还是控制通道导致了中断

(defn main-animation-loop [control-chan]
  (go (while (not= control-chan
                 (second (async/alts! [control-chan (async/timeout 150)])))
        (set-image! :normal)
        (<! (timeout 8000))
        (set-image! :blink))))

(defn dance! [control-chan]
  (go (!> control-chan :stop)
      (set-image! :look-left)
      (<! (timeout 1000))
      (set-image! :look-right)
      (<! (timeout 1000))
      (set-image! :wave)
      (<! (timeout 2000))
      (main-animation-loop control-chan)))
(defn主动画循环[控制通道]
(go)(while)(not=控制)
(第二个(异步/高度![控制通道(异步/超时150)]))
(设置图像!:正常)
(控制:停止)
(设置图像!:向左看)
(

通过将相同的通道传递给两个功能,您允许它们彼此通信。
主动画循环
将保持循环,只要它接收到的所有消息都来自超时通道。一旦它看到其中一个来自控制通道而不是超时,它将停止。这允许
dance!
通过向控制通道发送任何消息来告诉它停止。在类似的代码中,我经常让主事件循环检查消息的内容,并不仅仅是停止,尽管在这种情况下停止就足够了,因为
舞蹈!
可以简单地再次启动事件循环。

我在这里有些不知所措。完整的代码解决方案o这个问题至少对我很有帮助。谢谢。我已经扩展了我的答案,虽然没有实际的动画部分,但我还没有运行它。为什么文档说
alts!!
不能在
go
块中使用?这是因为在go块中使用的版本是
alts!
(有一个!)我马上把它修好。