我在clojure中編寫了一個多線程彈跳球程序。在啓動動畫線程後,我會 -在Clojure中使用代理的多線程彈跳球程序
(send-balls)
啓動彈跳球線程。球不會移動,這是顯示在控制檯上 -
(#<[email protected] FAILED: #<[email protected]: {:x 759, :y 629, :x-speed 3, :y-speed 1}>> #<[email protected] FAILED: #<[email protected]: {:x 794, :y 258, :x-speed 2, :y-speed 3}>> #<[email protected] FAILED: #<[email protected]: {:x 831, :y 251, :x-speed 4, :y-speed 2}>>)
有人可以指出這裏發生了什麼?
(import
'(java.awt Color Graphics Dimension)
'(java.awt.image BufferedImage)
'(javax.swing JPanel JFrame))
(def width 1000)
(def height 1000)
(def number-of-balls 3)
(def rad 20)
(def origin-x 100)
(def origin-y 100)
(def box-height 500)
(def box-width 700)
(def max-x (+ origin-x box-width (* 4 rad)))
(def max-y (+ origin-y box-height (* 4 rad)))
(def min-x origin-x)
(def min-y origin-y)
(defn init-x
[]
(+ (rand-int (- max-x min-x)) min-x))
(defn init-y
[]
(+ (rand-int (- max-y min-y)) min-y))
(defstruct ball :x :y :x-speed :y-speed)
(def balls
(apply vector (map (fn [_] (ref (struct ball (init-x) (init-y)
(rand-int 10) (rand-int 10))))
(range number-of-balls))))
(def ball-agents (apply vector (map agent balls)))
(defn get-ball
[n]
(balls n))
(defn set-new-x
[ball]
(let [x (@ball :x)
x-speed (@ball :x-speed)
new-x (+ x x-speed)]
(dosync
(if (and (>= new-x min-x) (<= new-x max-x))
(ref-set ball (assoc @ball :x new-x))
(ref-set ball (assoc @ball :x-speed (* -1 x-speed)))))
(println "the new x is " @(ball :x)))
@ball)
(defn set-new-y
[ball]
(let [y (@ball :y)
y-speed (@ball :y-speed)
new-y (+ y y-speed)]
(dosync
(if (and (>= new-y min-y) (<= new-y max-y))
(ref-set ball (assoc @ball :y new-y))
(ref-set ball (assoc @ball :y-speed (* -1 y-speed))))))
@ball)
(defn paint-balls
[bg x y]
(doto bg
(.setColor (. Color red))
(.fillOval x y rad rad)))
(defn render
[g]
(let [img (new BufferedImage width height
(. BufferedImage TYPE_INT_ARGB))
bg (. img (getGraphics))]
(doto bg
(.setColor (. Color white))
(.fillRect 0 0 (. img (getWidth)) (. img (getHeight)))
(.setColor (. Color red))
(.drawRect origin-x origin-y (+ origin-x box-width) (+ origin-y box-height)))
(dorun
(for [i (range number-of-balls)]
(do
(paint-balls bg (@(get-ball i) :x) (@(get-ball i) :y)))))
(. g (drawImage img 0 0 nil))
(. bg (dispose))))
(def panel (doto (proxy [JPanel] []
(paint [g] (render g)))
(.setPreferredSize (new Dimension
width
height))))
(def frame (doto (new JFrame) (.add panel) .pack .show))
(def animator (agent nil))
(defn bounce
[x]
(while true
(set-new-x @*agent*)
(set-new-y @*agent*)
(. Thread (sleep 100))
(println "here in bounce " *agent*)))
(defn animation
[x]
(send-off *agent* animation)
(. panel (repaint))
(. Thread (sleep 100)))
(defn send-balls
[]
(doall
(for [i (range number-of-balls)]
(do
(send-off (ball-agents i) bounce)))))
(send-off animator animation)
看起來您的代理更新失敗 - 可能是由於反彈功能中的異常。我懷疑有一個問題是你的解除引用過多,即「@ * agent *」實際上應該是「\ * agent \ *」。 – mikera 2011-05-14 15:13:54
@mikera - 我試過了,但那不是... – Pranav 2011-05-14 18:30:47