在 python 中创建状态机

Creating a state machine in python

我之前在python做过各种简单的二次元游戏,因为很简单,所以没必要做这种东西。但我现在需要它,因为需要回去第四次。 不过,要继续前进,我需要某种方向...

我在一个新游戏中大约有 200 行,我还没有开始真正的游戏,它目前都在处理 window、事件和状态

### state machine

def run:
  #~setup window

  # Current state
  state = menu()

  running = True
  while running:
    #~event handler

    returns = state.update(events)
    if returns == "playgame":
      state = game()
    state.draw(window)
#menu state
class menu:
  def __init__(self):
    #~define vars for the menu (buttons, etc...)
    self.clickables = [] # filled with gui etc..
    self.image = image() # image of the menu

  def update(self, events):
    for event in events: # go through events
      for clickable in self.clickables: # go through clickables
        if clickable.testClicked(event.pos) != False: # Returns if clicked
          return clickable.testClicked(event.pos)

  def draw(self, window):
    self.image.draw(window)
#game state
class game(menu): # Exactly the same as menu (just used as example)
  def __init__(self):
    super(menu).__init__()
#gui button
class button: # Extremely shortened for example use
  def __init__(self, do): # do is a string 
    self.whenClickedDo = do

  def testClicked(self, mousePos):
    if mousePos in self.myRect: # myRect is the area of the button (Example!)
      return self.whenClickedDo
    return False

上面的这个例子完全是仓促的,但我思考的问题是......实现这个的更好方法是什么,或者上面的方法是 achievable/smart 做事的方法吗?

TLDR;函数 "run" 有一个值 "state",它可以 return 一个值,该值将用于将自身更改为不同的状态。这是制作状态机的合理方法吗?

我用 C++ 编写了一个简单的游戏引擎,并使用了一个基于屏幕的系统。我现在将尝试在 python 中为您编写一个简单的版本。这个想法是游戏的每个部分都是不同的屏幕。所以主菜单是一个屏幕,有一个游戏屏幕(所有操作都在这里发生),可能有一个供用户更改设置的选项屏幕等等。这些都是由屏幕列表管理的,每个屏幕在列表中有一个位置,您可以根据游戏事件在屏幕之间切换。因此,如果主菜单屏幕处于活动状态,当用户单击 'play' 按钮时,游戏屏幕现在已加载。

我完全想不出如何将它移植到 python 但这至少应该给你一个开始的地方。

所以屏幕会是 class 像这样的东西:

class Screen:

    # you can have objects in the screen as variables of the class here
    # e.g self.player = None

    def onEntry(self):
        # here you would init the assets for your screen
        # this could be the interface, sprites etc
        # e.g self.player = Player()

    def onExit(self):
        # do any clean up
        # maybe save player data if this is a gameplay screen
        # e.g self.player.save()

    def update(self):
        # main loop for this screen
        # e.g self.player.update()

您游戏的每个特定屏幕都将从屏幕 class 继承并使用该屏幕的自定义逻辑实现这些功能。那么屏幕列表基本上就是这些自定义屏幕 classes 的列表。您的游戏只会在这些屏幕之间切换。