我正在使用 Pygame 组合一个组件实体游戏引擎,并且我正在使用自定义 Pygame Userevents 作为我的消息传递系统(引擎中不同子系统可以在不真正了解彼此的情况下进行通信的方式)。
消息传递系统通过将事件类型列表附加到系统来工作。在 Engine 类(管理系统)的每个更新周期中,将该系统的事件过滤列表传递给系统,以便它可以对这些事件采取行动。
我有一个组件工厂,它创建组件对象,将对对象的引用附加到事件,然后发布事件。在我正在测试的有问题的代码中,我ADDINPUTCOMPONENT
在创建InputComponent
对象后发布了一个事件(自定义 Pygame Userevent)。
在我的测试代码中,您可以看到我创建了一个输入系统,将其安装在具有正确事件类型的引擎上,然后创建一个输入组件,它应该触发事件。
我已验证发布事件的代码正在发生。我还验证了引擎将事件正确绑定到输入系统。
您可以在我的更新函数中看到InputSystem
,我应该处理从工厂发布的事件,但是我从未在 .返回的事件列表中看到该事件pygame.event.get()
。
引擎
class PygameEngine(object):
def __init__(self, systems=None):
self.systems = list() if systems is None else systems
def install_system(self, system, event_types=None):
new_system = SystemEntity(system, event_types)
self.systems.append(new_system)
def update(self, time, events):
for i in self.systems:
i.system.update(time,
filter(lambda x: x.type in i.event_types, events))
系统
class InputSystem(object):
def __init__(self, components=None):
# a map of lists, map keys are input devices, list items are
# components mapped to that device
self.components = defaultdict(list) if components is None else components
def update(self, time, events=None):
for device, components in self.components.items():
for comp in components:
comp.last_state = copy.deepcopy(comp.state)
print comp.state
for event in events:
# system events
if event.type == ADDINPUTCOMPONENT:
self.components[event.device].append(event.component)
print "Added new input component"
elif event.type == REMOVEINPUTCOMPONENT:
self.components[event.device].remove(event.component)
elif event.type == UPDATEBINDINGS:
pass
工厂
def create_component(self, type, **props):
component = None
# InputComponent
if type == 'input':
device = props['device']
entity_id = props['entity_id']
# TODO: convert bindings to a bidict
bindings = dict() if not 'bindings' in props else props['bindings']
component = inputs.InputComponent(entity_id, bindings)
new_event = event.Event(ADDINPUTCOMPONENT, device=device, component=component)
event.post(new_event)
测试代码
inp = inputs.InputSystem()
eng.install_system(inp, (ADDINPUTCOMPONENT, REMOVEINPUTCOMPONENT,
UPDATEBINDINGS, pygame.KEYDOWN,
pygame.KEYUP, pygame.JOYBUTTONDOWN,
pygame.JOYBUTTONUP, pygame.MOUSEBUTTONDOWN,
pygame.MOUSEBUTTONUP))
t_entity = factory.create_entity()
t_bindings = {
'up': pygame.K_UP,
'down': pygame.K_DOWN,
'left': pygame.K_LEFT,
'right': pygame.K_RIGHT
}
t_inp_component = factory.create_component('input', device=-1,
entity_id=t_entity.entity_id,
bindings=t_bindings)
游戏循环
while not(done):
last_time = current_time
current_time = pygame.time.get_ticks()
time_since_last_update = current_time - last_time
events = pygame.event.get()
eng.update(time_since_last_update, events)