我正在使用带有Pygame模块的Python创建一个小游戏。
我尝试实现一个非常基本的(我猜一个非常天真的)状态管理器。
然而,
我目前有一个问题:
一旦我切换到“播放”状态,我就无法切换回“菜单”
这是我设计州政府经理的一个缺陷吗?
我有两种方法,
state_change
方法采用一个参数,即所需的状态。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()
答案 0 :(得分: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 :(得分: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!
答案 2 :(得分:0)
您在正在运行的循环中一个接一个地使用两个 if 语句。请尝试使用 if 和 elif 语句。
答案 3 :(得分:0)
我相信你的游戏状态管理很复杂。
state_change
state_check
。 self.state
self.current_state
对于游戏状态,您可以使用变量
- <type 'bool'>
如果有2.
- <type 'int'>
如果超过2个
但是然后使用字符串使代码可读。
在这种情况下,偶数1变量,(见下文)
我建议使用2个变量
1.包含所有可能状态的tuple
2.当前状态,值或索引(参考tuple
)
这种方法也适用于更多的州,为您提供开发更多州的空间,没有太多的管理支柱,
如何?
查看下面的代码和2个变量的使用
self.state
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!