(ns frpong.core (:require [frpong.helpers :as h] [cljs.core.async :refer [! chan put!]] [domina :as dom :refer [log]]) (:require-macros [cljs.core.async.macros :as m :refer [go]] [frpong.core :refer (go-loop)])) ;; ;; Signal Diagram ;; ;; +---------------------+ ;; | +-------------+ | ;; | | | | ;; v v | | ;; +----------+ vel-chan | | ;; +-->|c-detector+----------+ | ;; | +----------+ | | ;; | +-----------------+ | ;; | | +-----------------+ ;; | | | | ;; | v v | ;; +---------+ frame-chan +------+ tick-chan | +----------+ pos-chan | ;; |frame-gen+------------>|ticker+-----------+-->|positioner+--------------+ ;; +---------+ +------+ +----------+ | ;; +---------------------+ ;; | ;; v ;; +----------+ ;; | renderer | ;; +----------+ (defn abs [x] (.abs js/Math x)) (defn tick-chan [frames] (let [c (chan)] (go (loop [prev (! c t)) (recur t)))) c)) (defn ball-positioner [ticks vel pos-in pos-out] (go-loop (let [tick (! pos-out pos-next)))) (defn paddle-positioner [keycodes max-y movement pos-in pos-out] (let [keys (h/key-chan keycodes)] (go-loop (let [pos (! pos-out (condp = ( y (+ p-pos padding)) (< y (- (+ p-pos paddle-size) padding)))) detect-x-collision (fn [x y pl-pos pr-pos] (cond (< x ef-paddle-width) (if (in-y-range? y pl-pos) :collision-left :gameover) (> x (- width ef-paddle-width)) (if (in-y-range? y pr-pos) :collision-right :gameover) :else :moving)) detect-y-collision (fn [y] (cond (< y padding) :collision-left (> y (- height padding)) :collision-right :else :moving))] (go-loop (let [tick (! vel-out [vel-xn vel-yn]) (>! 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 renderer [game-state pos pl-pos pr-pos] (let [ball-el (dom/by-id "ball") state-el (dom/by-id "state") lpaddle-el (dom/by-id "lpaddle") rpaddle-el (dom/by-id "rpaddle")] (go-loop (let [[x y] (! ticks (