Heyo,这是我之前提出的"导入中的导入"问题的扩展,因此版主可以随意合并2。
我有 2 个文件:A.py 和 B.py
#A.py
import pygame
import B
pygame.init()
tv = pygame.display.set_mode((256, 256))
tv.blit(<some surface here>)
#B.py
import pygame
pygame.init()
tv.blit()??? <--- I need to blit to tv, but how do I do it here?
我尝试制作一个名为 Globe 的空白文件并为其分配全局值,但大多数时候我发现它只会让我的代码看起来笨拙且难以编写。也。。我也不想init
两次pygame。有没有"Pythonic"的方法可以做到这一点?
这个问题实际上适用于任何结构化的python应用程序。
一个可执行的python脚本将有一个入口点。这是您为启动应用程序而调用的脚本。在此脚本中,它可以导入库模块以重用扩展功能。
应用程序需要具有单个入口点。让我们假设它将A.py
.
B.py
将是一个库模块,您将导入并使用其功能。它不应该期望全局tv
变量进行操作。相反,它至少应该具有接受参数的函数。甚至,使用要使用的图面实例化的类。这种方法的好处是,您的B
模块现在是可重用的,并且不依赖于某些可执行的主脚本,该脚本提供始终称为tv
的全局图面
B.py
def blitSpecial(surf):
surf.blit()
A.py
import B
tv = pygame.display.set_mode((256, 256))
B.blitSpecial(tv)
这是一个好习惯。如果所有模块都依赖于主脚本中的全局对象,则它们的可重用性将大大降低。
特别是针对您的pygame情况,屏幕表面的所有内容都应该在A.py
中使用所有其他模块进行自定义类和实用程序函数。
你可以编写采用pygame的函数。表面对象作为参数:
class TV():
def __init__(self):
self.img = ...
### insert code to load image here
self.rect = self.img.get_rect()
def draw(self, surface):
surface.blit(self.img, self.rect.topleft)
def erase(self, surface, background):
surface.blit(background, self.rect)
我个人不知道与其他基于 sprite 的引擎相比,这有多快/多慢,但这是一种非常快速的方法,可以构建一个可以绘制/擦除自己的类。
要使用它,只需创建一个显示屏和一个电视对象。
screen = pygame.display.set_mode((256, 256))
background = pygame.Surface((0,0),(256,256))
background.fill(pygame.Color(0,0,0))
screen.fill(pygame.Color(0,0,0))
myTVobj = TV()
每次您想将电视的副本绘制到您呼叫的屏幕上时
myTVobj.draw(screen)
要拭除对象,请使用
myTVobj.erase(screen, background)
然后,您可以稍后使用从TV类创建的对象做有趣的事情,例如将它们粘贴到列表中。
tv_list = []
tv_list.append(myTVobj)
您可以将一大堆电视添加到列表中,并同时绘制所有电视。
tv_list = []
tv_list.append(myTVobj)
tv_list.append(myTVobj)
tv_list.append(myTVobj)
for tv in tv_list:
tv.draw(screen)
或者,您只需更改一行即可将它们全部删除
for tv in tv_list:
tv.erase(screen)
最后,您可以向电视类添加另一个函数,以便移动它。如果您将 .rect 成员视为"位置标记",您所要做的就是摆弄其成员(呵呵)以更改对象的屏幕更新位置。
def move(self, move_amount=(1,0):
self.rect.move_ip(move_amount[0], move_amount[1])
你只需要调用pygame.init()
一次,所以我认为你的代码应该看起来像这样:
#A.py
import pygame
import B
def setup():
pygame.init()
tv = pygame.display.set_mode((256, 256))
...
mysurface = ...
tv.blit(mysurface)
return tv
#B.py
import pygame
def mydraw(surface):
...
surface.blit()
# In whatever file you like :)
if __name__ == '__main__':
surface_A = B.setup() # Do this first
mydraw(surface_A)