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的一个实例是不可能做到这一点的。我想知道如何/是否可以实施以下任一解决方案:
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的问题,而且几乎总是这样