summary refs log tree commit diff
path: root/lib/game.fnl
diff options
context:
space:
mode:
authorequa <equaa@protonmail.com>2021-04-18 09:57:30 -0500
committerequa <equaa@protonmail.com>2021-04-18 09:57:30 -0500
commit0c8a8cf8d861bc4ef3162e45e8b58d2f0173d2f7 (patch)
tree5fe4e826b92173f33abf8a1f2391ccab706db230 /lib/game.fnl
nanpa wan
commit of the last two days: working cellular automata and rendering,
prototype system, etc
Diffstat (limited to 'lib/game.fnl')
-rw-r--r--lib/game.fnl109
1 files changed, 109 insertions, 0 deletions
diff --git a/lib/game.fnl b/lib/game.fnl
new file mode 100644
index 0000000..da96d9f
--- /dev/null
+++ b/lib/game.fnl
@@ -0,0 +1,109 @@
+(local state (require :lib.state))
+(local cell (require :lib.cell))
+(local cells (require :lib.cells))
+(local fv (require :fennel.view))
+
+(fn lerp* [a b c d x]
+  (+ c (* (/ (- x a) (- b a)) (- d c))))
+
+(fn vec-lerp* [a b c d x]
+  {:x (lerp* a.x b.x c.x d.x x.x)
+    :y (lerp* a.y b.y c.y d.y x.y)})
+
+(fn new-grid [w h f]
+  (var t {})
+  (for [x 0 (- w 1)]
+    (tset t x {})
+    (for [y 0 (- h 1)]
+      (tset (. t x) y (f x y))))
+  t)
+
+(fn update [self]
+  (set self.ship.x (+ self.ship.x 0.02))
+  (set self.ship.y (+ self.ship.y 0.005))
+  (when (= self.tick 0)
+    (for [x 0 (- self.width 1)]
+      (for [y 0 (- self.height 1)]
+        (fn get [v]
+          (. self.grid
+             (% (+ v.x x) self.width)
+             (% (+ v.y y) self.height)))
+        (if (. self.grid x y)
+            ;; check if alive
+            (tset self.grid-alt x y (cell.update (. self.grid x y)
+                                                 get))
+            ;; check for neighbors and then use one at random
+            (do
+              (var neighbors [])
+              (for [x -1 1]
+                (for [y -1 1]
+                  (table.insert neighbors (get {: x : y}))))
+              (if (. neighbors 1)
+                  (tset self.grid-alt x y
+                        (cell.birth (. neighbors (math.random (length neighbors))) get))
+                  (tset self.grid-alt x y nil))))))
+    (set (self.grid self.grid-alt) (values self.grid-alt self.grid)))
+    ;; TODO
+  (set self.tick (% (+ self.tick 1) self.rate)))
+
+(fn id [x] x)
+
+(fn draw [self]
+  (local (width height) (love.graphics.getDimensions))
+  (love.graphics.scale width height)
+  (local camera-size (math.max width height))
+  (let [camera-size (math.max width height)
+        camera-box {:x width :y height}
+        camera-box {:x 1 :y 1}
+        radius-x (* self.radius (/ width camera-size))
+        radius-y (* self.radius (/ height camera-size))
+        camera-a {:x (- self.ship.x radius-x)
+                  :y (- self.ship.y radius-y)}
+        camera-b {:x (+ self.ship.x radius-x)
+                  :y (+ self.ship.y radius-y)}
+        cell-box (vec-lerp* {:x 0 :y 0}
+                            {:x (* 2 radius-x)
+                             :y (* 2 radius-y)}
+                            {:x 0 :y 0}
+                            camera-box
+                            {:x 1 :y 1})]
+    (for [x (math.floor camera-a.x) (math.floor camera-b.x)]
+      (for [y (math.floor camera-a.y) (math.floor camera-b.y)]
+        (let [vec {:x (% x self.width) :y (% y self.height)}
+              render-a (vec-lerp* camera-a camera-b {:x 0 :y 0} camera-box
+                                  {: x : y})
+              render-b (vec-lerp* camera-a camera-b {:x 0 :y 0} camera-box
+                                  {:x (+ x 1) :y (+ y 1)})
+              the (. self.grid vec.x vec.y)
+              color (and the (cell.color the))]
+          (when color
+            (love.graphics.setColor (unpack color))
+            (love.graphics.rectangle :fill
+                                     (id render-a.x)
+                                     (id render-a.y)
+                                     (id cell-box.x)
+                                     (id cell-box.y))))))))
+    ;; (love.graphics.setLineWidth 0.1)
+    ;; (love.graphics.line 0 0 0.3 0.3)
+    ;; (love.graphics.polygon :line 0.3 0.3 0.6 0.3 0.4 0.6)
+    ;; (love.graphics.line 0.4 0.8 0.4 0.8)
+    ;; (love.graphics.print :Gaming))
+
+(fn init [self]
+  (setmetatable
+    {:width 64
+     :height 64
+     :ship {:x 31 :y 31}
+     :radius 32
+     :tick 0
+     :rate 6
+     :grid (new-grid 64 64 #(if (= (math.random 6) 1)
+                                (if (< $1 52)
+                                    (cell.init cells.life)
+                                    (cell.init cells.brain))
+                                nil))
+     :grid-alt (new-grid 64 64 #nil)
+     }
+    self))
+
+{state.draw draw state.init init state.update update}