Commits

Steve Losh  committed 341098f

Collision detection for buildings.

  • Participants
  • Parent commits bd8d3a1

Comments (0)

Files changed (3)

File src/ruin/core.clj

 (ns ruin.core
   (:use [ruin.state :only [game]]
-        [ruin.entities :only [make-person]]
+        [ruin.entities :only [make-person start-person]]
         [ruin.buildings :only [make-house make-silo make-farm]]
         [ruin.ui :only [->UI]]
         [ruin.drawing :only [draw-ui]]
   (:require [lanterna.screen :as s]))
 
 
+(defn entities-at [coord]
+  (filter #(= coord (:location @%))
+          (vals @(:entities @game))))
+
+(defn buildings-collide? [a b]
+  (let [[ax ay] (:location a)
+        [bx by] (:location b)
+        [aw ah] (:size a)
+        [bw bh] (:size b)
+        ax' (+ ax aw)
+        ay' (+ ay ah)
+        bx' (+ bx bw)
+        by' (+ by bh)]
+    (not (or (< ay' by)
+             (> ay by')
+             (< ax' bx)
+             (> ax bx')))))
+
+
+(defn add-building [f]
+  (let [existing (vals @(:buildings @game))
+        building (f)]
+    (if (some #(buildings-collide? @building @%)
+              existing)
+      (recur f)
+      (dosync
+        (alter (:buildings @game) assoc (:id @building) building)))))
+
 (defn calc-score []
   (letfn [(count-things [source kind]
             (count (filter #(= kind (:type @%))
 
 
 (defn create-initial-population []
-  (into {}
-        (gen-things 10 make-person)))
+  (let [population (into {}
+                         (gen-things 10 make-person))]
+    (dorun (map start-person (vals population)))
+    population))
 
 (defn create-initial-buildings []
-  (into {}
-        (concat (gen-things 4 make-house)
-                (gen-things 1 make-farm)
-                (gen-things 2 #(make-silo 25)))))
+  (dorun (repeatedly 4 #(add-building make-house)))
+  (dorun (repeatedly 2 #(add-building (partial make-silo 25))))
+  (dorun (repeatedly 1 #(add-building make-farm))))
 
 
 (defn create-fresh-game
                                     :font-size 16})]
       (ref-set game {:screen scr
                      :entities (ref (create-initial-population))
-                     :buildings (ref (create-initial-buildings))
+                     :buildings (ref {})
                      :resources (ref 20)
                      :viewport-origin [0 0]
                      :score (ref [0 0])
                      :state :running
                      :uis [(->UI :start)]})
+      (create-initial-buildings)
       (s/start scr))))
 
 
   "Continually draw all the game's UIs, until the game stops running."
   []
   (draw-uis)
-  (Thread/sleep 300)
+  (Thread/sleep 100)
   (when (:state @game)
     (recur)))
 

File src/ruin/drawing.clj

         [cols rows] (s/get-size screen)
         map-height rows
         map-width (- cols (inc SIDEBAR-WIDTH))
+        row (apply str (repeat map-width \.))
         ]
     (s/put-sheet screen 0 0
-                 (repeat map-height (repeat map-width \.)))))
+                 (repeat map-height row))))
 
 (defn clear-sidebar []
   (let [game @game

File src/ruin/entities.clj

-(ns ruin.entities)
+(ns ruin.entities
+  (:use [ruin.state :only [game]]
+        [ruin.util :only [dir-to-offset]]))
 
 
 (defonce eid (atom 1))
           :happiness 50}))
 
 
+(defn walk-random [person]
+  (let [dir (rand-nth [:n :s :e :w :ne :nw :se :sw])
+        offset (dir-to-offset dir)
+        new-location (map + offset (:location person))]
+    (assoc person :location new-location)))
+
+(defn tick-person [person tick]
+  (dosync
+    (when (:state @game)
+      (send-off *agent* #'tick-person (inc tick)))
+    (Thread/sleep 1000)
+    (if (< (rand) 0.5)
+      (walk-random person)
+      person)))
+
+
 (defn start-person [p]
-  nil)
+  (send-off p tick-person 0))