[Video] Game development in Clojure (with play-clj)

756 views
Skip to first unread message

James Trunk

unread,
Mar 27, 2014, 1:07:21 PM3/27/14
to clo...@googlegroups.com
Hi everyone,

I thought some of you might be interested to watch my screencast about game development in Clojure with play-clj.

Cheers,
James

Kris Calabio

unread,
Apr 12, 2014, 5:28:29 PM4/12/14
to clo...@googlegroups.com
Great video! I've looked through Zach's examples, and even started coding a game myself. But your screencast helped me have a better understanding of some of the concepts and code that I was having trouble understanding just by looking at the example games. Thanks!
-Kris

James Trunk

unread,
Apr 13, 2014, 5:47:15 PM4/13/14
to clo...@googlegroups.com
Hi Kris,

Thanks for your comment, and I'm very glad that you found the video helpful.

I started doing screencasts because I realised that I learn a new concept fastest by watching someone else doing/explaining it - and I figured I might not be the only one. Saying that, I know screencasts aren't for everyone, and they have a few drawbacks compared to text (harder to search, skim, or repeat sections). So positive comment like yours remind me that I'm not the only auditory/visual learner around here, and inspire me to keep going. Thanks!

James

Kris Calabio

unread,
Apr 13, 2014, 6:08:16 PM4/13/14
to clo...@googlegroups.com
Actually, I thought it would be even more helpful if you had the source code available (for searching/skimming). Is that somewhere online?
-Kris


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/mR1IBJ_OomY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

James Trunk

unread,
Apr 13, 2014, 6:13:14 PM4/13/14
to clo...@googlegroups.com
There's a link to a gist of core.clj in the video's description.

Cheers, 
James

Kris Calabio

unread,
Apr 13, 2014, 6:15:15 PM4/13/14
to clo...@googlegroups.com
Oh great! I guess I must have missed that :P

C K Kashyap

unread,
Apr 13, 2014, 10:41:45 PM4/13/14
to clo...@googlegroups.com
+1 nice video


You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.

halit...@gmail.com

unread,
Apr 14, 2014, 8:04:05 AM4/14/14
to clo...@googlegroups.com
Great video, thanks!

Kris Calabio

unread,
Apr 15, 2014, 5:26:07 PM4/15/14
to clo...@googlegroups.com
James, I have a question. I see this pattern a lot in the sample code and in your code as well, for example:

(defn- move-player [entities]
(->> entities
(map (fn [entity]
(->> entity
(update-player-position)
(update-hit-box))))
(remove-touched-apples)))

When the entities vector gets threaded through the map function, it comes out as a LazySeq. But don't we want to keep the entities as a vector? This seems to be causing problems in my own code, and the only way to keep it working is to change it back to a vector every time I do this, which seems inelegant. Just wondering if I'm missing something.
-Kris

Zach Oakes

unread,
Apr 15, 2014, 6:34:48 PM4/15/14
to clo...@googlegroups.com
Kris, the entities are automatically converted back into a vector by play-clj after being returned by a given function. Can you elaborate on what problem you believe is occurring when you don't change it back to a vector?

Kris Calabio

unread,
Apr 15, 2014, 7:11:56 PM4/15/14
to clo...@googlegroups.com
In one of the callback functions in the defscreen I have a pipeline of functions that do something to the entities vector and return the resulting entities. I do something like this:

