I've got a single moving square and a small pile of Clojure written so far, but now what I want to do is have a collection of moving squares because no game of Space Invaders is complete without aliens, and last I checked there was more than one of them.
Well, if I want lots of squares I'm going to have to look at some means of representing collections in Clojure and my searches take me to Sequences
To create a sequence, I can do something like this
(defn createSeq []
(for [x [0 1 2 3]]
x
)
)
Which returns me a sequence containing 0 1 2 3, an important point here is (at least I think), is that this sequence is lazy, it has not been executed yet.
Now, my collection of invaders will actually be 2D, so what I can actually do is
(defn createSeq []
(for [x [0 1 2 3] y [0 1 2 3]]
[x y]
)
)
Which returns me a sequence containing lots of [x y] pairs, so [0 0] [0 1] [0 2] etc.
Of course, there are functions for me here, so I can make a range
(defn createSeq []
(for [x (range 0 100 10)
y (range 0 100 10)]
[x y]
)
)
Pretty nifty if I do say so myself, so what I can start with if I want to draw a grid of yellow squares is something like
(defn initState []
(for [x (range 0 100 10)
y (range 0 100 10)]
[x y]
)
)
And I can call my initial tick method, passing in this state
(defn ^:export init []
(tick (initState))
)
And then loop through this
(defn tick [enemies]
(let [ctx (context)]
(clearScreen ctx)
(doseq [[x y] enemies] (drawSquare ctx x y 5 5))
(js/setTimeout (fn []
(tick enemies)
) 33 )
)
)
Note that I'm able to expand the content of this sequence as part of the doseq call
(doseq [[x y] enemies] (drawSquare ctx x y 5 5))
Gotta like that at least a little bit!
About this doseq, this doseq is explicitly created to allow for side effects, I could have done
(for [[x y] enemies] (drawSquare ctx x y 5 5))
But nothing would happen because this is lazy too - had my head scratching for a while on that one...
2020 © Rob Ashton. ALL Rights Reserved.