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:
- Ship movement, that is, rotation, forward, and backward
- Firing the ship's gun
- Pausing the game
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.