我正在使用 pygame 将图像 blit 到屏幕上,同时它执行主循环。我对线程使用多处理,但似乎有问题。请不要因为奇怪的想成为 xml 评论而咀嚼我,因为我对此还很陌生。
这是我的代码。
#Import libraries
import pygame
import os, sys
import multiprocessing as threading
import time
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((1400,900), FULLSCREEN)
class loader:
def sound(name):
load = os.path.join("data", name)
sound = pygame.mixer.Sound(load)
return sound
def song(name):
load = os.path.join('data', name)
song = pygame.mixer.Sound(load)
return song
def picture(name):
load = os.path.join("data", name)
image = pygame.image.load(load)
image = image.convert()
return image
def movie(name):
load = os.path.join("data", name + ".mpg")
movie = pygame.movie.Movie(name)
return movie
class data():
class movies():
#Turns out it's not supported D:
pass
class songs():
theme = loader.song("theme.ogg")
class sounds():
fctune = loader.sound("fctune.wav")
class pictures():
fc = loader.picture("fc_opaque.tga")
#------------------------Logics-------------------------
def showlogo():
screen.blit(data.pictures.fc, (0,0))
data.sounds.fctune.play()
time.sleep(30)
def startloops():
logo = threading.Process(target=showlogo, args=())
gameloop = threading.Process(target=mainloop, args=())
logo.start()
logo.join(None)
gameloop.start()
gameloop.join(None)
def mainloop():
while 1:
clock.tick(30)
pygame.display.flip()
for event in pygame.event.get():
if event.type == QUIT:
return
elif event.type == KEYDOWN and event.key == K_ESCAPE:
sys.exit(1)
elif event.type == MOUSEBUTTONDOWN:
pass
elif event.type is MOUSEBUTTONUP:
pass
#End of looper.
#-----------------------/Logics-------------------------
#----------------------Globals--------------------------
clock = pygame.time.Clock()
#----------------------/Globals-------------------------
if __name__ == "__main__": startloops()
它的作用是创建 2 个 pygame 窗口 .. (一个应该在你打电话时出现
screen = pygame.display.set_mode((1400,900), FULLSCREEN)
所以显然它调用了两次。
嗯,多处理似乎是罪魁祸首。任何人都可以帮忙吗?
最佳答案
这就是我相信正在发生的事情。基本上,multiprocessing
模块的工作原理是将 target
需要的所有内容的副本发送给全新的解释器;这就是它绕过 GIL 的方式。但这意味着副作用(对全局变量的更改,对传入但未返回的对象的更改)不会按预期传播。这是一个简单的例子:
>>> import multiprocessing
>>> d = {'a':5, 'b':6}
>>> def alter_d():
... d['a'] = 7
... print d
...
>>> p = multiprocessing(target=alter_d)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'module' object is not callable
>>> p = multiprocessing.Process(target=alter_d)
>>> p.start()
>>> {'a': 7, 'b': 6}
>>> d
{'a': 5, 'b': 6}
如您所见,已传递给新进程的
d
版本已更改。但是 d
的本地版本保持不变。现在我对 pygame 的内部一无所知。但我的猜测是,当您使用
logo = threading.Process(target=showlogo, args=())
创建一个新进程时,它会复制 screen
。然后,无论是在制作该副本时,还是在新进程中调用 screen.blit(data.pictures.fc, (0,0))
时,都会生成一个全新的屏幕。幸运的是,您现在使用多处理的方式完全没有意义。
join
只是停止主进程并等待子进程完成——没有任何并发性。此外,我敢打赌 pygame 提供了您实际需要的任何线程功能——我怀疑您根本不需要多处理。我建议你放弃它。关于Pygame 和多处理的 Python 帮助,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6400241/