Got positioner and collision-detector working
This commit is contained in:
parent
07c53dcf2b
commit
00c46a5ee7
@ -7,7 +7,7 @@
|
||||
:source-paths ["src/clj"]
|
||||
:dependencies [[org.clojure/clojure "1.5.1"]
|
||||
[domina "1.0.2-SNAPSHOT"]
|
||||
[org.clojure/clojurescript "0.0-1878"]
|
||||
[org.clojure/clojurescript "0.0-1844"]
|
||||
[org.clojure/core.async "0.1.222.0-83d0c2-alpha"]]
|
||||
|
||||
:plugins [[lein-cljsbuild "0.3.3"]]
|
||||
|
@ -8,6 +8,9 @@
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<div>FPS: <span id="fps"></span></div>
|
||||
<div>Position: <span id="pos"></span></div>
|
||||
<div style="position: absolute" id="ball">O</div>
|
||||
<!-- pointing to cljsbuild generated js file -->
|
||||
<script src="js/frpong.js"></script>
|
||||
<script type="text/javascript">frpong.core.init()</script>
|
||||
|
@ -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)))
|
||||
|
@ -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"))))))
|
||||
|
180
src/cljs/frpong/helpers.cljs
Normal file
180
src/cljs/frpong/helpers.cljs
Normal file
@ -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))
|
Loading…
Reference in New Issue
Block a user