Doing the collision work only got me a glimpse into the map implementation as a whole. Since then, while working on saving/loading maps, I have got a better idea how everything fits together and am finding some flaws that should probably be corrected now.
First, of all here's a picture of the fundamental parts the map consists of (objects and characters ... later we'll throw items into the mix too): frames --> animations --> sprites \ / objects | | X shapes --> models / \ characters / position / Basically, an object consists of a sprite and a model. A character has additional location (and velocity) information. That means, each character instance has a distinct state. This is different for objects, where one instance usually exists at different locations of the map (and only the map knows about those locations). This is quite efficient, but it also has severe restrictions: All instances of a certain objects will have the same state, i.e. they will display the same animation. That may be okay for most objects, but there are some exceptions: * Doors or chests that can be opened/closed, light sources that could be lit/dimmed, etc. ... . All those need to be individual objects whose state needs to be changed without affecting any other instance. * In a similar manner, it will not be possible to use a sprite to group multiple variations of essentially the same object. Say a bookshelf with or without books or other items, a tree with or without leaves, with snow on it or with the wind moving its twigs. (Whether we want to use this sort of grouping remains a different issue) I haven't yet found any good solution for this issue, though. I don't want to lose the efficiency of the current implementation that works well for the biggest part of stuff we'll have on the map. One thought is to maybe implement those objects as items or to introduce a different kind of map object. The general theme seems to be that those objects can be interacted with (doors, push-buttons, ...), whereas the current type of object is meant for static scenery only. Then there is another issue. The original (and IMHO quite nice) idea of Alex had been to divide objects into their graphical and internal representation. Hence we have sprites and models, as can be seen above. All the map needs to work are the models, so we have the chance to load the whole game world and simulate what is going on without using much memory (whether we can actually have a lot of NPC/creature schedules running simultaneously is again a different matter, of course). Then, for those areas visible in a map view, we also load the graphics to actually display that area to the user. Great stuff, but I am not so sure if the implementation is all that great. It uses multiple inheritance, which can be a bit of a problem at times ... for example I couldn't get the overloaded draw methods of character_with_gfx/object_with_gfx to resolve correctly when only having a placeable_gfx, so the rendering code needs some ugly kludges right now: switch ((*it).obj->type ()) { case world::CHARACTER: ((world::character_with_gfx *) (*it).obj)->draw (pos_x, pos_y, &da, target); break; case world::OBJECT: ((world::object_with_gfx *) (*it).obj)->draw (pos_x, pos_y, &da, target); break; } That's not OOP at all! And means more work once we add in items, for example. Instead, the following should work: ((world::placeable_gfx *) (*it).obj)->draw (pos_x, pos_y, &da, target); Also, the part where it all comes together (area::thing_manager) does not easily mix objects with and without gfx and its not really possible to load the gfx of an object once it becomes required by a map view (or unload it again later). So all that screams for a bit of a redesign. Maybe something subtle is enough to get rid of these issues; I only recently started thinking more about all this. A first idea would be to have draw methods in all objects, not just those with gfx. Those without gfx could just render wireframes of their model (something that's right now implemented as a draw_border method in objects with gfx.) That should help get rid of the switch statement required so far. There's not much of an idea about how to load/unload gfx at runtime though. I only see a couple possible implementations I do not like much :-). * Only have one type of object, and just don't load the sprite unless requested. But that means a lot of ifs and elses inside that object. Not nice. * Replace the pure object with its gfx counterpart (and vice versa). But that requires copying (or reloading) of the model (and in case of characters) location data. Not efficient. This seems to indicate that it's no good idea to let the gfx object inherit from the non-gfx object (as in the current implementation). A proposal that comes to my mind would be to work with a delegate, where a map object (a placeable) has a renderer component that does the drawing. For objects without gfx, we could have a default, static renderer that gets the model from the object and draws the wireframe. No allocations/deallocations of that non-gfx renderer, and no ifs/elses either. For objects with gfx, we could do the same and have one class that gets the sprite from placeable, looks it up in the animation cache and draws it. More efficient seems to be to have individual instances that hold on to the sprite instead, though. Only few allocations/deallocations vs. numerous cache lookups every frame. The map view could handle setting the proper renderers as objects come into or go out of view. Another idea could be to have a default empty renderer, that only waits for the first call to its draw method to instantiate the real render which loads the sprite and draws it. The cleanup would still have to be done by the mapview though (at least I can't think of anything else right now). For special cases (debugging, map editor) we could use special renderers that draw the wireframe or other helpful indicators. (Basically, it has to be possible to specify the renderer class that will get instantiated.) This should get rid of most (if not all) the multiple inheritance and seems a way to untangle the current mess between objects with and without gfx. Kai _______________________________________________ Adonthell-devel mailing list Adonthell-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/adonthell-devel