亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Pygame:如何多態地編寫事件循環

Pygame:如何多態地編寫事件循環

慕娘9325324 2022-08-11 17:07:38
我對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, abstractmethodimport pygamedef 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 eventsclass EventHandler(ABC):    @staticmethod    @abstractmethod    def determine_event(event): passclass Exit(EventHandler):    @staticmethod    # How do I identify this with the event-type "pygame.QUIT," for example    def determine_event(event):        pygame.quit()        quit(0)
查看完整描述

3 回答

?
BIG陽

TA貢獻1859條經驗 獲得超6個贊

在 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): pass


class 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): pass


class 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)


查看完整回答
反對 回復 2022-08-11
?
慕碼人8056858

TA貢獻1803條經驗 獲得超6個贊

你不需要使用帶有靜態方法的類,并且基于Rabbid76的答案進行構建,一種(恕我直言)優雅的方法是使用裝飾器在dict中注冊每個事件處理程序:


import pygame


event_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}")


查看完整回答
反對 回復 2022-08-11
?
慕妹3242003

TA貢獻1824條經驗 獲得超6個贊

也許你可以用一個字符串使用eval():


EVENTS = {

pygame.QUIT : "quit_handler()" ,

pygame.MOUSEBUTTONDOWN: "click_handler(event)"

}


for event in pygame.event.get:

    eval (EVENTS.get(event.type))


查看完整回答
反對 回復 2022-08-11
  • 3 回答
  • 0 關注
  • 127 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號