发布的事件没有出现pygame.event.get()

时间:2013-08-08 05:37:13

标签: python sdl pygame

我正在使用Pygame组建一个组件实体游戏引擎,我正在使用自定义Pygame Userevents作为我的消息传递系统(引擎中的不同子系统可以在没有彼此真实知识的情况下进行通信的方式)。

消息传递系统通过将事件类型列表附加到系统来工作。在Engine类(管理系统)的每个更新周期中,将系统的已过滤事件列表传递给系统,以便它可以对这些事件起作用。

我有一个组件工厂,它创建组件对象,将对象的引用附加到事件,然后发布事件。在我正在测试的有问题的代码中,我在创建ADDINPUTCOMPONENT对象后发布了InputComponent事件(自定义Pygame Userevent)。

在我的测试代码中,您可以看到我创建了一个输入系统,使用正确的事件类型将其安装在引擎上,然后创建一个输入组件,该组件应触发事件。

我已经确认发布该事件的代码正在发生。我还验证了引擎正确地将事件绑定到输入系统。

您可以在我的更新函数中看到InputSystem,我应该处理从工厂发布的事件,但是我从未在pygame.event.get()返回的事件列表中看到该事件。 / p>

引擎

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)

1 个答案:

答案 0 :(得分:3)

好吧,我发现了问题所在。来自pygame.event的文档:

  

所有事件都有类型标识符。此事件类型介于两者之间   NOEVENT和NUMEVENTS的值。所有用户定义的事件都可以拥有   USEREVENT或更高的值。建议确保您的活动   id's遵循这个系统。

http://www.pygame.org/docs/ref/event.html

NOEVENT是值0的“常量”,NUMEVENTS是32,USEREVENT是24.发布类型值为32或更大的事件会导致pygame基本上丢失事件,它出现了。这意味着您只有8个可能的自定义事件值(NUMEVENTS - USEREVENT)。

我没有看到发布的事件是39.它的定义如下:

ADDINPUTCOMPONENT = USEREVENT + 15

我尝试将其更改为USEREVENT + 1并且有效。

基本上,如果您想拥有超过8种类型的自定义事件,您只需要为发布的事件添加一个属性,以便您区分事件类型。

此外,此限制似乎从SDL继续: http://www.libsdl.org/docs/html/sdluserevent.html