Pepijn de Vos wrote:
> Hey,

Hi,

Just a couple of remarks:

> I'm writing some Clojure game stuff, and I'm having trouble coming up with a 
> sensible model for the game objects.
>
> The basic idea is that I have a bunch of objects that represent the game, and 
> call 'act' on them, supplying the current world to get their next state.

That doesn't sound too unreasonable as a starting point.

> The objects have a few properties, like an ID, a position, a sprite and any 
> extra information an object might need. I also want to make it implement 
> java.awt.Shape for collision detection using an internal Rectangle.

This sounds like you're trying to cram too much stuff into a single
object. For example, java.awt.Rectangle already has an intersects()
method, so:

1. you don't need to implement Shape just to do rectangle collision.
2. you also don't need to implement Rectangle, as long as your objects
can provide a rectangle in some way.

> To write a game, one must define new types of objects, and implement their 
> 'act' function.
>
> My initial thought was to use a record and an actor protocol.
>
> The first problem with this is that the properties of the record are not 
> embedded in the actor protocol, so there might be actors that blow up 
> rendering by having no sprite for example.
>
> Another problem is that subclasses would need to implement Shape themselves.

See point 2 above. If you don't require implementing all the stuff in
the same object, the problem goes away.

> Yet another one is that updating the position of a record via assoc does not 
> update the Rectangle.

Again, fixed by having the object provide the Rectangle (via a
multimethod, or protocol method or something similar).

> Then I considered using a multimethod on type, which can use the :type 
> metadata. This leads to a model where no subclasses of the game object are 
> made, but merely given a different type on their meta.

Sounds reasonable to me.

> To integrate the Rectangle with the object, I considered using a type 
> instead, and use classic getters and setters. This has the advantage that I 
> can manage the Rectangle and that the properties of the object are embedded 
> in the protocol.
>
> Problem #1 here is that I lose the ability to store arbitrary data on the 
> object. This can be circumvented by using the extension model. But having now 
> defined even more methods, I place an even larger implementation burden on 
> the child type.
>
> What would be a clean way to do this?

Split up the stuff that doesn't NEED to be "in" the same object. This
is a typical pitfall in OO design; when you can implement
functionality with aggregation, you probably should use aggregation
instead of inheritance.

For instance: in your initial outline for the "actor" protocol, you
basically say that all it does is change the current game state to a
new state. That sounds good. But that also means that actors don't
inherently have to have sprites, or shapes, or even collision
detection. That's all external to the core idea. I can also easily
imagine game objects that don't necessarily need to change game state,
but where you do still need to have shapes and collision detection -
like walls. So to me it sounds like you're talking about two different
concepts that are probably complicating your design when you force
them to together.

Hope that helped,
Joost.

-- 
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