Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines
(1 edit) (+1)

Hint #5 -- Taking advantage of E-S to avoid special cases.

It's very tempting at times to just draw something in the render as a special case. And that's not necessarily bad! Especially if you're trying to get something working. However, if you can take advantage of Canned Heat's entity store, your code will be a lot more flexible and maintainable. Not to mention probably shorter!

Here's an example... I wanted to put a "GAME OVER" message up, so I dropped it in at the end of the main draw function as a special case just so I could see it:

       (when (= 'dead hero.state)
         (:= cx 'fillStyle 'orange)
              (:= cx 'font "Bold 100px sans-serif")
              (:= cx 'textAlign 'center)
              (cx.fillText "GAME OVER"
                           (+ (/ SV.screen.width 2)  (- (* 5 (Math.random)) 3))
                           (+ (/ SV.screen.height 2) (- (* 5 (Math.random)) 3)))
              (:= cx 'textAlign 'start))
       )

The drawing is conditional on the hero being dead, which is simple enough. However that's one place where stuff like this can get you into trouble, when you have too many special cases to keep track of. Then, I set special font attributes and text alignments. While I clean up the alignment, I didn't bother resetting anything else. And, notice that I'm computing during the draw with the jitter factor being applied to the location of the cx.filllText. That should be really happening in a System.

So, to clean this up, I used mk-text instead. You can specify all the properties you need and let the draw loop handle it for you:

   (define (sys-lose?)
     "( --) Check to see if Kat has fallen and can't get up."
     (let ([hero (q1 'hero)])
       (when (and (not (= 'dead hero.state))
                  (< (+ SV.screen.height (/ SV.screen.height 4)) hero.y))
         (:= hero.state 'dead)
         (mk-text '(("GAME OVER"))
                  (/ SV.screen.width 2) (/ SV.screen.height 2) 'orange
                  '((font "Bold 100px sans-serif")
                    (jitter 3) (textAlign center)))
         )))

Now I set create the GAME OVER message in the System where I determine that the hero has died. The jitter property is set so that the sys-jitter System will animate it properly. But best of all, instead of dead pixels drawn irretrievably into a frame buffer, I have a live object for the GAME OVER text that I could do other things with if I wanted. The other advantage, of course, is that I have a general way to create text from the data in the Store instead of having to write code to do it.