Highlight player's segment. Added levels. Started working on more enemies.
"Called by next-game-state when game and player are active."
[game-state]
(->> game-state
+ clear-player-segment
dequeue-keypresses
+ highlight-player-segment
maybe-change-level
clear-frame
draw-board
(def ^{:doc "Enumeration of directions a flipper can be flipping."}
DirectionEnum {"NONE" 0 "CW" 1 "CCW" 2})
+(def ^{:doc "Enumeration of types of enemies."}
+ EnemyEnum {"NONE" 0 "FLIPPER" 1 "TANKER" 2
+ "SPIKER" 3 "FUSEBALL" 4 "PULSAR" 5})
+
(defn direction-string-from-value
"Given a value from DirectionEnum, return the corresponding string."
[val]
:level level
:hits-remaining 1
:path-fn #([])
- :bounding-fn #(identity 0)
:flip-dir (DirectionEnum "NONE")
:flip-point [0 0]
:flip-stride 1
:flip-cur-angle 0
:can-flip false
:shoot-probability 0
+ :type (EnemyEnum "NONE")
})
+(defn build-tanker
+ [level seg-idx & {:keys [step] :or {step 0}}]
+ (assoc (build-enemy level seg-idx :step step)
+ :type (EnemyEnum "TANKER")
+ :path-fn path/tanker-path-on-level
+ :can-flip false
+ :stride 0.2
+ :shoot-probability 0.0
+ ))
+
(defn build-flipper
"A more specific form of build-enemy for initializing a flipper."
[level seg-idx & {:keys [step] :or {step 0}}]
(assoc (build-enemy level seg-idx :step step)
- :bounding-fn path/flipper-path-bounding-box
+ :type (EnemyEnum "FLIPPER")
:path-fn path/flipper-path-on-level
:flip-dir (DirectionEnum "NONE")
:flip-point [0 0]
(assoc global-state :zoom target)
(assoc global-state :zoom newzoom)))))
+(defn clear-player-segment
+ "Returns game-state unchanged, and as a side affect clears the player's
+ current segment back to blue. To avoid weird color mixing, it is cleared
+ to black first (2px wide), then redrawn as blue (1.5px wide). This looks
+ right, but is different from how the board is drawn when done all at once."
+ [game-state]
+ (do
+ (set! (. (:bgcontext game-state) -lineWidth) 2)
+ (draw/draw-player-segment game-state {:r 0 :g 0 :b 0})
+ (set! (. (:bgcontext game-state) -lineWidth) 1.5)
+ (draw/draw-player-segment game-state {:r 10 :g 10 :b 100})
+ game-state))
+
+(defn highlight-player-segment
+ "Returns game-state unchanged, and as a side effect draws the player's
+ current segment with a yellow border."
+ [game-state]
+ (do
+ (set! (. (:bgcontext game-state) -lineWidth) 1)
+ (draw/draw-player-segment game-state {:r 150 :g 150 :b 15})
+ game-state))
+
+
(defn draw-board
"Draws the level when level is zooming in or out, and updates the zoom level.
This doesn't redraw the board normally, since the board is drawn on a
(if is-zooming?
(do
(draw/clear-context (:bgcontext global-state) (:dims global-state))
- (draw/draw-board (:bgcontext global-state)
- {:width (/ width zoom) :height (/ height zoom)}
- (:level global-state)
- zoom)
+ (draw/draw-board (assoc global-state
+ :dims {:width (/ width zoom)
+ :height (/ height zoom)}))
(update-zoom global-state))
global-state)))
(:flip-point entity)
(:flip-cur-angle entity))
(.closePath context))))
+
+(defn draw-player-segment
+ "Draws just the segment of the board that the player is on, with the given
+ color."
+ [{:keys [dims level zoom player] context :bgcontext {pseg :segment} :player}
+ {:keys [r g b]}]
+ (.beginPath context)
+ (set! (. context -strokeStyle) (str "rgb(" r "," g "," b ")"))
+ (draw-rectangle
+ context
+ (path/round-path (path/rectangle-to-canvas-coords
+ dims
+ (path/rectangle-for-segment level pseg))))
+ (.closePath context))
+
(defn draw-board
"Draws a level on a 2D context of an HTML5 canvas with :height and :width
specified in dims."
- [context dims level zoom]
+ [{:keys [dims level zoom player] context :bgcontext}]
(doseq []
(.save context)
;; To fix bug in Firefox. scale to 0.0 breaks it.
(if (zero? zoom)
(.scale context 0.00001 0.0001)
(.scale context zoom zoom))
- (.beginPath context)
+ (set! (. context -lineWidth) 1)
(set! (. context -strokeStyle) (str "rgb(10,10,100)"))
+ (.beginPath context)
(doseq [idx (range (count (:segments level)))]
(draw-rectangle
context
(path/round-path (path/rectangle-to-canvas-coords
dims
(path/rectangle-for-segment level idx)))))
- (.closePath context)
(.restore context)
+ (.closePath context)
))
-;; (path/round-path (map #(list (+ (- (:width dims) (* (:width dims) zoom)) (first %)) (peek %)) (path/rectangle-to-canvas-coords dims (path/rectangle-for-segment level idx)))))
-
(defn clear-context
"Clears an HTML5 context"
[*default-line-length* 342]
])
+
;; Flat level with 14 segments
(def *level3_lines* (vec (flat-level 7 15 80)))
(def *level7_lines* (vec (oblong-level [135 45 135 45] 15 3)))
-;; Oblong level, an open "W"
+;; Oblong level
(def *level8_lines* (vec (oblong-level [135 105 90 33] 8 10)))
+;; Oblong level, V shape
+(def *level9_lines* (vec (oblong-level [50 50 60 60 70] 15 60)))
+
+;; Custom level, a 'V' in horizontal and vertical steps
+(def *level10_lines*
+ [[38 203]
+ [43 217]
+ [34 229]
+ [44 239]
+ [39 255]
+ [50 262]
+ [50 278]
+ [39 284]
+ [44 300]
+ [34 310]
+ [43 322]
+ [38 336]
+ ])
+
(defn make-level-entry
"Make a map that defines a level. A level contains a vector of lines, a
{:flipper 0.01}
:length-fn #(* 10 %)
:steps 400)
+ (make-level-entry *level9_lines* false
+ {:flipper 20}
+ {:flipper 0.01})
+ (make-level-entry *level10_lines* false
+ {:flipper 20}
+ {:flipper 0.01})
])
(enemy-angle flipper)
(flipper-path-with-width (* 0.8 (entity-desired-width flipper))))))
+(defn tanker-path-on-level
+ "Returns the path of polar coordinates to draw a flipper correctly at its
+ current location. It corrects for size and angle."
+ [tanker]
+ (let [coord (polar-entity-coord tanker)]
+ (rotate-path
+ (enemy-angle tanker)
+ (tanker-path-with-width (* 0.8 (entity-desired-width tanker))))))
+
(defn projectile-path-on-level
"Returns the path of polar coordinates to draw a projectile correctly at its
current location. It corrects for size and angle."
(enemy-angle projectile)
(projectile-path-with-width (* 0.3 (entity-desired-width projectile))))))
+(defn tanker-path-with-width
+ "Returns a path to draw a 'flipper' enemy with given width."
+ [width]
+ (let [r (/ width (js/Math.cos (util/deg-to-rad 16)))]
+ [[0 0]
+ [(/ r 2) 16]
+ [(/ r 4) 214]
+ [(/ r 4) 326]
+ [r 164]
+ [(/ r 4) 326]
+ [(/ r 4) 214]
+ [(/ r 2) 16]]))
+
+
(defn flipper-path-with-width
"Returns a path to draw a 'flipper' enemy with given width."
[width]