Clojure is a dialect of Lisp, written for the JVM and with functional programming in mind. Clojure comes with native Java interoperability, making it able to leverage the powerful existing libraries in the Java ecosystem. ClojureTV on YouTube has a lot of good videos, specifically Clojure for Java Programmers (Part 2).

project setup

Your project’s directory structure should look something like

  1. demo
  2. - android
  3. - desktop
  4. - resources
  5. - src
  6. - demo
  7. - core
  8. - desktop_launcher.clj
  9. - src-common
  10. - demo
  11. - core.clj
  12. - project.clj

project.clj

  1. (defproject demo "0.0.1-SNAPSHOT"
  2. :description "FIXME: write description"
  3. :dependencies [[com.badlogicgames.gdx/gdx "1.9.3"]
  4. [com.badlogicgames.gdx/gdx-backend-lwjgl "1.9.3"]
  5. [com.badlogicgames.gdx/gdx-box2d "1.9.3"]
  6. [com.badlogicgames.gdx/gdx-box2d-platform "1.9.3"
  7. :classifier "natives-desktop"]
  8. [com.badlogicgames.gdx/gdx-bullet "1.9.3"]
  9. [com.badlogicgames.gdx/gdx-bullet-platform "1.9.3"
  10. :classifier "natives-desktop"]
  11. [com.badlogicgames.gdx/gdx-platform "1.9.3"
  12. :classifier "natives-desktop"]
  13. [org.clojure/clojure "1.7.0"]]
  14. :source-paths ["src" "src-common"]
  15. :javac-options ["-target" "1.6" "-source" "1.6" "-Xlint:-options"]
  16. :aot [demo.core.desktop-launcher]
  17. :main demo.core.desktop-launcher)

desktop_launcher.clj

  1. (ns demo.core.desktop-launcher
  2. (:require [demo.core :refer :all])
  3. (:import [com.badlogic.gdx.backends.lwjgl LwjglApplication]
  4. [org.lwjgl.input Keyboard])
  5. (:gen-class))
  6. (defn -main []
  7. (LwjglApplication. (demo.core.Game.) "demo" 800 600)
  8. (Keyboard/enableRepeatEvents true))

core.clj

  1. (ns demo.core
  2. (:import [com.badlogic.gdx Game Gdx Graphics Screen]
  3. [com.badlogic.gdx.graphics Color GL20]
  4. [com.badlogic.gdx.graphics.g2d BitmapFont]
  5. [com.badlogic.gdx.scenes.scene2d Stage]
  6. [com.badlogic.gdx.scenes.scene2d.ui Label Label$LabelStyle]))
  7. (gen-class
  8. :name demo.core.Game
  9. :extends com.badlogic.gdx.Game)
  10. (def main-screen
  11. (let [stage (atom nil)]
  12. (proxy [Screen] []
  13. (show []
  14. (reset! stage (Stage.))
  15. (let [style (Label$LabelStyle. (BitmapFont.) (Color. 1 1 1 1))
  16. label (Label. "Hello world!" style)]
  17. (.addActor @stage label)))
  18. (render [delta]
  19. (.glClearColor (Gdx/gl) 0 0 0 0)
  20. (.glClear (Gdx/gl) GL20/GL_COLOR_BUFFER_BIT)
  21. (doto @stage
  22. (.act delta)
  23. (.draw)))
  24. (dispose[])
  25. (hide [])
  26. (pause [])
  27. (resize [w h])
  28. (resume []))))
  29. (defn -create [^Game this]
  30. (.setScreen this main-screen))

you can launch the window with lein run in the project.clj directory, or the repl of your choice by calling (demo.core.desktop-launcher/-main).

For repl based dev have your main-screen call fns for each lifecycle method you wish to re-evaluate.

play-clj

The play-clj library provides a Clojure wrapper for libGDX. To get started, install Leiningen and run the following command:

  1. lein new play-clj hello-world

A directory called hello-world should appear, and inside you’ll find directories for android and desktop. Inside the desktop directory, you’ll find a src-common directory, which contains the game code that both projects will read from. Navigate inside of it to find core.clj, which looks like this:

  1. (ns hello-world.core
  2. (:require [play-clj.core :refer :all]
  3. [play-clj.ui :refer :all]))
  4. (defscreen main-screen
  5. :on-show
  6. (fn [screen entities]
  7. (update! screen :renderer (stage))
  8. (label "Hello world!" (color :white)))
  9. :on-render
  10. (fn [screen entities]
  11. (clear!)
  12. (render! screen entities)))
  13. (defgame hello-world
  14. :on-create
  15. (fn [this]
  16. (set-screen! this main-screen)))

This will display a label on the bottom left corner, which you can see by running lein run inside the desktop directory. To generate a JAR file that you can distribute to other people, run lein uberjar and grab the file in the target directory that contains the word “standalone”.

  • The play-clj tutorial provides a more in-depth walk-through on how to use the library.
  • The Nightmod game tool provides an easier way to use play-clj by integrating the game and the text editor together so you can see instant results when you save your code.