back home

A Matter of Patience. Adventures With Quil, ClojureScript and Matter.js

Written by Bunkers on March 12, 2017

Today I'm supposed to be writing about 'waiting' and until a couple of minutes ago I had know idea what experience I could use for this topic. Luckily, or perhaps not, I've been struggling with a project that I'm using to teach myself some more Clojure. The problems I've been having are nearly all related to me attempting to run before I can walk. I should have waited and got a simple thing working first but instead I started by adding loads of complexity to a simple example, and leaving myself scratching my head. As having patience is a form of waiting, I've decided it fits the topic well enough!

I'm using Daniel Schiffman's tutorial on Matter.js with P5, and attempting to create it with Quil and ClojureScript. Quil uses Processing.js under the hood which appears to be a dying project (maybe because of P5) so another project would be to swap that out for P5, although that's a laughable ambition given the amount of time it took me to debug some of this example so far!

To setup the project I used Leiningen to setup a simple Quil template:

lein new quil-cljs hello-quil

As in the tutorial on the wiki. I added Matter as a dependency to my project.clj file:

:dependencies [[org.clojure/clojure "1.8.0"]
                 [quil "2.6.0"]
                 [cljsjs/matter "0.9.1-0"]
                 [org.clojure/clojurescript "1.9.473"]]

The version of Matter available is out of date now, so I don't know if I'll come across any fixed bugs. If so, this could spawn another project to update this. It should just be case of updating any new externs.

I wanted to use Figwheel for live reloading, and so I further adapted my project.clj file to include the plugin:

  :plugins [[lein-cljsbuild "1.1.5"]
            [lein-figwheel "0.5.9"]]

Lastly, I add in the build configurations and profiles:

  {:builds {:main
             :source-paths ["src"]
             {:asset-path "js/out"
              :output-to "resources/public/js/main.js"
              :output-dir "resources/public/js/out"
              :main "hello_quil.core"
  :profiles {:dev {:dependencies [[binaryage/devtools "0.7.2"]]
                   :cljsbuild {
                               :builds {
                                        :main {:figwheel true
                                               :compiler {:optimizations :none
                                                          :source-map true
                                                          ;; namespace to load before the `:main` namespace
                                                          :preloads [devtools.preload]}}}}}
             ;; `prod` key is not known to lein, choose any you want
             :prod {:cljsbuild {:builds {:main {:compiler {:optimizations :advanced
                                                           :pretty-print false}}}}}}

Figwheel serves files from resources/public by default, so I moved the generated index.html file from the project's root folder to there. It's not created by the project template, so don't worry if you've got no resources/public folder, just create it.

This seems like one easy step, but just setting this project up and discovering useful additions like binaryage/devtools for pretty printing data structures to the Chrome console, took some time!

With these changes in place you can start the project up with:

lein figwheel

Visit http://localhost:3449 once everything has compiled and you should see the demo Quil sketch of a circle spinning while its colour strobes. I marvelled in this for a while and made a couple of edits to test the reloading, like the suggested change to convert the addition of the angle to subtraction, so the circle spins the other way.

Being able to live reload code like this is one of the reasons I'm so enamoured with Clojure at the moment. Also on the topic of waiting, my productivity is often destroyed when working on projects with long build times, or even build processes at all! I end up having to wait a minute or two for a process to complete, suddenly I'm off reading email or making coffee, and I lose half an hour. Just me?

With Clojure development I'm always playing about with a REPL to inspect data and debug problems. I transfer updates to my editor, save it and the code is hot reloaded in to the browser. It's great, I don't even need to hit refresh!

With this example project up and running, I set about hacking around with the src/hello_quil/core.cljs to complete the first step of getting a box on the screen. I've done that now, it falls down using Matter.js for the physics, but it took some thinking about. Unfortunately, I'm going to make you wait until the next post to find out my approach!