Asynchronous Clojure:每帧,读取用户输入(如果可用)。输入被传递到循环中,可以是惰性seq of(重复(readline))或预定义列表

Asynchronous Clojure:每帧,读取用户输入(如果可用)。输入被传递到循环中,可以是惰性seq of(重复(readline))或预定义列表,asynchronous,input,clojure,io,game-engine,Asynchronous,Input,Clojure,Io,Game Engine,我一直在琢磨如何实现这一点 概念是我想要: 能够让游戏更新,无论玩家是否有 输入的输入,但如果可用,请使用该输入 能够以预定义的方式无缝交换用户的输入 用于测试目的的顺序 这是我目前拥有的已损坏的实现: (defn game "Runs the simplified version of the main game" [world user-input-machine] (let [input [first (deref user-input-machine 10 ni

我一直在琢磨如何实现这一点

概念是我想要:

  • 能够让游戏更新,无论玩家是否有 输入的输入,但如果可用,请使用该输入
  • 能够以预定义的方式无缝交换用户的输入 用于测试目的的顺序
  • 这是我目前拥有的已损坏的实现:

    (defn game
        "Runs the simplified version of the main game"
        [world user-input-machine]
    
        (let [input [first (deref user-input-machine 10 nil)]]
            (if (not= input "QUIT")
                (do (println input) ; do game logic stuff
                        (game world (rest (deref user-input-machine)))) ;repeat
                world)))
    
    这个想法是通过类似

    (future (repeatedly(readline)))
    

    作为输入。由于许多原因,实施是错误的。我刚刚开始使用clojure,这是我第一次尝试使用未来/延迟/承诺等。 有人能帮我吗

    我遇到了一些相关的问题,这些问题还没有完全回答我想要的问题(我甚至不知道如何表达这个问题):


    据我所知,您正在尝试构建一台机器,它侦听用户输入事件流,并更新“世界”,并触发每个事件的副作用

    基于这一假设,我在这里看到了几个问题:

    • 您可以选择几种协调机制来实现“侦听事件流”(惰性序列、事件流、core.async通道等)的想法。问题是,在这种情况下,您同时使用惰性序列和未来;我建议您只选择一个,例如只使用惰性序列,不使用未来
    • 您正在为自己的循环使用递归。因为JVM没有尾部调用优化,这最终会耗尽堆栈(内存不足),所以我建议您改用loop/recur
    我个人会选择or,它比期货/承诺更适合事件流。如果您的显示模型支持,我会将显示的信息放在代理或atom中,每帧轮询一次以刷新显示,并为每个用户输入事件进行更新。如果没有游戏运作的更多细节,你很难给出更精确的方向

    最后,如果你以前从未做过这种游戏逻辑,我建议你用你熟悉的语言来做,然后用Clojure:)同时学习Clojure和异步控制流可能有点太难了

    (future (["hello", "world", "QUIT"]))