Python 如何创建两个单独的pygame显示?如果我能';t、 如何创建pygame的两个实例?

Python 如何创建两个单独的pygame显示?如果我能';t、 如何创建pygame的两个实例?,python,python-3.x,pygame,Python,Python 3.x,Pygame,我想创建两个独立的pygame显示器。我知道用pygame的一个实例是不可能做到这一点的。我想知道如何/是否可以实施以下任一解决方案: 创建一个单独的模块来运行使用单独显示的函数。这将使用一个独立于我的主代码的pygame实例,因此能够运行吗 使用子shell从脚本内部使用一些特殊参数运行脚本,解析sys.argv,然后在第二个实例中运行该函数。如何确保跨平台兼容性 还有别的吗 我不在乎它的效率有多低,有多丑,等等。结果就是这个程序。我只是想让这一切顺利 重要的是,主代码必须与相关代码通信(即更

我想创建两个独立的
pygame
显示器。我知道用pygame的一个实例是不可能做到这一点的。我想知道如何/是否可以实施以下任一解决方案:

  • 创建一个单独的模块来运行使用单独显示的函数。这将使用一个独立于我的主代码的pygame实例,因此能够运行吗
  • 使用子shell从脚本内部使用一些特殊参数运行脚本,解析sys.argv,然后在第二个实例中运行该函数。如何确保跨平台兼容性
  • 还有别的吗
  • 我不在乎它的效率有多低,有多丑,等等。结果就是这个程序。我只是想让这一切顺利

    重要的是,主代码必须与相关代码通信(即更改下面
    extraDisplayManager
    中的一些变量),但我计划使用pickle保存到文件并以这种方式通信。不过,我已经对相关部分进行了多线程处理,因此缺乏同步性并不重要

    我的代码相当长且复杂,因此我不会在这里发布,但相关部分的要点是:

    def主代码(*someargs):
    d=pygame.display.set_模式(尺寸)
    如果相关参数:
    extraDisplayManager=RelevantClass(*someotherargs)
    threading.Thread(目标=extraDisplayManager.relevantFunction,
    daemon=True)
    ...
    类别相关类别:
    def相关函数(self,*someotherargs):
    self.d=pygame.display.set_模式(维度)
    尽管如此:
    updateDisplay(someargs)#这是我的主代码的一部分,但是
    #是独立的,因此我可以将其复制到新模块
    
    如果您能回答我的一些问题或给我看一些相关的文档,我将不胜感激。

    如果您真的(真的)需要两个显示器,您可以使用python的模块生成一个进程,并使用a在两个进程之间传递数据

    下面是我拼凑的一个例子:

    import pygame
    import pygame.freetype
    import random
    import multiprocessing as mp
    
    # a simple class that renders a button
    # if you press it, it calls a callback function
    class Button(pygame.sprite.Sprite):
        def __init__(self, callback, *grps):
            super().__init__(*grps)
            self.image = pygame.Surface((200, 200))
            self.image.set_colorkey((1,2,3))
            self.image.fill((1,2,3))
            pygame.draw.circle(self.image, pygame.Color('red'), (100, 100), 50)
            self.rect = self.image.get_rect(center=(300, 240))
            self.callback = callback
    
        def update(self, events, dt):
            for e in events:
                if e.type == pygame.MOUSEBUTTONDOWN:
                    if (pygame.Vector2(e.pos) - pygame.Vector2(self.rect.center)).length() <= 50:
                        pygame.draw.circle(self.image, pygame.Color('darkred'), (100, 100), 50)
                        self.callback()
                if e.type == pygame.MOUSEBUTTONUP:
                        pygame.draw.circle(self.image, pygame.Color('red'), (100, 100), 50)
    
    # a simple class that display a text for 1 second anywhere
    class Message(pygame.sprite.Sprite):
        def __init__(self, screen_rect, text, font, *grps):
            super().__init__(*grps)
            self.image = pygame.Surface((300, 100))
            self.image.set_colorkey((1,2,3))
            self.image.fill((1,2,3))
            self.rect = self.image.get_rect(center=(random.randint(0, screen_rect.width), 
                                                    random.randint(0, screen_rect.height)))
            font.render_to(self.image, (5, 5), text)
            self.timeout = 1000
            self.rect.clamp_ip(screen_rect)
    
        def update(self, events, dt):
            if self.timeout > 0:
                self.timeout = max(self.timeout - dt, 0)
            else:
                self.kill()
    
    # Since we start multiple processes, let's create a mainloop function
    # that can be used by all processes. We pass a logic_init_func-function
    # that can do some initialisation and returns a callback function itself.
    # That callback function is called before all the events are handled.
    def mainloop(logic_init_func, q):
        import pygame
        import pygame.freetype
        pygame.init()
        screen = pygame.display.set_mode((600, 480))
        screen_rect = screen.get_rect()
        clock = pygame.time.Clock()
        dt = 0
        sprites_grp = pygame.sprite.Group()
    
        callback = logic_init_func(screen, sprites_grp, q)
    
        while True:
            events = pygame.event.get()
            callback(events)
    
            for e in events:
                if e.type == pygame.QUIT:
                    return
    
            sprites_grp.update(events, dt)
            screen.fill((80, 80, 80))
            sprites_grp.draw(screen)
            pygame.display.flip()
            dt = clock.tick(60)
    
    # The main game function is returned by this function.
    # We need a reference to the slave process so we can terminate it when
    # we want to exit the game.
    def game(slave):
        def game_func(screen, sprites_grp, q):
    
            # This initializes the game.
            # A bunch of words, and one of it is randomly choosen to be
            # put into the queue once the button is pressed
            words = ('Ouch!', 'Hey!', 'NOT AGAIN!', 'that hurts...', 'STOP IT')
    
            def trigger():
                q.put_nowait(random.choice(words))
    
            Button(trigger, sprites_grp)
    
            def callback(events):
                # in the mainloop, we check for the QUIT event
                # and kill the slave process if we want to exit
                for e in events:
                    if e.type == pygame.QUIT:
                        slave.terminate()
                        slave.join()
    
            return callback
    
        return game_func
    
    def second_display(screen, sprites_grp, q):
    
        # we create font before the mainloop
        font = pygame.freetype.SysFont(None, 48)
    
        def callback(events):
            try:
                # if there's a message in the queue, we display it
                word = q.get_nowait()
                Message(screen.get_rect(), word, font, sprites_grp)
            except:
                pass
    
        return callback
    
    def main():
        # we use the spawn method to create the other process
        # so it will use the same method on each OS.
        # Otherwise, fork will be used on Linux instead of spawn
        mp.set_start_method('spawn')
        q = mp.Queue()
    
        slave = mp.Process(target=mainloop, args=(second_display, q))
        slave.start()
    
        mainloop(game(slave), q)
    
    
    if __name__ == '__main__':
        main()
    
    导入pygame
    导入pygame.freetype
    随机输入
    将多处理作为mp导入
    #呈现按钮的简单类
    #如果你按下它,它会调用一个回调函数
    类按钮(pygame.sprite.sprite):
    定义初始化(自我、回调、*GRP):
    超级()
    self.image=pygame.Surface((200200))
    self.image.set_颜色键((1,2,3))
    自映像填充((1,2,3))
    pygame.draw.circle(self.image,pygame.Color('red'),(100100),50)
    self.rect=self.image.get_rect(中心=(300240))
    self.callback=回调
    def更新(自身、事件、dt):
    对于事件中的e:
    如果e.type==pygame.MOUSEBUTTONDOWN:
    if(pygame.Vector2(e.pos)-pygame.Vector2(self.rect.center)).length()0:
    self.timeout=max(self.timeout-dt,0)
    其他:
    self.kill()
    #因为我们启动了多个进程,所以让我们创建一个mainloop函数
    #所有进程都可以使用它。我们传递一个逻辑函数
    #它可以进行一些初始化并返回回调函数本身。
    #在处理所有事件之前调用该回调函数。
    def主循环(逻辑初始化函数,q):
    导入pygame
    导入pygame.freetype
    pygame.init()
    screen=pygame.display.set_模式((600480))
    screen\u rect=screen.get\u rect()
    clock=pygame.time.clock()
    dt=0
    sprites\u grp=pygame.sprite.Group()
    callback=logic\u init\u func(屏幕,精灵组,q)
    尽管如此:
    events=pygame.event.get()
    回调(事件)
    对于事件中的e:
    如果e.type==pygame.QUIT:
    返回
    精灵组更新(事件,dt)
    屏幕填充((80,80,80))
    精灵组绘制(屏幕)
    pygame.display.flip()
    dt=时钟滴答声(60)
    #此函数返回主游戏函数。
    #我们需要一个对从进程的引用,以便在需要时终止它
    #我们想退出比赛。
    def游戏(从机):
    def游戏功能(屏幕、精灵、q):
    #这将初始化游戏。
    #一堆单词,其中一个是随机选择的
    #按下按钮后立即进入队列
    words=(‘哎哟!’、‘嘿!’、‘别再来了!’、‘好痛……’、‘住手’)
    def触发器():
    q、 put_nowait(随机选择(单词))
    按钮(触发器、精灵\u grp)
    def回调(事件):
    #在主循环中,我们检查退出事件
    #如果我们想退出的话,就杀了从进程
    对于事件中的e:
    如果e.type==pygame.QUIT:
    slave.terminate()
    slave.join()
    返回回调
    返回博弈函数
    def第二屏幕(屏幕、精灵组、q):
    #我们在主循环之前创建字体
    font=pygame.freetype.SysFont(无,48)
    def回调(事件):
    尝试:
    #如果队列中有消息,我们将显示它
    word=q.get_nowait()
    消息(screen.get_rect()、单词、字体、精灵)
    除:
    通过
    返回回调
    def main():
    #我们使用spawn方法创建另一个进程
    #因此,它将在每个操作系统上使用相同的方法。
    #否则,将在Linux上使用fork而不是spawn
    mp.set\u start\u方法('spawn')
    q=mp.Queue()
    slave=mp.Process(target=mainloop,args=(第二次显示,q))
    slave.start()
    主循环(游戏(从属),q)
    如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
    main()
    

    当然,这只是一个简单的例子;您可能需要更多的错误处理,停止嵌套函数,比如疯狂等等。此外,在python中还有其他方法

    最后,但并非最不重要的一点是,考虑一下您是否真的需要两个pygame显示器,因为多处理增加了大量复杂性。我已经回答了一些关于pygame的问题,而且几乎总是这样