summary refs log tree commit diff
path: root/lib/game.fnl
blob: da96d9f46bc7a34b6b39858d56dd2901090d03e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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}