Enclojure

Yoo Min Cha
Mike Jannino
December 3, 2014

Overview

Enclojure is a 2D platformer game where you must escape the Enclojure you are trapped in. Players must avoid the zombies, collect coins, and reach the light at the end of the tunnel.

Screenshot

Concepts Demonstrated

  • Map, filter, and reduce on various displayed elements
  • Hash table/key lookup
  • Local bindings with let and passing lambda functions
  • Functional programming

External Technology and Libraries

We used a game development library for Clojure called play-clj. This was the most documented and most fleshed out library we could find; we looked into a library and API for Clojure and Unity2D, but it was too young a project for our deadline. Play-clj is a wrapper for a cross-platform library called libgdx, which is a well-supported game engine meant to speed up cross-platform releases by allowing games to be written with one code base and be released on many platforms. The documentation reflects the libgdx documentation extremely well, which was a huge factor in our choosing of this specific library. It took a while to get things working and we were heavily inspired by previous examples, but this was by far the strongest game engine library available for a functional language out there.

Favorite Lines of Code

Each partner should identify a favorite line of code, Scheme expression, or entire procedure written by himself / herself in the entire project, and explain what it does. E.g.:

  • Michael Jannino:
(defn get-x-velocity	
 ...
    npc?
    (if (> 5 (rand 100))
      (if (< 5 (rand 10))
        (* max-velocity-npc (- (rand-int 10)))
        ;else
        (* max-velocity-npc (rand-int 10)))
      0)
     :else x-velocity))

Within get-x-velocity, I developed an npc velocity algorithm without having to include a time library based on Yoo's existing velocity algorithm/zombie package. Gating any positive velocity behind (> 5 (rand 100)) ensures that any movement will occur infrequently; due to the way velocity works in our program, I then needed a fair way to determine how frequently the zombie moved left and right so I just split it up in half, 0-4 and 5-9.

  • Yoo Min Cha:
(defn move-zombie
  [{:keys [delta-time]} {:keys [x y can-jump?] :as entity}] 
  (let [x-velocity (u/get-x-velocity entity)                          
        y-velocity (+ (u/get-y-velocity entity) u/gravity) 
        x-change (* x-velocity delta-time)   
        y-change (* y-velocity delta-time)]  
    (if (or (not= 0 x-change) (not= 0 y-change))   TA
      (assoc entity                                    
             :x-velocity (u/decelerate x-velocity)                       
             :y-velocity (u/decelerate y-velocity)                
             :x-change x-change                                      
             :y-change y-change      
             :x (+ x x-change)           
             :y (+ y y-change)            
             .....)

I created a package for zombies being put throughout the world. My favorite part of this was adding functionality for movement in a way that is similar to the player class. I developed the backbone of Michael's movement algorithm and that is being called by move-zombie during the render time of each frame, aka 60 FPS. This pushes the zombie forward if there is a positive or negative x-velocity, and keeps him still if there wasn't.

Technology Used Block Diagram

Additional Remarks

This was extremely difficult to achieve, and we had to use a lot of modules and inspiration from previous work. Play-clj isn't very well fleshed out yet, and libGDX's documentation left something to be desired. We really struggled to get a working game out in time, but it was a great experience and thinking in a functional frame of mind really challenged each of us individually.