From 00af64d4e503dd82abf4657ec6fd44b0a418adb2 Mon Sep 17 00:00:00 2001 From: equa Date: Mon, 19 Apr 2021 20:39:21 -0500 Subject: cool bullets --- lib/bullet.fnl | 25 +++++++++++++++++++++++++ lib/cells.fnl | 20 ++++++++++++++------ lib/entity.fnl | 1 + lib/game.fnl | 18 +++++++++++++----- lib/main.fnl | 1 + lib/player.fnl | 16 +++++++++++++++- lib/vec.fnl | 8 +++++++- 7 files changed, 76 insertions(+), 13 deletions(-) create mode 100644 lib/bullet.fnl diff --git a/lib/bullet.fnl b/lib/bullet.fnl new file mode 100644 index 0000000..d7f1b62 --- /dev/null +++ b/lib/bullet.fnl @@ -0,0 +1,25 @@ +(local entity (require :lib.entity)) +(local vec (require :lib.vec)) +(local cell (require :lib.cell)) +(local cells (require :lib.cells)) + +(fn init [self pos vel] + (setmetatable {entity.position pos + entity.velocity vel + entity.duration 120} + self)) + +(fn draw [self game id] + (love.graphics.setColor 1 1 1 (/ (entity.duration self) 120)) + (love.graphics.setLineWidth 0.3) + (love.graphics.line 0 0 + (. self entity.velocity :x) + (. self entity.velocity :y))) + +(fn collide [self game id x y] + (when (> (cell.aliveness (. game.grid x y)) 0) + (tset game.entities id nil) + ;; TODO: less boom-y thing? + (tset game.grid x y (cell.init cells.boom (/ (entity.duration self) 180))))) + +{entity.init init entity.draw draw entity.collide collide} diff --git a/lib/cells.fnl b/lib/cells.fnl index 3a43010..e415f21 100644 --- a/lib/cells.fnl +++ b/lib/cells.fnl @@ -17,18 +17,26 @@ (set x (+ x 1)))) x) +(fn neighbors< [f threshold] + (var x 0) + ;; nnn this could be faster maybe + (for [k 1 8] + (when (< (cell.aliveness (f (. neighbors k))) threshold) + (set x (+ x 1)))) + x) + (local life {cell.init (fn [self] (setmetatable {} self)) cell.birth (fn [self get] - (if (= (neighbors> get 0) 3) + (if (= (neighbors> get 0.5) 3) self nil)) cell.update (fn [self get] - (let [n (neighbors> get 0)] + (let [n (neighbors> get 0.5)] (if (or (= n 3) (= n 2)) self @@ -65,12 +73,12 @@ (local boom {cell.init - (fn [self] - (setmetatable {:life 1} self)) + (fn [self x] + (setmetatable {:life (or x 1)} self)) cell.birth (fn [self get] (if (and (> self.life 0.08) - (> (neighbors> get (* (if (> self.life 0.9) 0.3 0.1) (math.random 7))) 0)) + (> (neighbors< get (* (if (> self.life 0.9) -0.3 -0.1) (math.random 7))) 0)) (do (setmetatable {:life (* self.life 0.8)} (getmetatable self))) nil)) @@ -80,7 +88,7 @@ (setmetatable {:life (* self.life (+ 0.5 (* (math.random 5) 0.1)))} (getmetatable self)) nil)) cell.aliveness - #$.life + #(- $.life) cell.color #[(+ 0.4 (* 0.6 $.life)) (math.max 0 (- 0.8 (* 0.9 (- 1 $.life)))) diff --git a/lib/entity.fnl b/lib/entity.fnl index 2032e65..6771b5e 100644 --- a/lib/entity.fnl +++ b/lib/entity.fnl @@ -3,6 +3,7 @@ {:init (proto.table-method :entity.init) :position (proto.table-value :entity.position) :velocity (proto.table-value :entity.velocity) + :duration (proto.table-value :entity.duration) ;; [self game {: up : down : left : right}] :steer (proto.meta-method :entity.velocity) ;; [self game] diff --git a/lib/game.fnl b/lib/game.fnl index b75a254..3f99550 100644 --- a/lib/game.fnl +++ b/lib/game.fnl @@ -51,7 +51,9 @@ :player {:up (love.keyboard.isDown :up) :right (love.keyboard.isDown :right) - :left (love.keyboard.isDown :left)})) + :left (love.keyboard.isDown :left) + :shoot (love.keyboard.isDown :z) + })) ;; entities (each [id e (pairs self.entities)] (tset e entity.position (vec.wrap @@ -62,7 +64,10 @@ t (. self.grid x y)] (when t (entity.collide e self id x y))) - ) + (when (entity.duration e) + (tset e entity.duration (- (entity.duration e) 1)) + (if (= (entity.duration e) 0) + (tset self.entities id nil)))) ) (fn id [x] x) @@ -128,7 +133,10 @@ (each [id v (pairs self.entities)] (love.graphics.push) (let [pos (entity.position v) - render-pos (vec.lerp camera-a camera-b display-a display-b pos)] + render-pos (vec.lerp camera-a camera-b display-a display-b + (vec.add camera-a + (vec.wrap (vec.sub pos camera-a) + (vec.sub camera-b camera-a))))] (love.graphics.translate render-pos.x render-pos.y) (love.graphics.scale cell-box.x cell-box.y)) @@ -172,9 +180,9 @@ :rate 6 :entities {:player (entity.init player {:x 32 :y 32})} :grid (new-grid width height #(if (= (math.random 6) 1) - (if (> $1 34) + (if (> $1 44) (cell.init cells.life) - (< $1 00) + (< $1 10) (cell.init cells.brain) nil) nil)) diff --git a/lib/main.fnl b/lib/main.fnl index 8e4908a..71319b8 100644 --- a/lib/main.fnl +++ b/lib/main.fnl @@ -11,6 +11,7 @@ ;; TODO: ^ (local hotswap-modules [:lib.player + :lib.bullet :lib.cells :lib.game :lib.main]) diff --git a/lib/player.fnl b/lib/player.fnl index 0633727..8e31a18 100644 --- a/lib/player.fnl +++ b/lib/player.fnl @@ -2,15 +2,19 @@ (local vec (require :lib.vec)) (local cell (require :lib.cell)) (local cells (require :lib.cells)) +(local bullet (require :lib.bullet)) (fn init [self pos] (setmetatable {entity.position pos entity.velocity {:x 0 :y 0} :target-spin 0 + :shot-age 0 :direction 0} self)) (fn steer [self game id controls] + (when (> self.shot-age 0) + (set self.shot-age (- self.shot-age 1))) ;; TODO: smooth turning (when controls.left (set self.target-spin (- self.target-spin 0.15))) @@ -24,7 +28,17 @@ (set v.x (+ v.x (* (math.cos self.direction) 0.02))) (set v.y (+ v.y (* (math.sin self.direction) 0.02))) (when (> (vec.mag v) 0.8) - (tset self entity.velocity (vec.mul v (/ 0.8 (vec.mag v))))))) + (tset self entity.velocity (vec.mul v (/ 0.8 (vec.mag v)))))) + (when (and controls.shoot (= self.shot-age 0)) + (set self.shot-age 10) + (local v (entity.velocity self)) + (table.insert + game.entities + (entity.init + bullet + (vec.clone (entity.position self)) + {:x (+ (* (math.cos self.direction) 0.6)) + :y (+ (* (math.sin self.direction) 0.6))})))) (fn draw [self game id] (love.graphics.setColor 1 1 1) diff --git a/lib/vec.fnl b/lib/vec.fnl index cce9627..943c7dc 100644 --- a/lib/vec.fnl +++ b/lib/vec.fnl @@ -16,6 +16,9 @@ (fn mag [v] (math.sqrt (+ (* v.x v.x) (* v.y v.y)))) +(fn norm [v n] + (mul v (/ (or n 1) (mag v)))) + (fn wrap [a b] {:x (% a.x b.x) :y (% a.y b.y)}) @@ -24,4 +27,7 @@ {:x (ilerp* a.x b.x c.x d.x x.x) :y (ilerp* a.y b.y c.y d.y x.y)}) -{: lerp : add : sub : mul : mag : wrap} +(fn clone [v] + {:x v.x :y v.y}) + +{: lerp : add : sub : mul : mag : wrap : norm : clone} -- cgit 1.3.0-6-gf8a5