无法将游戏状态恢复到菜单

-1 投票
4 回答
767 浏览
提问于 2025-04-17 14:17

我正在用Python和Pygame模块制作一个小游戏。

我尝试实现一个相对简单(我想这可能有点幼稚)的状态管理器。

不过,
我现在遇到了一个问题:
一旦我切换到“游戏”状态,就无法再切换回“菜单”状态了。
这是我设计状态管理器时的缺陷吗?

我有两个方法:

  1. state_change方法接受一个参数,就是想要切换到的状态。
  2. state_check方法只接受一个状态作为参数,并返回当前状态。

这两个方法是这样的:

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 个回答

0

你在运行的循环中使用了两个if语句,一个接一个。试试用一个if和一个elif语句来代替吧。

1

这里有几个可能性。你提到的这一行可能在指向错误的对象(比如说,它应该指的是菜单,但却指向了test_car),不过我没有看到完整的代码,无法确定。

self.test_car.event_handler()

但是如果这是应该发生的事情,那么在test_car.event_handler里,你调用了self.state_change,这可能不会改变你期待的状态。因为到那时,self指向的是test_car,而不是菜单。这就意味着你实际上并没有改变menu.state(或者说main_loop正在运行的其他对象),而是改变了test_car.state

1

我觉得你可能把事情想得太复杂了——你真的需要 check_state 和 set_state 这两个函数,还有两个变量吗?

我会这样做:

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! 

撰写回答