oakes/play-cljc

Drawing rectangle

Closed this issue · 3 comments

I think I might be misunderstanding some library concepts I want to clear up. I have edited the "run" function like this in an attempt to draw a rectangle on screen, using https://oakes.github.io/play-cljc/cljs/play-cljc.gl.examples-2d/rand-rects-example.html as a guide:

(defn run [game]
  (let [{:keys [pressed-keys
                player-x
                player-y
                direction
                player-images
                player-image-key]
         :as state} @*state
        game-width (utils/get-width game)
        game-height (utils/get-height game)]
    ;; render the blue background
    (c/render game (update screen-entity :viewport
                           assoc :width game-width :height game-height))
    ;; get the current player image to display
    (when-let [player (get player-images player-image-key)]
      (let [player-width (/ game-width 10)
            player-height (* player-width (/ (:height player) (:width player)))]
        ;; render the player
        (c/render game
          (-> player
              (t/project game-width game-height)
              (t/translate (cond-> player-x
                                   (= direction :left)
                                   (+ player-width))
                           player-y)
              (t/scale (cond-> player-width
                               (= direction :left)
                               (* -1))
                       player-height)))
        ;; render another player
        (c/render game
          (-> player
              (t/project game-width game-height)
              (t/translate (cond-> player-x
                                   (= direction :left)
                                   (+ player-width))
                           (- player-y 50))
              (t/scale (cond-> player-width
                               (= direction :left)
                               (* -1))
                       player-height)))
        ;; render a rectangle
        (let [rect-entity (c/compile game (e/->entity game p/rect))]
          (c/render game
                    (-> rect-entity
                        (t/project game-width game-height)
                        (t/color [0 0 0])
                        (t/translate 100 100)
                        (t/scale 500 500))))
        ;; change the state to move the player
        (swap! *state
          (fn [state]
            (->> (assoc state
                        :player-width player-width
                        :player-height player-height)
                 (move/move game)
                 (move/prevent-move game)
                 (move/animate game)))))))
  ;; return the game map
  game)

My duplicate bird rendering works great (as I expect), but my rectangle does not seem to show up. Am I missing a function call that adds crucial data to the rect entity to make it drawable? Is the rect entity of the same "type" as the bird entity? One thing I do think I realize is that initializing the entity in the init is probably much more efficient than doing it on every run, but this shouldn't make it not renderable, right?

oakes commented

You are right that you should never call e/->entity or c/compile in the run function, because that will cause it to allocate a new entity and compile the shaders every single loop of your game. Instead, run that in the init function and save it into the *state, then pull it out in the beginning of the run function.

It looks like you are only passing three values to t/color but it expects rgba, so you need to give it the alpha value. Try passing [0 0 0 1].

That worked! Thanks! I think I need to learn more about what a protocol is, but as I do, how would I find the implementation of the t/color function to find this out for myself? I'm having a hard time locating it for a rectangle entity.

oakes commented

You can find the implementation here. The rectangle is a TwoDEntity so all the protocols are implemented on that.