我有两个文件: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'的方法呢?
答案 0 :(得分:5)
这个问题可能真的适用于任何结构化的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
中进行,它使用所有其他模块来实现自定义类和实用程序功能。
答案 1 :(得分:0)
您只需拨打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)
答案 2 :(得分:0)
您可以编写将pygame.Surface对象作为参数的函数:
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)
我个人不知道这与其他基于精灵的引擎相比有多快/慢,但它是一种非常快速的方法来构建一个可以绘制/擦除自身的类。
要使用它,只需创建一个显示屏和一个电视对象。
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_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成员视为“位置标记”,您所要做的就是摆弄其成员(hehe)以更改对象的屏幕更新位置。
def move(self, move_amount=(1,0):
self.rect.move_ip(move_amount[0], move_amount[1])