Putting it all together

We're now ready to assemble our game. Go ahead and open the core namespace file, src/reagi_game/core.cljs, and add the following code:

(ns reagi-game.core 
  (:require [monet.canvas :as canvas] 
            [reagi.core :as r]
            [reagi-game.entities :as entities 
             :refer [move-forward! move-backward! rotate-left! rotate-right! fire!]])) 

The following snippet sets up various data structures and references that we'll need to develop the game:

(def canvas-dom (.getElementById js/document "canvas")) 
 
(def monet-canvas (canvas/init canvas-dom "2d")) 
 
(def ship  
       (entities/shape-data (/ (.-width (:canvas monet-canvas)) 2) 
                            (/ (.-height (:canvas monet-canvas)) 2) 
                            0)) 
 
(def ship-entity (entities/ship-entity ship)) 
 
(canvas/add-entity monet-canvas :ship-entity ship-entity) 
(canvas/draw-loop monet-canvas) 

We start by creating monet-canvas from a reference to our canvas DOM element. We then create our ship data, placing it at the center of the canvas, and add the entity to monet-canvas. Finally, we start draw-loop, which will handle our animations using the browser's native capabilities – internally, it calls window.requestAnimationFrame(), if available, but it falls back to window.setTimemout() otherwise.

If you were to try the application now, this would be enough to draw the ship on the middle of the screen, but nothing else would happen as we haven't started handling user input yet.

As far as user input goes, we're concerned with a few actions:

To account for these actions, we'll define some constants that represent the ASCII codes of the keys involved:

(def UP    38) 
(def RIGHT 39) 
(def DOWN  40) 
(def LEFT  37) 
(def FIRE  32) ;; space 
(def PAUSE 80) ;; lower-case P 

This should look sensible, as we are using the keys that are traditionally used for these types of actions.