Pygame:如何多态地编写事件循环

我对pygame有点陌生,在试图回到它的时候,我发现了“用多态性替换你的条件”的建议。大多数 pygame 教程建议使用“for event in pygame.event.get()”循环,然后使用条件来确定是否发生了任何特定事件。


1:如何使用多态函数编写该代码 2:是否值得重构代码,或者只是将条件保持原样


以下是大多数教程推荐的内容


def gameloop():

"""

Stuff that comes before the event-loop

"""


for event in pygame.event.get():

    if event.type == pygame.QUIT:   # This is the conditional I want to remove

        quit_functions()

以下是我想如何做到这一点


from abc import ABC, abstractmethod

import pygame



def detect_event(event_class_name):

    for event in pygame.event.get():

        # This is how I want to get the event and then assign it a function

        event_class_name.determine_event(event)



# Above: I want to use this function to detect events and call their functions


# Below: This is how I want to assign functions to the events



class EventHandler(ABC):

    @staticmethod

    @abstractmethod

    def determine_event(event): pass



class Exit(EventHandler):

    @staticmethod

    # How do I identify this with the event-type "pygame.QUIT," for example

    def determine_event(event):

        pygame.quit()

        quit(0)


慕娘9325324
浏览 158回答 3
3回答

BIG阳

在 pygame 中,事件类型是枚举器常量。必须将此常量映射到相应的类。使用字典:def Exit(event):    # [...]def Keydown():    # [...]eventhandler = {pygame.QUIT: Exit, pygame.KEYDOWN: Keydown}当然,字典也可以动态生成甚至扩展。(例如:eventhandler[pygame.MOUSEBUTTONDOWN] = MouseDown)必须将事件委托给在事件处理程序中分配的相应操作:while True:    for event in pygame.event.get():        if event.type in eventhandler:            eventhandler[event.type](event)例:class EventHandler():    @staticmethod    def determine_event(event): passclass Exit(EventHandler):    @staticmethod    def determine_event(event):        pygame.quit()        quit(0)class Keydown(EventHandler):    @staticmethod    def determine_event(event):        print(event.key)eventhandler = {pygame.QUIT: Exit, pygame.KEYDOWN: Keydown}while True:    for event in pygame.event.get():        if event.type in eventhandler:            eventhandler[event.type].determine_event(event)对于更通用的方法,可以在列表中管理处理程序。因此,可以将多个操作关联到一个事件类型:def Exit(event):    # [...]def Keydown1():    # [...]def Keydown2():    # [...]eventhandler = {pygame.QUIT: [Exit], pygame.KEYDOWN: [Keydown1, Keydown2]}while True:    for event in pygame.event.get():        if event.type in eventhandler:            for target in eventhandler[event.type]:                target(event)例:class EventHandler():    targets = {}    @staticmethod    def add(type, event):        EventHandler.targets.setdefault(type, []).append(event)     @staticmethod    def notify(event):          if event.type in EventHandler.targets:            for target in EventHandler.targets[event.type]:                target.determine_event(event)    @staticmethod    def determine_event(event): passclass Exit(EventHandler):    @staticmethod    def determine_event(event):        pygame.quit()        quit(0)class KeydownPrint(EventHandler):    @staticmethod    def determine_event(event):        print(event.key)class KeydownAction(EventHandler):    @staticmethod    def determine_event(event):        print("action")EventHandler.add(pygame.QUIT, Exit)EventHandler.add(pygame.KEYDOWN, KeydownPrint)EventHandler.add(pygame.KEYDOWN, KeydownAction)while True:    for event in pygame.event.get():        EventHandler.notify(event)或者甚至是两个答案的组合(参见@AKX的答案):class EventHandler:    targets = {}    def register(type):        def decorator(fn):            EventHandler.targets.setdefault(type, []).append(fn)           return decorator    def notify(event):        fnl = EventHandler.targets[event.type] if event.type in EventHandler.targets else []          for fn in fnl:           fn(event)@EventHandler.register(pygame.QUIT)def onExit(event):    pygame.quit()    quit(0)@EventHandler.register(pygame.KEYDOWN)def keydownPrint(event):    print(event.key)@EventHandler.register(pygame.KEYDOWN)def keydownAction(event):    print("action")while True:    for event in pygame.event.get():        EventHandler.notify(event)

慕码人8056858

你不需要使用带有静态方法的类,并且基于Rabbid76的答案进行构建,一种(恕我直言)优雅的方法是使用装饰器在dict中注册每个事件处理程序:import pygameevent_handler_registry = {}def register_event_handler(event):    def decorator(fn):        event_handler_registry[event] = fn        return fn    return decorator@register_event_handler(pygame.QUIT)def on_exit(event):    pygame.quit()    quit(0)@register_event_handler(pygame.KEYDOWN)def on_key_down(event):    print(event.key)while True:    for event in pygame.event.get():        event_handler = event_handler_registry.get(event.type)        if event_handler:            event_handler(event)        else:            print(f"No event handler for {event}")

慕妹3242003

也许你可以用一个字符串使用eval():EVENTS = {pygame.QUIT : "quit_handler()" ,pygame.MOUSEBUTTONDOWN: "click_handler(event)"}for event in pygame.event.get:    eval (EVENTS.get(event.type))
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python