単一のメイン ループに固執し、本当に必要でない場合はスレッドを使用しないでください。
ゲームがさまざまな画面で構成されていることは既にわかっているので (描画する実際の画面Scene
と混同しないように名前を付けましょう)、次の論理的なステップはメイン ループからそれらを分離することです。
次のシーンがあるとします。
次に、それらのそれぞれに対してクラスを作成する必要があります。これは、描画/イベント処理/この部分で必要なものを担当します。
簡単な例:
import pygame
pygame.init()
class Scene(object):
screen = None
class Intro(Scene):
def __init__(self):
self.c = (32, 32, 100)
def draw(self):
Scene.screen.fill(self.c)
def update(self):
# since scenes are classes, they have a state that we can modify
r,g,b = self.c
r += 1
g += 1
b += 2
if r > 255: r = 0
if g > 255: g = 0
if b > 255: b = 0
self.c = r, g, b
def handle(self, event):
# move to Menu-scene when space is pressed
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
# returning a scene from handle or update changes the current scene
return Menu()
class Menu(Scene):
def draw(self):
# draw menu
Scene.screen.fill((200, 200, 100))
def update(self):
pass
# do something
def handle(self, event):
# handle menu input
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
return Game()
if event.key == pygame.K_b:
return Intro()
class Game(Scene):
pass # implement draw update handle
Scene.screen = pygame.display.set_mode((800, 600))
scene = Intro()
while True:
if pygame.event.get(pygame.QUIT): break
for e in pygame.event.get():
scene = scene.handle(e) or scene
scene = scene.update() or scene
scene.draw()
pygame.display.flip()
このように、メインループは 1 つですが、ゲームのさまざまな部分が個別のクラスによって管理されます。上記の単純な例では、各シーンは特定のイベントでアクティブにする他のシーンを認識していますが、これは必須ではありません。SceneHandler
シーン間の遷移を管理するようなものを作成できます。また、シーン間で渡したいある種のゲーム状態オブジェクトが必要になる場合があります (たとえば、ゲーム シーンのポイントをゲーム オーバー シーンに表示します)。