-1

モジュールPygameでPythonを使用して小さなゲームを作成しています。

私はかなり基本的な(そしてかなり単純だと思います)状態マネージャーを実装しようとしました。

ただし、
現在問題があります
。「再生」状態に切り替えると、「メニュー」に戻ることができません。
これは、ステート マネージャーの設計方法に問題がありますか?

私には2つの方法がありますが、

  1. このstate_changeメソッドは、1 つの引数 (目的の状態) を取ります。
  2. このstate_checkメソッドは状態を唯一の引数として取り、それを現在の状態として返します。

以下に 2 つの方法を示します。

def state_check(self, state):
    self.current_state = state
    print self.current_state
    return self.current_state

def state_change(self, state):
    self.state = state

メインループの前に、
最初stateは「メニュー」に初期化されます。
メイン ループ内で
state_checkは、開始状態を示す if ステートメントの前にあります。

def game_loop(self):                                                                       

    running = True
    self.test_car = car()
    self.state = "menu"
    while running:
        pygame.display.set_caption("Project G")
        self.state_check(self.state)
        if self.current_state ==  "menu":
            self.state_check(self.state)
            self.screen.blit(self.background, (0,0))
            #Blits the current state on the screen for testing purposes.
            self.screen.blit(self.menu_text, (700, 580))
            self.event_handler()
            pygame.display.flip()
        if self.current_state == "play":
            self.state_check(self.state)
            self.screen.blit(self.background, (0,0))
            #Blits the current state on the screen.
            self.screen.blit(self.play_text, (700, 580))
            self.test_car.event_handler()
            self.test_car.update(self.test_car.x_speed, self.test_car.y_speed)
            pygame.display.flip()

if ステートメント内に
は、イベント ハンドラー メソッドがあります。これは現在、キーボード入力を取得して状態を切り替え (state_changeメソッドを呼び出すことにより)、プログラムを終了するために作成しました。

いくつかの印刷方法を使用して、キーが登録されていない可能性を除外しました。

#Event handler for the menu

def event_handler(self):

    for event in pygame.event.get():
        if event.type == QUIT:
           pygame.quit()
           sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_p:
                self.state_change("play")
                print "Key Pressed: p"
            if event.key == K_q:
                print "Key Pressed: q"
                pygame.quit()
                sys.exit()
#Sample of the Event handler for "play"

def event_handler(self):
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_m:
                self.state_change("menu")
                print "Key Pressed: m"
            if event.key == K_q:
                print "Key Pressed: q"
                pygame.quit()
                sys.exit()
4

4 に答える 4

1

いくつかの可能性として、次の行が間違ったオブジェクトを参照している可能性があります (test_carそれがメニューであるはずなのに?) が、残りのコードがなければ実際にはわかりません。

self.test_car.event_handler()

しかし、それが起こることになっている場合、その中でtest_car.event_handler呼び出しているのはself.state_change、期待しているものの状態を変更しない可能性があるためです. つまり、実際に(または実行中のオブジェクトを) 変更することはなく、代わりに.selftest_carmenu.statemain_looptest_car.state

于 2013-01-31T04:36:18.483 に答える
1

少し複雑にしすぎていると思います。check_state 関数と set_state 関数、および 2 つの変数が本当に必要ですか?

私はこのようなことをします:

class State(object):
    menu = "menu"
    play = "play"

class Game(??):

    def event_handler(self):
        for event in pygame.event.get():
            if event.type == KEYDOWN:
                if event.key == K_m:
                    self.state = State.menu
                    print "Key Pressed: m"
                elif event.key == K_p:
                    self.state = State.play
                    print "Key Pressed: p"

    def game_loop(self):
        self.state = State.menu

        while running:
            if self.state is State.menu:
                # Do menu things
            elif self.state is State.play:
                # Play game! 
于 2013-01-31T04:41:56.863 に答える
0

ゲームの状態管理を複雑にしていると思います。

  1. 関数の必要はありませんが、
    • state_change
    • state_check.
  2. または、状態を処理するための 2 つの変数。
    • self.state
    • self.current_state

ゲームの状態については、変数を使用することもできます (2 つある場合)。 - 2
つ 以上ある場合。 しかし、文字列を使用するとコードが読みやすくなります。<type 'bool'>
<type 'int'>

この場合、1 つの変数でも十分です(以下を参照) 。2 つの変数を使用する
ことをお勧めし
ますtuple
2. 現在の状態、値、またはインデックス ( を参照tuple)

このアプローチは、より多くの状態でも機能するため、多くの管理の煩わしさなしに、より多くの状態を開発する余地が与えられます。

どのように?
以下のコードと 2 つの変数の使用を見てください。

  1. self.state
  2. self.states

コード:

class Game:

    def __init__(...):
        self.states = ('menu','play')
        self.state = 0

    def events_play(self):
        for event in pygame.event.get():
            # event handling
                self.state = self.states[0]

    def events_menu(self):
        for event in pygame.event.get():
            # event handling
                self.state = self.states[1]

    def game_loop(self):

        while running:
            if self.state == 'menu':
                # I always handle events first :)
                self.events_menu()
                # Do menu things

            elif self.state == 'play':
                # I always handle events first :)
                self.events_play()
                # Play game!
于 2013-01-31T14:02:07.800 に答える
0

実行中のループで2 つのifステートメントを続けて使用しています。代わりにifおよびelifステートメントを使用してみてください。

于 2013-01-31T04:41:14.217 に答える