diff --git a/resources/public/index.html b/resources/public/index.html
index 1949762..4ac2be2 100644
--- a/resources/public/index.html
+++ b/resources/public/index.html
@@ -12,10 +12,11 @@
FPS:
Position:
Velocity:
+ State:
diff --git a/src/cljs/frpong/core.cljs b/src/cljs/frpong/core.cljs
index 2ebb12a..869060c 100644
--- a/src/cljs/frpong/core.cljs
+++ b/src/cljs/frpong/core.cljs
@@ -50,14 +50,32 @@
pos-next [(+ x (* vel-x tick)) (+ y (* vel-y tick))]]
(>! pos-out pos-next))))
-(defn collision-detector
- [{:keys [width height padding]}
- ticks ball-state pos pl-pos pr-pos vel-in vel-out]
- (let [adjust-v (fn [p v size]
- (cond
- (< p padding) [(abs v) :collision]
- (> p (- size padding)) [(- (abs v)) :collision]
- :else [v :moving]))]
+(defn collision-detector
+ [{:keys [width height padding paddle-size paddle-width]}
+ ticks game-state pos pl-pos pr-pos vel-in vel-out]
+ (let [adjust-v (fn [state v] [(condp = state
+ :collision-left (abs v)
+ :collision-right (- (abs v))
+ :moving v
+ :gameover 0)
+ state])
+ detect-y-collision (fn [y] (cond
+ (< y padding) :collision-left
+ (> y (- height padding)) :collision-right
+ :else :moving))
+ detect-x-collision (fn [x y pl-pos pr-pos]
+ (cond
+ (< x (+ paddle-width padding))
+ (if (and (> y (+ pl-pos padding))
+ (< y (- (+ pl-pos paddle-size) padding)))
+ :collision-left
+ :gameover)
+ (> x (- width (+ paddle-width padding)))
+ (if (and (> y (+ pr-pos padding))
+ (< y (- (+ pr-pos paddle-size) padding)))
+ :collision-right
+ :gameover)
+ :else :moving))]
(go-loop
(let [tick (! vel-out [vel-xn vel-yn])
- (>! ball-state
- (if (or (= bs-x :collision) (= bs-y :collision)) :collision :moving))))))
+ (>! game-state
+ (cond
+ (= bs-x :gameover) :gameover
+ (or (= bs-x :collision-left) (= bs-x :collision-right)
+ (= bs-y :collision-left) (= bs-y :collision-right)) :collision
+ :else :moving))))))
(defn paddle-positioner [keycodes max-y movement pos-in pos-out]
(let [keys (h/key-chan keycodes)]
(go-loop
- (let [dir (! pos-out
- (condp = dir
+ (condp = (! ticks (! c2 v)
- (while true
- (>! c2 (! c v)))
+ (go (loop []
+ (if-let [v (! c v)
+ (recur))
+ (close! c))))
c))
(defn multiplex [in cs-or-n]
@@ -36,86 +30,72 @@
(go (loop []
(let [x (! c (f (! c (f v)) (recur))
+ (close! c))))
c))
-(defn filter-chan
- ([f source] (filter-chan (chan) f source))
- ([c f source]
- (go-loop
- (let [v (! c v))))
+(defn filter-chan [f source]
+ (let [c (chan)]
+ (go (loop []
+ (if-let [v (! c v)) (recur))
+ (close! c))))
c))
(defn interval-chan
([msecs]
(interval-chan msecs :leading))
([msecs type]
- (interval-chan (chan (dropping-buffer 1)) msecs type))
- ([c msecs type]
- (condp = type
- :leading (go-loop
- (>! c (now))
- (! c (now))))
- c))
+ (let [c (chan (dropping-buffer 1))]
+ (condp = type
+ :leading (go-loop
+ (>! c (now))
+ (! c (now))))
+ c)))
-(defn throttle
- ([source control]
- (throttle (chan) source control))
- ([c source control]
+(defn throttle [source control]
+ (let [c (chan)]
(go
(loop [state ::init last nil]
(let [[v sc] (alts! [source control])]
(condp = sc
source (condp = state
- ::init (do (>! c v)
- (recur ::throttling last))
+ ::init (do (>! c v) (recur ::throttling last))
::throttling (recur state v))
control (if last
- (do (>! c last)
- (recur state nil))
+ (do (>! c last) (recur state nil))
(recur ::init last))))))
c))
-(defn sustain
- ([source control]
- (sustain (chan) source control))
- ([c source control]
+(defn sustain [source control]
+ (let [c (chan)]
(go
(loop [last nil]
(let [[v ch] (alts! [source control] :priority true)]
- (condp = ch
- source (do (>! c v) (recur v))
- control (do (when last (>! c last)) (recur last))))))
+ (if (nil? v)
+ (close! c)
+ (condp = ch
+ source (do (>! c v) (recur v))
+ control (do (when last (>! c last)) (recur last)))))))
c))
-(defn debounce
- ([source msecs]
- (debounce (chan) source msecs))
- ([c source msecs]
+(defn debounce [source msecs]
+ (let [c (chan)]
(go
(loop [state ::init cs [source]]
(let [[_ threshold] cs]
@@ -132,10 +112,8 @@
threshold (recur ::init (pop cs)))))))
c))
-(defn after-last
- ([source msecs]
- (after-last (chan) source msecs))
- ([c source msecs]
+(defn after-last [source msecs]
+ (let [c (chan)]
(go
(loop [cs [source]]
(let [[_ toc] cs]
@@ -147,22 +125,19 @@
toc (do (>! c (now)) (pop cs))))))))
c))
-(defn fan-in
- ([ins] (fan-in (chan) ins))
- ([c ins]
- (go (while true
- (let [[x] (alts! ins)]
- (>! c x))))
+(defn fan-in [ins]
+ (let [c (chan)]
+ (go-loop
+ (let [[x] (alts! ins)]
+ (>! c x)))
c))
-(defn distinct-chan
- ([source] (distinct-chan (chan) source))
- ([c source]
+(defn distinct-chan [source]
+ (let [c (chan)]
(go
(loop [last ::init]
(let [v (! c v))
+ (when-not (= last v) (>! c v))
(recur v))))
c))
@@ -181,20 +156,28 @@
c))
(defn frame-chan []
- (let [c (chan (sliding-buffer 1000))
+ (let [fc (chan (sliding-buffer 1000))
+ rc (chan (sliding-buffer 10))
step (fn step [ts]
(let [req-id (.requestAnimationFrame js/window step)]
- (put! c [ts req-id])))]
+ (put! fc ts)
+ (put! rc req-id)))
+ stop-fn (fn []
+ (go (loop []
+ (if-let [id (! c count)
- (recur (inc count))))
+ (if-let [v (! c count) (recur (inc count)))
+ (close! c))))
c))
(defn diff-chan [source]
@@ -202,17 +185,17 @@
(go
(let [start (! c (- ts start))
- (recur ts)))))
+ (if-let [v (! c (- v start)) (recur v))
+ (close! c)))))
c))
(defn dropping-chan [source n]
(let [c (chan)]
(go
(loop [count 0]
- (if (= count 0)
- (>! c (! c v))
+ (recur (rem (inc count) n)))
+ (close! c))))
c))