代码之家  ›  专栏  ›  技术社区  ›  Ethanol

如何修复pygame事件循环的缓慢性?

  •  1
  • Ethanol  · 技术社区  · 6 年前

    我正在为游戏创建一个button类,我正在使用pygame事件循环来检测鼠标点击(特别是当鼠标释放时)(我听说使用 pygame.mousemget_pressed()[0] )但是,事件循环似乎很慢,单击时没有响应和执行按钮功能。我想这可能是因为我是如何在类中创建事件循环的,但我不确定。下面是我的代码示例:

    class Button:
        """A Button class, built for all kinds of purposes"""
        def __init__(self, window, rect, message, off_color, on_color, message_color, message_font_size):
            pass # just a bunch of variables that use the parameters given
    
        def in_button(self):  
            mouse_pos = pygame.mouse.get_pos()
            if pygame.Rect(self.rect).collidepoint(mouse_pos):
                return True
    
        def clicked(self):
            if self.in_button():
    
                pygame.event.pump() 
                for e in pygame.event.get():
                    if e.type == pygame.MOUSEBUTTONUP:
                        return True
    # I proceed to create 5 instances using this class.
    

    我删除了代码中一些不必要的方法信息。如果你还需要什么,请帮助我。

    1 回复  |  直到 6 年前
        1
  •  1
  •   skrx    6 年前

    您必须实现 clicked 方法,因为应用程序中应该只有一个事件循环,而不是每个按钮实例中都有一个。 pygame.event.get() 清空事件队列,因此每帧多次调用它会导致问题。

    我建议将事件传递给按钮。在这个(非常简单的)示例中,我传递 pygame.MOUSEBUTTONDOWN 事件到 单击 方法,然后检查 event.pos 事件的(鼠标位置)与矩形碰撞。如果它返回 True ,我在main函数的事件循环中执行一些操作。

    import pygame as pg
    
    
    class Button:
    
        def __init__(self, pos):
            self.image = pg.Surface((100, 40))
            self.image.fill(pg.Color('dodgerblue1'))
            self.rect = self.image.get_rect(center=pos)
    
        def clicked(self, event):
            """Check if the user clicked the button."""
            # pygame.MOUSE* events have an `event.pos` attribute, the mouse
            # position. You can use `pygame.mouse.get_pos()` as well.
            return self.rect.collidepoint(event.pos)
    
    
    def main():
        screen = pg.display.set_mode((640, 480))
        clock = pg.time.Clock()
        button = Button((100, 60))
        number = 0
    
        done = False
    
        while not done:
            for event in pg.event.get():
                if event.type == pg.QUIT:
                    done = True
                elif event.type == pg.MOUSEBUTTONDOWN:
                    # Pass the MOUSEBUTTONDOWN event to the buttons.
                    if button.clicked(event):
                        number += 1  # Do something.
                        print('clicked', number)
    
            screen.fill((30, 30, 30))
            screen.blit(button.image, button.rect)
    
            pg.display.flip()
            clock.tick(60)
    
    
    if __name__ == '__main__':
        pg.init()
        main()
        pg.quit()
    

    如果希望按钮具有多个图像,可以使用类似于button类的内容 here (the first addendum) 或者为pygame搜索更复杂的按钮类。