1

ねえ、これは私が以前に尋ねた「インポート内のインポート」の質問を少し拡張したものなので、モデレーターは自由に 2 をマージしてください。

A.py と B.py の 2 つのファイルがあります。

#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同様に..私も2回pygameしたくありません。それを行う「Pythonic」の方法はありますか?

4

3 に答える 3

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)

これは良い習慣です。すべてのモジュールがメイン スクリプトのグローバル オブジェクトに依存している場合、それらの再利用性ははるかに低くなります。

A.py特にpygameの状況では、カスタムクラスとユーティリティ関数用の他のすべてのモジュールを使用して、画面表面に関するすべてが発生するはずです。

于 2012-04-23T00:19:23.790 に答える
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)

これが他のスプライトベースのエンジンと比較してどれほど速い/遅いかは個人的にはわかりませんが、それ自体を描画/消去できるクラスを構築するための非常に迅速な方法です。

使用するには、表示画面とTVオブジェクトを作成するだけです。

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)

または、1行変更するだけですべて消去できます

for tv in tv_list:
    tv.erase(screen)

最後に、TVクラスにもう1つの関数を追加して、TVクラスを移動できます。.rectメンバーを「位置マーカー」として扱う場合は、そのメンバー(hehe)をいじって、オブジェクトの画面上の更新位置を変更するだけです。

def move(self, move_amount=(1,0):
    self.rect.move_ip(move_amount[0], move_amount[1])
于 2012-04-23T00:45:34.573 に答える
0

呼び出す必要があるのはpygame.init()1 回だけなので、コードは次のようになるはずです。

#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)
于 2012-04-23T00:22:45.307 に答える