May 23, 2015

Tetris in clojurescript and re-frame Part 4 - Drawing

Drawing functions

There are several drawing functions.
The first one is a helper function taking the canvas and a vector of functions that will be executed.

(defn draw-block-x [ctx & [line-to-fns]]
  (.beginPath ctx)
  (doseq [f line-to-fns] (f))
  (.fill ctx))
                     
These four functions will draw the for single blocks that each tetrimino contains.

(defn draw-block-top [x y ctx]
  (draw-block-x ctx [#(.moveTo ctx x y)
                         #(.lineTo ctx (+ 20 x) y)
                         #(.lineTo ctx (+ 18 x) (+ 2 y))
                         #(.lineTo ctx (+ 2 x) (+ 2 y))]))

(defn draw-block-left [x y ctx]
  (draw-block-x ctx [#(.moveTo ctx x y)
                     #(.lineTo ctx x (+ 20 y))
                     #(.lineTo ctx (+ 2 x) (+ 18 y))
                     #(.lineTo ctx (+ 2 x) (+ 2 y))]))

(defn draw-block-right [x y ctx]
  (draw-block-x ctx [#(.moveTo ctx (+ 20 x) y)
                     #(.lineTo ctx (+ 20 x) (+ 20 y))
                     #(.lineTo ctx (+ 18 x) (+ 18 y))
                     #(.lineTo ctx (+ 18 x) (+ 2 y))]))

(defn draw-block-bottom [x y ctx]
  (draw-block-x ctx [#(.moveTo ctx x (+ 20 y))
                     #(.lineTo ctx (+ 20 x) (+ 20 y))
                     #(.lineTo ctx (+ 18 x) (+ 18 y))
                     #(.lineTo ctx (+ 2 x) (+ 18 y))]))
    
And finally the function to draw a complete tetriminio which will call all four functions to draw the single blocks.
(defn draw-block [x y h ctx]
  (let [x' (* x 20)
        y' (* y 20)]                                        ; (* 20 (- 19 y))
    (aset ctx "fillStyle" (str "hsl(" h ",100%,50%)"))
    (.fillRect ctx (+ 2 x') (+ 2 y') 16 16)

    (aset ctx "fillStyle" (str "hsl(" h ",100%,70%)"))
    (draw-block-top x' y' ctx)

    (aset ctx "fillStyle" (str "hsl(" h ",100%,40%)"))
    (draw-block-left x' y' ctx)

    (draw-block-right x' y' ctx)

    (aset ctx "fillStyle" (str "hsl(" h ",100%,30%)"))
    (draw-block-bottom x' y' ctx)))

The draw-grid function draws the complete tetris grid which has a width of 200px and a height of 400pxs.
it takes a grid as a param which is a 2 dimensional vector whereas each x-y entry contains the element at that place of the the grid:

(defn draw-grid [grid ctx]
  (.clearRect ctx 0 0 200 400)
  (doseq [x (range 10)
          y (range 20)]
    (let [t (get-in grid [x y])]
      (when-not (= 0 t)
        (draw-block x y (get color-map t) ctx)))))  
Tags: tetris clojuresrcipt