Skip to content

Latest commit

 

History

History
117 lines (99 loc) · 3.37 KB

day07.md

File metadata and controls

117 lines (99 loc) · 3.37 KB

Day 7

Made board renderer generic for different sizes and scales, so we can render the "next piece" display as a small board and the competitor boards at smaller scales.

(defn size-canvas!
  "Set the size of the canvas."
  ([id board scale] (size-canvas! id board scale 0))
  ([id board scale y-cutoff]
   (let [canvas (.getElementById js/document id)
         [w h] (board-size board)]
     (aset canvas "width" (* scale w))
     (aset canvas "height" (* scale (- h y-cutoff))))))

(defn draw-board!
  "Draw the given board to the canvas."
  ([id board scale level] (draw-board! id board scale level 0))
  ([id board scale level y-cutoff]
    (let [canvas (.getElementById js/document id)
          ctx (.getContext canvas "2d")
          [w h] (board-size board)]
      (doseq [x (range w) y (range h)]
        (let [color (cell-colors (read-board x y board))
              left (* scale x)
              top (* scale (- y y-cutoff))]
          (aset ctx "fillStyle" color)
          (.fillRect ctx left top scale scale)))
      nil)))

The actual board rendering lines are a bit long with addition of the new parameters; I wonder how I would make it cleaner.

; Set sizes
(size-canvas! "game-canvas" empty-board cell-size rows-cutoff)
(size-canvas! "next-canvas" (next-piece-board) cell-size)

; Draw boards
(draw-board! "game-canvas" new-board cell-size (:level @state) rows-cutoff)
(draw-board! "next-canvas" (next-piece-board next-piece) cell-size (:level @state))

The "next piece" board is just generated with a function:

(defn next-piece-board
  "Returns a small board for drawing the next piece."
  ([] (next-piece-board nil))
  ([piece]
    (let [board [[0 0 0 0]
                 [0 0 0 0]
                 [0 0 0 0]
                 [0 0 0 0]]]
      (if piece
        (write-piece-to-board piece 1 2 board)
        board))))

Created a simple tilemap, with the first three rows representing the original, dos, and gameboy versions. The rest of the rows just use our default colors:

tilemap

The column order for the tiles are listed below in the cell-columns map. And draw-board is shown modified to read from the tilemap instead of drawing a solid-filled rectangle.

(def tilemap (let [img (js/Image.)]
               (aset img "src" "tilemap.png")
               img))

(def cell-columns
  { 0 0
   :I 1
   :L 2
   :J 3
   :S 4
   :Z 5
   :O 6
   :T 7
   :G 8  ; ghost piece
   :H 9  ; highlighted (filled or about to collapse)
   })

(defn draw-board!
  "Draw the given board to the canvas."
  ([id board scale level] (draw-board! id board scale level 0))
  ([id board scale level y-cutoff]
    (let [canvas (.getElementById js/document id)
          ctx (.getContext canvas "2d")
          [w h] (board-size board)]
      (doseq [x (range w) y (range h)]
        (let [; tilemap position
              row (mod level 10)
              col (cell-columns (read-board x y board))

              ; source coordinates (on tilemap)
              sx (* scale col)
              sy (* scale row)
              sw scale
              sh scale

              ; destination coordinates (on canvas)
              dx (* scale x)
              dy  (* scale (- y y-cutoff))
              dw scale
              dh scale]

          (.drawImage ctx tilemap sx sy sw sh dx dy dw dh)))
      nil)))