Creative-Coding

/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

/img/colorful-coding_proyecto-2-card.png
Colorful Coding, Proyecto 2, Spirograph

Resultado Código (def r1 (volatile! (+ 100 (rand-int 50))) ) (def r2 (volatile! (+ 100 (rand-int 50)))) (def a1 (volatile! 0)) (def a2 (volatile! 0)) (def prevX (volatile! nil)) (def prevY (volatile! nil)) (def a1Inc (volatile! nil)) (def a2Inc (volatile! nil)) (def speed (volatile! 50)) (defn setup [] (vreset! a1Inc (js/random 0.1 5)) (vreset! a2Inc (js/random 0.1 5)) (let [canvas (js/createCanvas 800 800)] (.parent canvas "p5jsparent") (js/angleMode js/DEGREES) (js/background 30))) (defn draw [] (js/translate (/ js/width 2) (/ js/height 2)) (doseq [_ (range @speed)] (let [x1 (* @r1 (js/cos @a1)) y1 (* @r1 (js/sin @a1)) x2 (+ x1 (* @r2 (js/cos @a2))) y2 (+ y1 (* @r2 (js/sin @a2))) r (js/map (js/sin js/frameCount) -1 1 100 200) g (js/map (js/sin js/frameCount) -1 1 100 200) b (js/map (js/sin js/frameCount) -1 1 200 100)] (js/stroke r g b)Giro (y ) usando seno y coseno de ;; Si no compruebo el valor nil/no nil, me aparece ralla desde 0 ;; hasta el primer punto calculado. (when-not (nil? @prevX) (js/line @prevX @prevY x2 y2)) (vreset! prevX x2) (vreset! prevY y2) (vreset! a1 (+ @a1 @a1Inc)) (vreset! a2 (+ @a2 @a2Inc))) )) Otros estados chulos #js {:speed 50 :r1 121, :r2 136, :a1 0, :a2 0, :prevX nil, :prevY nil, :a1Inc 0.7508956561156331, :a2Inc 3.8642557890718057} #js {:a2 0, :a1Inc 4.275794517513079, :speed 50, :a1 0, :r2 136, :a2Inc 1.0797030798400762, :r1 109, :prevY nil, :prevX nil} #js {:a2 0, :a1Inc 1.2013414944503171, :speed 50, :a1 0, :r2 103, :a2Inc 3.7605190603179026, :r1 141, :prevY nil, :prevX nil} 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