Coding-Train

/img/coding-train_coding-challenge-103-card.png
Coding Train, Challenge 103, Fire Effect

Resultado Código (def w 300) (def h 200) (def buffer1 (volatile! nil)) (def buffer2 (volatile! nil)) (def cooling (volatile! nil)) (def y-start (volatile! 0.0)) (defn mouse-pressed [] (.fill @buffer1 255) (.noStroke @buffer1) (.ellipse @buffer1 js/mouseX js/mouseY 100 100)) (defn setup [] (js/pixelDensity 1) (let [canvas (js/createCanvas (* 2 w) h)] (.parent canvas "p5jsparent") (js/loadPixels)) (vreset! buffer1 (js/createGraphics w h)) (vreset! buffer2 (js/createGraphics w h)) (vreset! cooling (js/createImage w h))) (defn cool [] (.loadPixels @cooling) (let [increment 0.02] (doseq [x (range w) y (range h)] (let [xoff (* (inc x) increment) yoff (+ @y-start (* (inc y) increment)) n (js/noise xoff yoff) bright (* (js/pow n 3) 255) index (* 4 (+ x (* y w)))] (aset (.-pixels @cooling) (+ index 0) bright) (aset (.-pixels @cooling) (+ index 1) bright) (aset (.-pixels @cooling) (+ index 2) bright) (aset (.-pixels @cooling) (+ index 3) 255))) (.updatePixels @cooling) (vswap! y-start (fn [v] (+ v increment))))) (defn fire [rows] (.loadPixels @buffer1) (doseq [x (range w) j (range rows)] (let [y (- h (inc j)) index (* 4 (+ x (* y w)))] (aset (.-pixels @buffer1) (+ index 0) 255) (aset (.-pixels @buffer1) (+ index 1) 255) (aset (.-pixels @buffer1) (+ index 2) 255) (aset (.-pixels @buffer1) (+ index 3) 255) )) (.updatePixels @buffer1)) (defn draw [] (fire 2) (when js/mouseIsPressed (.fill @buffer1 255) (.noStroke @buffer1) (.ellipse @buffer1 js/mouseX js/mouseY 100 100)) (cool) (js/background 0) (.loadPixels @buffer1) (.loadPixels @buffer2) (doseq [x (range 1 (dec w)) y (range 1 (dec h))] (let [yw (* y w) index0 (* 4 (+ x yw)) index1 (* 4 (+ (inc x) yw)) index2 (* 4 (+ (dec x) yw)) index3 (* 4 (+ x (* (inc y) w))) index4 (* 4 (+ x (* (dec y) w))) c1 (aget (.-pixels @buffer1) index1) c2 (aget (.-pixels @buffer1) index2) c3 (aget (.-pixels @buffer1) index3) c4 (aget (.-pixels @buffer1) index4) c5 (aget (.-pixels @cooling) index0) new-c (- (* 0.25 (+ c1 c2 c3 c4)) c5)] (aset (.-pixels @buffer2) (+ index4 0) new-c) (aset (.-pixels @buffer2) (+ index4 1) new-c) (aset (.-pixels @buffer2) (+ index4 2) new-c) (aset (.-pixels @buffer2) (+ index4 3) 255) )) (.updatePixels @buffer2) (let [tmp @buffer1] (vreset! buffer1 @buffer2) (vreset! buffer2 tmp)) (js/image @buffer2 0 0) (js/image @cooling w 0)) Enlaces Starlight Challenge p5.js The Coding Train Challenges Libro The Nature Of Code ClojureScript Studio Editor de p5js con ClojureScript Eric Norman sobre concurrencia en Clojure

/img/coding-train_coding-challenge-180-card.png
Coding Train, Challenge 180, Falling Sand

Resultado Código ;; 180 - Falling Sand (ns challenges.challenge-180-falling-sand (:require [p5])) ;; Definición de variables ;; (def state {:sizes {:w js/window.innerWidth :h js/window.innerHeight}}) (def state {:sizes {:w 800 :h 1400}}) (def width (-> state :sizes :w)) (def height (-> state :sizes :h)) (def w 5) ;; tamaño de cada celda; (def cols (/ width w)) (def rows (/ height w)) (def rcols (range cols)) (def rrows (range rows)) (def grid (volatile! #js [])) (def matrix 6) (def hue-value (volatile! 50)) (defn make-2darray "Creación de matriz con función opcional para rellenarla. Se le pasan dimensiones (`nrows` y `ncols`) y opcionalmente un callback para calcular el valor de sus elementos a partir del índice de cada uno de ellos `(fn [col_idx row_idx))`. Si no pasamos función, el fallback es rellenar con ceros." [ncols nrows & {:keys [f] :or {f (constantly 0)}}] #_(vec (repeat nrows (vec (repeat ncols 0)))) (mapv (fn [i] (mapv #(f i %) (range nrows))) (range ncols))) (defn make-flat-2darray [ncols nrows] (vec (repeat (* nrows ncols) 0))) (defn setup [] (let [canvas (js/createCanvas width height)] (.parent canvas "p5jsparent") (js/loadPixels)) (js/colorMode js/HSB 360 255 255) (let [arr (make-2darray cols rows)] (println (count arr) (count (first arr)))) (vreset! grid (clj->js (make-2darray cols rows)))) (defn mouse-pressed [] (let [[mouse-col mouse-row] [(Math/floor (/ js/mouseX w)) (Math/floor (/ js/mouseY w))] extent (Math/floor (/ matrix 2))] ;; Pintamos de forma aletoria nuevos granos de arena alrededor del punto donde clicamos. (doseq [i (range (- extent) (inc extent)) j (range (- extent) (inc extent))] (when (zero? (rand-int 2)) (let [col (+ mouse-col i) row (+ mouse-row j)] (when (and (> col -1) (< col cols) (> row 1) (< row rows)) (aset @grid col row @hue-value))))) (vreset! hue-value (+ 5 @hue-value)) (when (> @hue-value 359) (vreset! hue-value 1)))) (comment (range 0 100 5) ) (defn draw [] (js/background 0) (js/noStroke) (doseq [i (range cols) j (range rows)] ;; (js/stroke 255) ;; Podríamos ahorranos esto si el valor del grid base fuese negro en el ;; espacio de color que estamos usando. Pero no tiene mayor importancia ;; y lo simplifica mucho. (when (> (aget @grid i j) 0) (js/fill (aget @grid i j) 255 255) (js/square (* i w) (* j w) w))) ;; Para calcular el movimiento, volvemos a repasar el grid, y ;; si teníamos en una celda un 1, en este nuevo grid el 1 se ;; habrá movido hacia abajo. (let [next-grid (clj->js (make-2darray cols rows))] (doseq [i rcols j rrows] (let [state (aget @grid i j)] (when (> state 0) (let [below (aget @grid i (inc j)) dir (if (zero? (rand-int 2)) 1 -1) next-i (+ i dir) prev-i (- i dir) next-j (inc j)] (cond (zero? below) (aset next-grid i next-j state) ;; Comprobamos posición bajo derecha. (and (pos? next-i) (< next-i cols) (zero? (aget @grid next-i next-j))) (aset next-grid next-i next-j state) ;; Comprobamos posición bajo izquierda. (and (pos? prev-i) (< prev-i cols) (zero? (aget @grid prev-i next-j))) (aset next-grid prev-i next-j state) :else (aset next-grid i j state)))))) (vreset! grid next-grid))) Enlaces Starlight Challenge p5.js The Coding Train Challenges Libro The Nature Of Code ClojureScript Studio Editor de p5js con ClojureScript Eric Norman sobre concurrencia en Clojure