pygameで画面遷移を行うには?

# pygameの画面遷移
ゲーム作りにおいて、画面遷移はプログラムの完成度に非常に関係します。
また可読性と汎用性においても関係します。

つまりは、この画面遷移は大事という話です
# やり方1 フラッグ
この方法は推奨されないが、プロセスにフラグを設定し、そのフラグを使って処理するかどうかを決める方法である。
```python: 記述例1
import pygame

pygame.init()

screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
running = True
gamen1 = True
gamen2 = False

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                gamen1 = not(gamen1)
                gamen2 = not(gamen2)
    screen.fill((255, 255, 255))
    if gamen1:
        pygame.draw.rect(screen, (0, 0, 0), (100, 100, 100, 100))
    if gamen2:
        pygame.draw.rect(screen, (0, 0, 0), (300, 100, 100, 100))
    pygame.display.update() 
    clock.tick(60)
pygame.quit()
```
実行結果
![Untitled video - Made with Clipchamp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3195955/c8f475ee-543c-55b5-b742-9bb1eca0218b.gif)
clickすると描写するブロックが変わるという仕組みです
ブロックが移動しているように見えますが画面を変えているといってもいいと思います。

この書き方は記述量が少ないときはいいですが、プロジェクトが大きくなる、
難解なプログラムを君臨させることになります。

# やり方2 クラスでフラッグ
かなり効果的な方法だと思います
画面別に処理を作り、それぞれにフラッグを持たせます
``` python: 記述例2
import pygame
pygame.init()
class Gamen1:
    def __init__(self) -> None:
        self.block1_color = (0, 0, 0)
        self.block1_rect = pygame.Rect(100, 100, 100, 100)
        self.enable = False
    def update(self):
        pass
    def draw(self, screen):
        if self.enable:
            pygame.draw.rect(screen, self.block1_color, self.block1_rect)

class Gamen2:
    def __init__(self) -> None:
        self.block1_color = (0, 0, 0)
        self.block1_rect = pygame.Rect(300, 100, 100, 100)
        self.enable = True
    def update(self):
        pass
    def draw(self, screen):
        if self.enable:
            pygame.draw.rect(screen, self.block1_color, self.block1_rect)
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
running = True
gamen1 = Gamen1()
gamen2 = Gamen2()

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                gamen1.enable = not(gamen1.enable)
                gamen2.enable = not(gamen2.enable)
    screen.fill((255, 255, 255))
    gamen1.update()
    gamen2.update()
    gamen1.draw(screen)
    gamen2.draw(screen)
    pygame.display.update() 
    clock.tick(60)

pygame.quit()
```
実行結果は変わりません。
これならある程度大きくなったプロジェクトでもやっていけるのかなって思います。
# やり方3 ファイルに分ける
このやり方が個人的にはお気に入りです。
ファイル別にSceneの処理を分ける方法です。
ファイルの読み込みはimportllibを使います
``` python: 記述例3 main.py
import pygame
import importlib
pygame.init()
def GetScene(name):
    return importlib.import_module(name).Main()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
running = True
gamen = [GetScene("Gamen1")]
index = 0
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                index += 1
                gamen = []
                gamen.append(GetScene("Gamen" + str((index % 2) + 1)))
    screen.fill((255, 255, 255))
    for g in gamen:
        g.update()
        g.draw(screen)
    pygame.display.update() 
    clock.tick(60)

pygame.quit()
```
``` python: Gamen1.py
class Main():
    def __init__(self) -> None:
        self.block1_color = (0, 0, 0)
        self.block1_rect = pygame.Rect(100, 100, 100, 100)
    def update(self):
        pass
    def draw(self, screen):
        pygame.draw.rect(screen, self.block1_color, self.block1_rect)
```
``` python:Gamen2.py
class Main:
    def __init__(self) -> None:
        self.block1_color = (0, 0, 0)
        self.block1_rect = pygame.Rect(300, 100, 100, 100)
    def update(self):
        pass
    def draw(self, screen):
        pygame.draw.rect(screen, self.block1_color, self.block1_rect)
```
テスト実行してないので動くかわかりませんがやりたいことだけをくみ取ってほしいです。
それぞれ画面用のファイル(Gamen1.py Gamen2.py)には同じ名前の(Main())クラスを書かないと、
```python
def GetScene(name):
    return importlib.import_module(name).Main() #.Main()で指定したファイル内のMainクラスを読み込む
```
がうまく動きませんので注意

# 最後に
気に入ったやり方を探してください