Fully pivot to pirates, some UI
This commit is contained in:
83
src/age_of_sail/core.clj
Normal file
83
src/age_of_sail/core.clj
Normal file
@@ -0,0 +1,83 @@
|
||||
(ns age-of-sail.core
|
||||
(:require [age-of-sail.vec2 :refer :all]
|
||||
[seesaw.core :refer :all]
|
||||
[seesaw.bind :as b]
|
||||
[clojure.math :as math]))
|
||||
|
||||
(def tickrate 100)
|
||||
(def hardcoded-wind [0.1 3.0]) ;; A strong easternly wind!
|
||||
(defonce ships (atom []))
|
||||
(defonce program (atom nil))
|
||||
|
||||
(defn find-ship
|
||||
[ships name]
|
||||
(some #(when (= name (:name @%)) %) ships))
|
||||
|
||||
(defn downwind-force
|
||||
"Calculates the force for a single square downwind sail
|
||||
Force = furl × length² × dot(wind, heading)"
|
||||
[sail wind heading]
|
||||
(scale heading (* (:furl sail) (:length sail) (:length sail) (dot wind heading))))
|
||||
|
||||
(defn downwind-sails-force
|
||||
[ship wind]
|
||||
(loop [slots (:slots ship)
|
||||
force (zero)]
|
||||
(if-let [slot (first slots)]
|
||||
(if (= :downwind-sail (:type slot))
|
||||
(recur (rest slots) (add force (downwind-force slot wind (:heading ship))))
|
||||
(recur (rest slots) force))
|
||||
force)))
|
||||
|
||||
(defn physics-step
|
||||
[ship wind]
|
||||
(dosync
|
||||
;; Update position
|
||||
(alter ship update :position add (scale (:velocity @ship) (/ tickrate)))
|
||||
;; linear dampening
|
||||
(alter ship update :velocity scale (- 1.0 (/ 0.5 tickrate)))
|
||||
;; wind force
|
||||
(alter ship update :velocity add (scale (downwind-sails-force @ship wind) (/ tickrate)))))
|
||||
|
||||
(defn tick
|
||||
[ships]
|
||||
(doseq [ship ships]
|
||||
(-> ship (physics-step hardcoded-wind))))
|
||||
|
||||
(defn stop-program
|
||||
[]
|
||||
(when @program
|
||||
(reset! @program false)))
|
||||
|
||||
(defn start-program
|
||||
[]
|
||||
(stop-program)
|
||||
(let [thread-continue (atom true)]
|
||||
(.start
|
||||
(Thread.
|
||||
(fn []
|
||||
(while @thread-continue
|
||||
(tick @ships)
|
||||
(Thread/sleep (quot 1000 tickrate))))))
|
||||
(reset! program thread-continue)))
|
||||
|
||||
;; UI
|
||||
(def tracked-ship (atom nil))
|
||||
|
||||
(defn ship-chooser
|
||||
[]
|
||||
(let [name (text :columns 20)]
|
||||
(b/bind (.getDocument name) (b/transform #(find-ship @ships %)) tracked-ship)
|
||||
(flow-panel :items ["Ship Name" name])))
|
||||
|
||||
(defn ship-info
|
||||
[])
|
||||
|
||||
(defn show-ui
|
||||
[]
|
||||
(-> (frame :title "Space Sim" :content (ship-chooser)) pack! show!))
|
||||
|
||||
(defn -main
|
||||
[args]
|
||||
(start-program)
|
||||
(show-ui))
|
||||
31
src/age_of_sail/vec2.clj
Normal file
31
src/age_of_sail/vec2.clj
Normal file
@@ -0,0 +1,31 @@
|
||||
(ns age-of-sail.vec2
|
||||
(:require [clojure.math :as math]))
|
||||
|
||||
(defn zero
|
||||
[]
|
||||
[0. 0.])
|
||||
|
||||
(defn add
|
||||
[v1 v2]
|
||||
(mapv + v1 v2))
|
||||
|
||||
(defn scale
|
||||
[v & scalars]
|
||||
(mapv #(* (apply * scalars) %) v))
|
||||
|
||||
(defn len2
|
||||
[v]
|
||||
(apply + (map #(* % %) v)))
|
||||
|
||||
(defn len
|
||||
[v]
|
||||
(math/sqrt (len2 v)))
|
||||
|
||||
(defn normalize
|
||||
[v]
|
||||
(let [length (len v)]
|
||||
(mapv #(/ % length) v)))
|
||||
|
||||
(defn dot
|
||||
[v1 v2]
|
||||
(apply + (map * v1 v2)))
|
||||
Reference in New Issue
Block a user