(ns frpong.core (: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]] [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 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]) (>! 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 [pos (! pos-out (condp = (! ticks (