Hi guys,
I’m trying to develop an abstraction layer on the top of Panda 3D Python code, similar to Crystal Space (CEL), Nebula 3 or Unreal Engine 3 (i think, but i’m not sure) ones.
The idea behind this is very simple: instead of heavy use of inheritance, is a best choice to organize logic entities with an “aggregation” approach.
In this approach there are 3 types of object:
-
Entity: is an high level logic entity (like a player, a forest tree, a weapon or a car). It has many properties and an associated behaviour code (the game logic).
-
Property: is a set of functionalities the owner can use. A property is an access point to Panda 3D features. An example of “property” can be a “sound source”, an “input handler”, a “3D mesh” and so on. Each property talks with other properties (of the same entity or of another one) with messages/events.
-
Message/Event: the standard event message system of Panda 3D.
For example, in a race game, we could describe the game logic as:
entity: Player
properties: mesh3d, physics object, camera handler, input handler, etc.
entity: Track
properties: mesh3d, physics world, etc.
entity: Semaphore
properties: mesh3d, trigger, etc.
entity: Opponent
properties: mesh3d, physics object, IA actor, etc.
This solution is very smart and modular, with an high level of reuse.
I’ve already implemented base classes (Entity and Property) and some specialized properties:
- mesh3D
- camera_handler
- input_handler
- physics_world
- physics_object
These are the sources of Entity and Property base classes:
class Entity(object):
def __init__(self, *args, **kwargs):
self.__properties = {}
def attach_property(self, property):
property.owner = self
self.__properties[property.name] = property
def detach_property(self, property):
key = property.name
self.__properties[key].destroy()
del self.__properties[key]
def get_property(self, name):
return self.__properties[name]
def has_property(self, name):
return name in self.__properties.keys()
from direct.showbase import DirectObject
from direct.showbase.MessengerGlobal import messenger
class Property(object, DirectObject.DirectObject):
def __init__(self, *args, **kwargs):
DirectObject.DirectObject.__init__(self)
self.owner = None
self.name = self.__module__.rpartition('.')[2]
def destroy(self):
self.owner = None
self.ignoreAll()
@classmethod
def event_name_from(cls, prop, suffix):
return '%s.%s' % (prop.name, suffix)
@classmethod
def send_message(cls, name, args=[]):
messenger.send(name, args)
…So, what do you think about this solution?