1- (ns hyperspace.game
2- (:use (hyperspace geometry
3- gravity
4- world)))
5-
6- (defn get-player
7- [world name]
8- (first (filter #(= name (:name %)) (:players world))))
9-
10- (defn update-player-params
11- [world name heading power]
12- (assoc world
13- :players (map (fn [player]
14- (if (= (:name player) name)
15- (assoc player
16- :heading heading
17- :power power)
18- player))
19- (:players world))))
20-
21- (defn fire
22- [world player-name]
23- (let [player (get-player world player-name)
24- {point :center
25- power :power
26- angle :heading } player
27- bullet (make-bullet point (make-vector-radial power angle))]
28- (assoc world
29- :bullets (conj (:bullets world) bullet))))
30-
31- (defn destroy-bullet?
32- [bullet planets]
33- (let [bullet-center (:center bullet)]
34- (some (fn [{planet-radius :radius
35- planet-center :center }]
36- (<= (point-distance bullet-center
37- planet-center)
38- planet-radius))
39- planets)))
40-
41- (defn update-bullet
42- [bullet planets]
43- (if (= (:status bullet) :dead )
44- bullet
45- (let [acceleration (get-acceleration bullet planets)
46- {position :center
47- velocity :velocity
48- traces :traces } bullet]
49- (assoc bullet
50- :center (move-point position velocity)
51- :velocity (vector-sum velocity acceleration)
52- :status (if (destroy-bullet? bullet planets) :dead :alive )
53- :traces (conj traces position)))))
54-
55- (defn update-world
56- " Simulates few steps for world. Returns new world and remaining time."
57- [world time]
58- (let [{bullets :bullets
59- planets :planets } world]
60- (if (< time 1 )
61- [world time]
62- (recur (assoc world
63- :bullets (doall (map #(update-bullet % planets) bullets)))
64- (- time 1 )))))
1+ (ns hyperspace.game
2+ (:use [hyperspace world geometry gravity misc]))
3+
4+ (defn turn-right
5+ [{[player & _] :players
6+ :as world}
7+ delta-angle]
8+ (let [{[angle, _] :heading } player]
9+ (assoc-in world
10+ [:players 0 :heading 0 ]
11+ (- angle delta-angle))))
12+
13+ (defn turn-left
14+ [{[player & _] :players
15+ :as world}
16+ delta-angle]
17+ (let [{[angle, _] :heading } player]
18+ (assoc-in world
19+ [:players 0 :heading 0 ]
20+ (+ angle delta-angle))))
21+
22+ (defn increase-power
23+ [world delta-power]
24+ (let [power (get-in world [:players 0 :heading 1 ])]
25+ (assoc-in world
26+ [:players 0 :heading 1 ]
27+ (saturation (+ power delta-power)
28+ 1 10 ))))
29+
30+ (defn decrease-power
31+ [world delta-power]
32+ (let [power (get-in world [:players 0 :heading 1 ])]
33+ (assoc-in world
34+ [:players 0 :heading 1 ]
35+ (saturation (- power delta-power)
36+ 1 10 ))))
37+
38+ (defn fire
39+ [{[player & _] :players
40+ :as world}]
41+ (let [{position :position
42+ [_, power :as heading] :heading } player
43+ missile-position (-> (polar->cartesian heading)
44+ normilize-vector
45+ (multiply-by-scalar (+ player-radius
46+ missile-radius))
47+ (vector-sum position))
48+ missile-velocity (-> (polar->cartesian heading)
49+ normilize-vector
50+ (multiply-by-scalar (* power 100 )))]
51+ (add-missile world
52+ missile-position
53+ missile-velocity)))
54+
55+ (defn update-particle
56+ [{position :position
57+ velocity :velocity
58+ :as particle}
59+ planets
60+ delta-time]
61+ (let [acceleration (apply vector-sum
62+ (map #(gravity-acceleration particle %)
63+ planets))
64+ ; ; FIXME: Duplicate code
65+ new-velocity (-> acceleration
66+ (multiply-by-scalar (* delta-time 1e-3 ))
67+ (vector-sum velocity))
68+ new-position (-> new-velocity
69+ (multiply-by-scalar (* delta-time 1e-3 ))
70+ (vector-sum position))]
71+ (assoc particle
72+ :position new-position
73+ :velocity new-velocity)))
74+
75+ (defn update-traces
76+ [traces
77+ {position :position
78+ trace-index :trace-index }]
79+ (update-in traces [trace-index] conj position))
80+
81+ (defn break-particle
82+ [{particle-position :position
83+ particle-radius :radius
84+ velocity :velocity
85+ radius :radius
86+ :as particle}
87+ planets]
88+ (let [planet (some #(when (circle-X-circle? % particle) %) planets)]
89+ (if (and planet (> radius 1.0 ))
90+ (let [{planet-position :position
91+ planet-radius :radius } planet
92+
93+ fragments-position (-> (vector-subtract particle-position planet-position)
94+ normilize-vector
95+ (multiply-by-scalar (+ particle-radius planet-radius 5 ))
96+ (vector-sum planet-position))]
97+ (repeatedly 5
98+ (fn []
99+ (make-fragment fragments-position
100+ (polar->cartesian [(rand (* 2 Math/PI)),
101+ (/ (vector-length velocity) 2 )])
102+ (- radius 2 )))))
103+ ())))
104+
105+ (defn update-world
106+ [{missiles :missiles
107+ planets :planets
108+ fragments :fragments
109+ traces :traces
110+ :as world}
111+ delta-time]
112+ (let [broken-particles (mapcat #(break-particle % planets)
113+ (concat missiles fragments))
114+ ; ; FIXME: Duplicate code
115+ new-missiles (->> missiles
116+ (filter #(circle-X-rectangle? % world))
117+ (remove #(circle-X-any-circle? % planets))
118+ (map #(update-particle % planets delta-time)))
119+ new-fragments (->> fragments
120+ (concat broken-particles)
121+ (filter #(circle-X-rectangle? % world))
122+ (remove #(circle-X-any-circle? % planets))
123+ (map #(update-particle % planets delta-time)))
124+
125+ new-traces (reduce update-traces traces new-missiles)]
126+ (assoc world
127+ :missiles new-missiles
128+ :fragments new-fragments
129+ :traces new-traces)))
0 commit comments