As far as the mutable state goes, yes, that's probably a better route,
at least for a simple game. However I would recommend against
"everything is a polygon" route. Once again, for a simple game, this
may be fine, but you're now making an assumption: "everything is a
polygon". What if you want a simple laser point-to-point entity? What
if you want a planet that is represented by a circle? What if you want
your ship to be a different color than the asteroids? By implementing
IRender, you get two side effects:

1) you can now de-couple the presentation of the object, from the code
that presents it
2) you can have very complex models (multiple polygons and colors)
without having complex render code
3) you can have entities represented by bitmaps, polygons, circles,
arcs, 3d meshes, etc.

This is what Clojure excels at...de-coupling, or as Rich put it in his
recent talk "Simple made Easy": don't assume things about your code.
Don't assume that all models will always fit into the concept of a
polygon...don't assume that you'll always want to represent your
models via Java2D.

Now, I'm not saying that your idea is bad for a simple game...but for
a larger project you may run into problems with this approach.

If you want a good way to think about this, I'd recommend trying to
design the engine to run on both Clojure and ClojureScript. Have it
support Java2D, SVG and Canvas front ends...even if you don't
implement anything but the JVM version, if you can at least show that
your engine would work on these other platforms without heavy
modifications (massive kodos if you can do this without any
modifications to the core engine at all) then I would say you have
reached a "higher plane of understanding" in when it comes to Clojure.

Timothy



On Mon, Oct 31, 2011 at 1:42 PM, Dennis Haupt <d.haup...@googlemail.com> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> no need for "IRender" since everything has a java.awt.polygon. i just
> draw it. in a sense, the polygon is my IRender and it's data is the
> implementation.
>
> i was thinking about using a simple type (:asteroid, :ship, :bullet)
> for each entity and pick an "advance"-function (input = complete old
> game state + one specific entity, output = new entity) depending on it.
> - ->
> {:asteroid advance-asteroid :ship advance-ship}
>
> i'd like to avoid mutable states as much as possible which means there
> will be one atom or agent for the whole world and a bufferedimage.
> other than that, i'd like to stay purely functional.
>
> Am 31.10.2011 19:03, schrieb Timothy Baldridge:
>>> In the OOP languages, entity systems seem to be all the rage. I
>>> suggest stealing ideas from there if you can.
>>
>>
>> In this same vein, I'd recommend thinking about the following
>> approach:
>>
>> First, read up on reify and protocols. Next, create protocols for
>> the main areas of your engine. Perhaps start with IRender and
>> IPhysicalEntity
>>
>> (defprotocol IRender (render [this]))
>>
>> (defprotocol IPhysicalEntity (update-position [this timespan]))
>>
>>
>>
>> then for the user ship, you can do something as simple as:
>>
>> (defn new-ship [x y] (let [pos (atom {:x x :y y})] (reify IRender
>> (render [this] (render-ship-model pos)) IPhysicalEntity
>> (update-position [this timespan] (swap! pos #(hash-map :x (inc (:x
>> %)) :y (:y %)))))))
>>
>> there's bound to be errors in the above code, but you get the
>> point. The thing I love about the above example is that we've
>> completely abstracted away the parts of this engine. We can have
>> entities that implement different protocols, we can have a separate
>> data structure for each and every entity, depending on its needs,
>> and everything is abstracted nicely. Static objects can just
>> implement IRender, and invisible objects can implement
>> IPhysicalEntity. Extend this to implement ICollideable (for
>> collision detection), and you have the makings of a very extensible
>> system.
>>
>> Timothy
>>
>
>
> - --
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v2.0.14 (MingW32)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
>
> iQIcBAEBAgAGBQJOruwPAAoJENRtux+h35aG0NsP/3CmDZHPnWjIYS2wULzTE4cp
> t9w+Citz3ZEfK5KmLDpy2dPB9l5bu2K4r7cwcgfmLLdZ90rcxgcan+WbtkffiPwd
> RZdB/E6IJrVPd2RvTt858VjNYvIeWxeU4XhpgS9EUBjiqRurQHrVrV/5bKFudRGn
> E8WO+wYv8kMGRxlB/3YjYxhxRtqy7Kevaf508J3Tq+U49TBnzpBYPvO8yX+HzRO2
> RNDVOr4S1ANf4OPn0l7AETxnEcvsI5D359JwSMGQ5whSk60kveZXTsMiD6nCFsQ0
> 2CD57iGlhHisNF78gnT78x+Qi1aMmkzWl2adfeXrW/zqZLXghLHaWamEy9dETATY
> TZxRlvYgqkp7Bwqh4+PHCB20uzRPTHex2bSw6SqY53XYiK8IWCG6iecwz0t/cuOt
> BxWRn+uTOlgX8FPZqX954eMmu1/5QjNRje5+i8kS7naRuXeZQLxwgZt6uFHN8jTS
> H4s2aso0eWyfimTQXgwQx1K+81LzbF+bDk2iI/6lk6sdbCoD1RkaIzp5qYJIxU4v
> zmFInbt+tPQFHtl8taEoUavN/Vc8//evcBDQpfdZ32JhzmZUHqGeJXEHQuVFojSr
> ursyF9oiCrWRlm4j63hWrYYdf6OUIzOYlzN2ehXGWt0Ek8TbV2J36XY8Jf6sPu3v
> 9LVXoiGlFmrjEtPKxog0
> =8KV+
> -----END PGP SIGNATURE-----
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@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+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en



-- 
“One of the main causes of the fall of the Roman Empire was
that–lacking zero–they had no way to indicate successful termination
of their C programs.”
(Robert Firth)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@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+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to