Last active
December 19, 2015 11:09
-
-
Save jcromartie/5945878 to your computer and use it in GitHub Desktop.
Clojure game skeleton
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn run-game! | |
[title w h init-state tick render] | |
(let [dim (Dimension. w h) | |
keystate (atom #{}) | |
listener (input/listener | |
{:key-pressed (fn [code] | |
(swap! keystate conj code)) | |
:key-released (fn [code] | |
(swap! keystate disj code)) | |
:focus-lost (fn [] | |
;; just reset all keys | |
(swap! keystate (fn [_] #{})))}) | |
canvas (doto (Canvas.) | |
(.setSize dim) | |
(.setBackground Color/white) | |
(.addKeyListener listener) | |
(.addFocusListener listener)) | |
frame (JFrame. title) | |
;; this atom tracks our window state | |
running' (atom true) | |
;; when the window is closed... | |
window-listener (proxy [WindowAdapter] [] | |
(windowClosed [_] | |
;; ... set the running? atom's value to false | |
(swap! running' (constantly false)))) | |
;; the thread that runs the game loop itself | |
thread (Thread. | |
(bound-fn [] | |
(loop [state init-state] | |
;; On each frame, derive the new state by checking | |
;; if we are still running and then passing the | |
;; old state and the input to the tick | |
;; function. We only proceed if the new state is | |
;; not nil. The tick function can return nil to | |
;; quit the game. | |
(when @running' | |
(if-let [new-state (tick state @keystate)] | |
(let [bs (.getBufferStrategy canvas) | |
g (.getDrawGraphics bs)] | |
(render new-state g) | |
(.dispose g) | |
(.show bs) | |
(Thread/sleep (hz 60)) | |
(recur new-state)) | |
(.dispose frame))))))] | |
(doto (.getContentPane frame) | |
(.setPreferredSize dim) | |
(.setLayout nil) | |
(.add canvas)) | |
(doto frame | |
;; call our window listener when the window is closed so we can | |
;; clean up the game loop thread | |
(.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE) | |
(.addWindowListener window-listener) | |
(.setResizable false) | |
(.setBackground Color/green) | |
(.pack) | |
(.setVisible true)) | |
;; canvas setup after the frame is visible | |
(doto canvas | |
(.requestFocus) | |
(.createBufferStrategy 3)) | |
(.start thread))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment