在clojure中实现人工时间

时间:2015-11-30 19:31:48

标签: timer clojure

我知道在编写clojure时远离状态通常是个好主意。然而,时间在我看来是非常有状态的。

我的目标是在我的游戏中代表时间,我正在用clojure写作。我的想法是将计时器作为一个单独的过程运行,并在需要时读取它的值,但似乎没有任何自然的方式在clojure中实现这一点。

你如何在clojure的简单角色扮演游戏中实现时间?

2 个答案:

答案 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