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