Я разрабатываю игру в стиле roguelike на Python и использую урезанную модель Entity / Component - без всех Систем.Компоненты просто упрощают добавление и удаление атрибутов игровых объектов.У меня есть метод getattr в Entity, чтобы сделать его действительно удобным для доступа к значениям компонентов напрямую из Entity, но я думаю, что это создает проблемы, поскольку он достигает максимальной глубины рекурсии при попытке перезагрузить сохраненную полку.
Как сохранить удобство, не мешая процессу сохранения?
Класс Component действительно прост:
class Component(object):
def __init__(self, entity=None):
self.entity = entity
А вот мой класс Entity:
import uuid
class Entity(object):
# A generic game object: player, monster, item, stairs, etc.
def __init__(self, *components):
# Set a unique uuid
self._uuid = uuid.uuid4()
# Add the supplied components.
self.components = {}
if components: # refactor this to *components when all the attributes are components
for component in components:
self.set(component)
@property
def uuid(self):
"""Property to access the Entity's uuid, exists to prevent uuid modification."""
return self._uuid
def find_component(self, name):
# Searches through the Entity's components to match the given value. If
# found, it returns the Component that manages that value, otherwise returns None.
for comp in self.components.values():
if hasattr(comp, name):
return comp
return None
def __getattr__(self, name):
comp = self.find_component(name)
if comp:
return getattr(comp, name)
raise AttributeError("Entity has no component with attribute {}".format(name))
def set(self, component):
"""Sets a new Component."""
key = type(component)
self.components[key] = component
def get(self, component):
""" Returns the specified Component, if it exists, otherwise returns None."""
return self.components.get(component, None)
def has(self, component):
""" Returns True if this Entity contains the specified Component, otherwise returns False."""
return self.get(component) is not None
def rm(self, component):
""" Removes a Component."""
return self.components.pop(component, None)