Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Got positioner and collision-detector working
- Loading branch information
Showing
5 changed files
with
243 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
(ns frpong.core) | ||
|
||
(defn foo | ||
"I don't do a whole lot." | ||
[x] | ||
(println x "Hello, World!")) | ||
(defmacro go-loop [& body] | ||
`(cljs.core.async.macros/go | ||
(while true | ||
~@body))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,61 @@ | ||
(ns frpong.core | ||
(:require [cljs.core.async :as async | ||
:refer [<! >! chan put!]] | ||
[domina :as dom] | ||
(:require [frpong.helpers :as h] | ||
[cljs.core.async :as async | ||
:refer [<! >! chan put! close! sliding-buffer dropping-buffer timeout]] | ||
[domina :as dom :refer [log]] | ||
[domina.events :as ev]) | ||
(:require-macros [cljs.core.async.macros :as m :refer [go]])) | ||
(:require-macros [cljs.core.async.macros :as m :refer [go]] | ||
[frpong.core :refer (go-loop)])) | ||
|
||
(defn positioner [tick-chan vel-chan pos-chan-in pos-chan-out] | ||
(go-loop | ||
(let [tick (<! tick-chan) | ||
[vel-x vel-y] (<! vel-chan) | ||
[x y] (<! pos-chan-in) | ||
pos-next [(+ x (* vel-x tick)) (+ y (* vel-y tick))]] | ||
(>! pos-chan-out pos-next)))) | ||
|
||
(defn event-chan [event-type] | ||
(let [c (chan)] | ||
(ev/listen! js/document event-type | ||
(fn [e] (put! c e))) | ||
c)) | ||
(defn collision-detector [width height tick-chan pos-chan vel-chan-in vel-chan-out] | ||
(go-loop | ||
(let [tick (<! tick-chan) | ||
[vel-x vel-y] (<! vel-chan-in) | ||
[x y] (<! pos-chan) | ||
[xn yn] [(+ x (* vel-x tick)) (+ y (* vel-y tick))]] | ||
(>! vel-chan-out | ||
(cond | ||
(< xn 0) [(- vel-x) vel-y] | ||
(< yn 0) [vel-x (- vel-y)] | ||
(> xn width) [(- vel-x) vel-y] | ||
(> yn height) [vel-x (- vel-y)] | ||
:else [vel-x vel-y]))))) | ||
|
||
(defn ^:export init [] | ||
(let [mm-chan (event-chan :mousemove)] | ||
(go | ||
(while true | ||
(let [e (<! mm-chan)] | ||
(.log js/console (str (:clientX e) " , " (:clientY e)))))))) | ||
(let [frame-chan (h/frame-chan) | ||
[frame-chan1 frame-chan2] (h/dup-chan frame-chan) | ||
|
||
fps-chan (h/map-chan #(/ 1000 %) (h/diff-chan frame-chan2)) | ||
|
||
width 100 | ||
height 100 | ||
init-pos [0 50] | ||
init-vel [0.05 0.05] | ||
|
||
[tick-chan-pos tick-chan-collsion] (h/dup-chan (h/diff-chan frame-chan1)) | ||
|
||
pos-chan (chan) | ||
[pos-chan-pos pos-chan-render pos-chan-collision] (h/multiplex pos-chan 3) | ||
|
||
vel-chan (chan) | ||
[vel-chan-pos vel-chan-collision] (h/dup-chan vel-chan)] | ||
(positioner tick-chan-pos vel-chan-pos pos-chan-pos pos-chan) | ||
(collision-detector width height tick-chan-collsion pos-chan-collision vel-chan-collision vel-chan) | ||
|
||
(go (>! pos-chan init-pos)) | ||
(go (>! vel-chan init-vel)) | ||
|
||
(go-loop | ||
(let [[x y] (map int (<! pos-chan-render))] | ||
(dom/set-text! (dom/by-id "fps") (<! fps-chan)) | ||
(dom/set-text! (dom/by-id "pos") [x y]) | ||
(dom/set-style! (dom/by-id "ball") "left" (str (+ 50 x) "px")) | ||
(dom/set-style! (dom/by-id "ball") "top" (str (+ 50 y) "px")))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
(ns frpong.helpers | ||
(:require [cljs.core.async :as async | ||
:refer [<! >! chan put! close! sliding-buffer dropping-buffer timeout]] | ||
[domina :as dom :refer [log]] | ||
[domina.events :as ev]) | ||
(:require-macros [cljs.core.async.macros :as m :refer [go]] | ||
[frpong.core :refer (go-loop)])) | ||
|
||
(defn now [] | ||
(.valueOf (js/Date.))) | ||
|
||
(defn put-all! [cs x] | ||
(doseq [c cs] | ||
(put! c x))) | ||
|
||
(defn cconj [v c1] | ||
(let [c2 (chan)] | ||
(go | ||
(>! c2 v) | ||
(while true | ||
(>! c2 (<! c1)))) | ||
c2)) | ||
|
||
(defn multiplex [in cs-or-n] | ||
(let [cs (if (number? cs-or-n) | ||
(repeatedly cs-or-n chan) | ||
cs-or-n)] | ||
(go (loop [] | ||
(let [x (<! in)] | ||
(if-not (nil? x) | ||
(do | ||
(put-all! cs x) | ||
(recur)) | ||
:done)))) | ||
cs)) | ||
|
||
(defn copy-chan | ||
([c] | ||
(first (multiplex c 1))) | ||
([out c] | ||
(first (multiplex c [out])))) | ||
|
||
(defn dup-chan [c] | ||
(multiplex c 2)) | ||
|
||
(defn map-chan | ||
([f source] (map-chan (chan) f source)) | ||
([c f source] | ||
(go-loop | ||
(>! c (f (<! source)))) | ||
c)) | ||
|
||
(defn filter-chan | ||
([f source] (filter-chan (chan) f source)) | ||
([c f source] | ||
(go-loop | ||
(let [v (<! source)] | ||
(when (f v) | ||
(>! c v)))) | ||
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)) | ||
(<! (timeout msecs))) | ||
:falling (go-loop | ||
(<! (timeout msecs)) | ||
(>! c (now)))) | ||
c)) | ||
|
||
(defn throttle | ||
([source control] | ||
(throttle (chan) source control)) | ||
([c source control] | ||
(go | ||
(loop [state ::init last nil cs [source]] | ||
(let [[_ sync] cs] | ||
(let [[v sc] (alts! cs)] | ||
(condp = sc | ||
source (condp = state | ||
::init (do (>! c v) | ||
(recur ::throttling last | ||
(conj cs control))) | ||
::throttling (recur state v cs)) | ||
sync (if last | ||
(do (>! c last) | ||
(recur state nil | ||
(conj (pop cs) control))) | ||
(recur ::init last (pop cs)))))))) | ||
c)) | ||
|
||
(defn debounce | ||
([source msecs] | ||
(debounce (chan) source msecs)) | ||
([c source msecs] | ||
(go | ||
(loop [state ::init cs [source]] | ||
(let [[_ threshold] cs] | ||
(let [[v sc] (alts! cs)] | ||
(condp = sc | ||
source (condp = state | ||
::init | ||
(do (>! c v) | ||
(recur ::debouncing | ||
(conj cs (timeout msecs)))) | ||
::debouncing | ||
(recur state | ||
(conj (pop cs) (timeout msecs)))) | ||
threshold (recur ::init (pop cs))))))) | ||
c)) | ||
|
||
(defn after-last | ||
([source msecs] | ||
(after-last (chan) source msecs)) | ||
([c source msecs] | ||
(go | ||
(loop [cs [source]] | ||
(let [[_ toc] cs] | ||
(let [[v sc] (alts! cs :priority true)] | ||
(recur | ||
(condp = sc | ||
source (conj (if toc (pop cs) cs) | ||
(timeout msecs)) | ||
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)))) | ||
c)) | ||
|
||
(defn distinct-chan | ||
([source] (distinct-chan (chan) source)) | ||
([c source] | ||
(go | ||
(loop [last ::init] | ||
(let [v (<! source)] | ||
(when-not (= last v) | ||
(>! c v)) | ||
(recur v)))) | ||
c)) | ||
|
||
(defn event-chan [event-type] | ||
(let [c (chan)] | ||
(ev/listen! js/document event-type #(put! c %)) | ||
c)) | ||
|
||
(defn frame-chan [] | ||
(let [c (chan (sliding-buffer 1000)) | ||
step (fn step [ts] (do (put! c ts) (.requestAnimationFrame js/window step)))] | ||
(.requestAnimationFrame js/window step) | ||
c)) | ||
|
||
(defn counting-chan [source] | ||
(let [c (chan)] | ||
(go | ||
(loop [count 0] | ||
(<! source) | ||
(>! c count) | ||
(recur (inc count)))) | ||
c)) | ||
|
||
(defn diff-chan [source] | ||
(let [c (chan)] | ||
(go | ||
(let [start (<! source)] | ||
(loop [start start] | ||
(let [ts (<! source)] | ||
(>! c (- ts start)) | ||
(recur ts))))) | ||
c)) |