HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Using atom to reference state in Clojure

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
referenceclojureusingstateatom

Problem

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

  • Is using atom referencing a vector the best way for representing simple states?



  • Should I use this kind of data structure for implementing fighting game frames?



  • If ignoring data structures, am I defining the functions (get-current-frame) and (get-current-frame) in an idiomatic way?

Solution

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

Context

StackExchange Code Review Q#79865, answer score: 3

Revisions (0)

No revisions yet.