:path-fn path/projectile-path-on-level
})
-(def DirectionEnum {"NONE" 0 "CW" 1 "CCW" 2})
+(def ^{:doc "Enumeration of directions a flipper can be flipping."}
+ DirectionEnum {"NONE" 0 "CW" 1 "CCW" 2})
(defn direction-string-from-value
+ "Given a value from DirectionEnum, return the corresponding string."
[val]
(first (first (filter #(= 1 (peek %)) (into [] maptest)))))
})
(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
:flip-permanent-dir nil
))
-;; TODO: CW usually right, not always
-;; CCW rotation goes through level
-;; adding 360 deg to angle fixes it... but when??
-
(defn flip-angle-stride
"Returns the angle stride of a flipper, which is how many radians to
increment his current flip angle by to be completely flipped onto his
:else (if cw? dir1 dir0))))
(defn mark-flipper-for-flipping
+ "Updates a flipper's map to indicate that it is currently flipping in the
+ given direction, to the given segment index. cw? should be true if
+ flipping clockwise, false for counter-clockwise."
[flipper direction seg-idx cw?]
(let [point (path/flip-point-between-segments
(:level flipper)
:flip-permanent-dir permanent)))
(defn update-entity-stop-flipping
+ "Updates an entity and marks it as not currently flipping."
[flipper]
(assoc flipper
:stride (:old-stride flipper)
:flip-cur-angle 0
:segment (:flip-to-segment flipper)))
-(defn random-direction-string
+(defn random-direction
+ "Returns a random direction from DirectionEnum (not 'NONE')"
[]
(condp = (rand-int 2)
0 (DirectionEnum "CW")
(DirectionEnum "CCW")))
(defn segment-for-flip-direction
+ "Returns the segment that the given flipper would flip into if it flipped
+ in direction flip-dir. If the flipper can't flip that way, it will
+ return the flipper's current segment."
[flipper flip-dir]
(condp = flip-dir
(DirectionEnum "CW") (segment-entity-cw flipper)
(segment-entity-ccw flipper)))
(defn swap-flipper-permanent-dir
+ "Given a flipper with its 'permanent direction' set, this swaps the
+ permanent direction to be opposite. A flipper's permanent direction is
+ the direction it flips constantly along the outermost edge of the level
+ until it hits a boundary."
[flipper]
(let [cur-dir (:flip-permanent-dir flipper)
new-dir (if (= (DirectionEnum "CW") cur-dir)
(assoc flipper :flip-permanent-dir new-dir)))
(defn maybe-engage-flipping
+ "Given a flipper, returns the flipper possibly modified to be in a state
+ of flipping to another segment. This will always be true if the flipper
+ is on the outermost edge of the level, and will randomly be true if it
+ has not reached the edge."
[flipper]
(let [should-flip (and (or
(= (:step flipper) 50)
)
(= (:flip-dir flipper) (DirectionEnum "NONE")))
permanent-dir (:flip-permanent-dir flipper)
- flip-dir (or permanent-dir (random-direction-string))
+ flip-dir (or permanent-dir (random-direction))
flip-seg-idx (segment-for-flip-direction flipper flip-dir)
cw? (= flip-dir (DirectionEnum "CW"))]
(cond
:else flipper)))
(defn update-entity-is-flipping
+ "Decide if an enemy should start flipping for every enemy on the level."
[game-state]
(let [{enemy-list :enemy-list} game-state]
(assoc game-state :enemy-list (map maybe-engage-flipping enemy-list))))
(defn update-entity-flippyness
+ "Update the position of any actively flipping enemy for every enemy on the
+ level."
[game-state]
(let [{enemy-list :enemy-list} game-state]
(assoc game-state :enemy-list (map update-flip-angle enemy-list))))
(defn update-flip-angle
+ "Given a flipper in the state of flipping, updates its current angle. If
+ the update would cause it to 'land' on its new segment, the flipper is
+ updated and returned as a no-longer-flipping. If the given enemy is
+ not flipping, returns it unchanged."
[flipper]
(let [new-angle (+ (:flip-stride flipper) (:flip-cur-angle flipper))
remaining (dec (:flip-steps-remaining flipper))
(path/round-path ((:path-fn entity) entity))
true
(:flip-point entity)
- ;;[20 -20]
- (:flip-cur-angle entity)
- ;;0
- )
+ (:flip-cur-angle entity))
(.closePath context)))
(defn draw-board
(polar-to-cartesian-coords point1)]))
(defn cartesian-point-between-segments
+ "Returns the cartesian coordinates of the point on the edge in between
+ the two given segments at the given step. This is the point about which
+ a flipping enemy should rotate."
[level seg-idx0 seg-idx1 step]
(let [line (edge-line-between-segments level seg-idx0 seg-idx1)
line-steps (step-length-for-level-line level line)
(defn edge-line-between-segments
+ "Returns the polar coordinates (i.e. description of a line) of the line
+ between the given segments."
[level seg-idx0 seg-idx1]
(let [segs0 (get (:segments level) seg-idx0)
segs1 (get (:segments level) seg-idx1)
))
(defn flip-point-between-segments
+ "Returns the point about which an enemy on seg-idx-cur flipping to
+ seg-idx-new from step step should be rotated. cw? should be true
+ if enemy would be flipping clockwise, false otherwise."
[level seg-idx-cur seg-idx-new step cw?]
(let [[x0 y0] (cartesian-point-between-segments level
seg-idx-cur
edge-points (cartesian-edge-coordinates level seg-idx-new step)]
[(- x1 x0) (- y0 y1)]))
-(comment
-(defn flip-point-between-segments
- [level seg-idx-cur seg-idx-new step cw?]
- (let [[x0 y0] (polar-to-cartesian-coords
- (polar-segment-midpoint level seg-idx-cur step))
- [[x1 y1] [x2 y2]] (cartesian-edge-coordinates level seg-idx-new step)]
- (.log js/console (str "CW? " (pr-str cw?) " "
- (pr-str [(- x0 x2) (- y2 y0)]
- [(- x1 x0) (- y0 y1)])))
- (if cw?
- [(- x0 x2) (- y2 y0)]
- [(- x1 x0) (- y0 y1)])))
-)
(defn rebase-origin
"Return cartesian coordinate 'point' in relation to 'origin'."
(:segment entity)
(:step entity)))
-
-(comment
- (defn polar-entity-coord
- "Returns current polar coordinates to the entity."
- [entity]
- (let [steplen (step-length-segment-midpoint (:level entity)
- (:segment entity))
- offset (* steplen (:step entity))
- midpoint (segment-midpoint (:level entity) (:segment entity))]
- (polar-extend offset midpoint)))
- )
-
(defn step-length-segment-midpoint
"Finds the 'step length' of a line through the middle of a level's segment.
This is how many pixels an entity should move per update to travel one