4
\$\begingroup\$

I am trying to implement a 2D fighting game in Clojure both for fun and learning.

Since the characters in a fighter game are essentially state machines, I constructed the following code:

(defrecord Frames [frames id])

where "frames" refer to the actual datas (hitboxes texture-names and etc) and "id" will be an atom referencing the "frames" data representing the current frame the character is in.

so I will initialize a frame like this (used :a :b :c just for testing):

(def f (Frames. [:a :b :c :d :e :f :g] (atom 0)))

and will retrieve the current frame by this:

(defn get-current-frame [frames] (nth (:frames frames) @(:id frames)))

and update by:

(defn update-current-frame [frames active] (reset! (:id frames) active))

and it works fine:

(def f (Frames. [:a :b :c :d :e :f :g] (atom 0)))
(update-current-frame f 3)
(get-current-frame f) ;; => :d

Obviously it works, but I am extremely in doubt that this is a good practice.

Due to my poor knowledge with Clojure, I am here asking

  1. Is using atom referencing a vector the best way for representing simple states?
  2. Should I use this kind of data structure for implementing fighting game frames?
  3. If ignoring data structures, am I defining the functions (get-current-frame) and (get-current-frame) in an idiomatic way?
\$\endgroup\$
3
\$\begingroup\$

No, you probably don't want to store an atom in the record. You probably want:

(defn get-current-frame [frame]
  (nth (:frames frame) (:id frame)))

(defn update-current-frame [frame active]
  (assoc frame :id active))

(def f (Frames. [:a :b :c :d :e :f :g] 0))

Then

> (get-current-frame f)
:a
> (get-current-frame (update-current-frame f 4))
:e

If you feel the need to have an atom:

brain.core> (def f (atom (Frames. [:a :b :c :d :e :f :g] 0)))
#'brain.core/f
brain.core> (get-current-frame @f)
:a
brain.core> (swap! f update-current-frame 4)
#brain.core.Frames{:frames [:a :b :c :d :e :f :g], :id 4}
brain.core> (get-current-frame @f)
:e
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.