我知道在编写clojure时远离状态通常是个好主意。然而,时间在我看来是非常有状态的。
我的目标是在我的游戏中代表时间,我正在用clojure写作。我的想法是将计时器作为一个单独的过程运行,并在需要时读取它的值,但似乎没有任何自然的方式在clojure中实现这一点。
你如何在clojure的简单角色扮演游戏中实现时间?
答案 0 :(得分:1)
我已将this Java answer中的代码改编为我的date-dif函数:
(defn date-dif [d1 d2]
(let [tu java.util.concurrent.TimeUnit/SECONDS
t1 (. d1 getTime)
t2 (. d2 getTime)]
(. tu convert (- t2 t1) java.util.concurrent.TimeUnit/MILLISECONDS)))
(defn start-timer []
(let [cur-time (new java.util.Date)]
(fn [] (date-dif cur-time (new java.util.Date)))))
start-timer
将创建并返回一个函数,该函数在调用时返回自创建函数以来的秒数。要使用它,请执行以下操作:
rpg-time.core> (def my-timer (start-timer))
#'rpg-time.core/my-timer
rpg-time.core> (my-timer)
3
rpg-time.core> (my-timer)
5
rpg-time.core> (my-timer)
6
如果你想要一个不同的时间单位而不是几秒钟,用here更合适的东西替换SECONDS。
您可以考虑其他选择。这只是我想到的第一个,编码或使用起来都不是很难。
答案 1 :(得分:1)
计时器非常无状态。实际上,计时器是它开始的时间点。
为简单起见,我将在此使用clj-time
。
(require '[clj-time.core :as t]
'[clj-time.coerce :as c])
(defn timer
[]
(let [now-sec #(-> (t/now) c/to-long (/ 1000) int)
start (now-sec)]
#(- (now-sec) start)))
(def my-timer (timer))
;; after a second
(my-timer)
;;=> 1
;; and after 2 seconds more
(my-timer)
;;=> 3