(->> entities
  (process-entities01)
  (process-entities02)
  (map (fn [entity]
          (->> entity
             (process-entity01)
             (process-entity02)))
  (process-entities03))

And that does not work, because each of the 'process-entities' functions are written in a way that expect a vector as input. Likewise, they each output a LazySeq unless I convert them back to a vector before returning. But I can't do that for the map function in the pipeline. But this does work:

(->> entities
  (process-entities01)
  vec
  (process-entities02)
   vec
  (map (fn [entity]
          (->> entity
             (process-entity01)
             (process-entity02)))
  vec
  (process-entities03)
  vec)

  

Zach Oakes

unread,
Apr 15, 2014, 7:37:36 PM4/15/14
to clo...@googlegroups.com
I see. If your code requires a vector, I think you will have to coerce the list each time as you are doing. Out of curiosity, what are you doing that makes this necessary? Are you using something like get-in?

Kris Calabio

unread,
Apr 15, 2014, 7:46:35 PM4/15/14
to clo...@googlegroups.com
I'm not exactly sure, but I think it's the use of 'conj'. My entities get out of order if they are not vectors.

All this might not matter though, because I've started rewriting my game from scratch since I'm using way too many mutable atoms than is necessary. James' screencast cleared a lot of things up for me, and I have a better understanding about how play-clj works.

But just to clarify, when exactly does play-clj convert the entities back into a vector? Is it when the callback functions of the screen return?

Colin Fleming

unread,
Apr 15, 2014, 9:08:10 PM4/15/14
to clo...@googlegroups.com
Note that you could use mapv, to perform the map but return a vector (filterv was also added at the same time).


You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.

Kris Calabio

unread,
Apr 15, 2014, 9:23:08 PM4/15/14
to clo...@googlegroups.com
Thanks, Colin! I wasn't aware of mapv.

kurofune

unread,
Apr 16, 2014, 11:40:09 AM4/16/14
to clo...@googlegroups.com
Jame's tutorial was right on the money and following it I was able to make a comparable version with Skeletor collecting magic gems in a desert. I am interested in leveraging Clojurescript and async for browser-game development, though, and while there is a core.async "Dots" game tutorial, it goes way over my head. If only there were a proper book that could teach Clojurescript, game development and async all at the same time! 
http://rigsomelight.com/2013/08/12/clojurescript-core-async-dots-game.html

I am exploring the game-query library for javascript and am reading a book about using jquery (can Clojurescript leverage this?) to make games. It's pretty sweet, but really polymorphic and un-Clojurey. By contrast, going through the Pedestal tutorial, it seems you can actually store the entire state of the game in an atom and just repeatedly swap! out that value, frame for frame, by matching it against a map representing changes to the DOM. This seems to make sense, but it feels like we are on a wild frontier with only a few examples to go by. If anyone else has experience with Pedestal, Clojurescript or core.async, as they pertain to game dev, I'd be stoked to hear about your experience.  

Jesse

edbond

unread,
Apr 16, 2014, 12:07:06 PM4/16/14
to clo...@googlegroups.com
Nice video, very cool.

Some notes:
- you can omit comma ',' in maps {:key value :another value}
- can omit contains? in filter:
user=> (filter :apple? [{:apple? true :x 6} {:apple? true :x 4} {:player? true :x 550}])
({:apple? true, :x 6} {:apple? true, :x 4})


Thanks again,
Eduard

James Trunk

unread,
Apr 16, 2014, 1:47:10 PM4/16/14
to clo...@googlegroups.com
> you can omit comma ',' in maps {:key value :another value}
In the interest of readability, I usually add commas when I have multiple key-value pairs on the same row.

> can omit contains? in filter:
Cool - thanks for the tip!

Also, thanks to everyone else for your comments. :-)

Cheers, 
James

amirteymuri

unread,
Oct 17, 2015, 7:32:44 PM10/17/15
to Clojure
Dear James,
is-pressed? can not be resolved for me. Is this a version matter? Is there still a is-pressed? function?
Greetings

William Swaney

unread,
Oct 18, 2015, 1:50:46 AM10/18/15
to Clojure
Really enjoyed this.  I've done a lot of LWJGL games in Java, but I'm going to try something in Clojure now.

Thanks,

Bill

Zach Oakes

unread,
Oct 18, 2015, 9:56:11 AM10/18/15
to Clojure
That function was renamed to `key-pressed?`.
Reply all
Reply to author
Forward
0 new messages