【问题标题】:Reset and restart pygame program doesn't work重置并重新启动pygame程序不起作用
【发布时间】:2021-11-26 17:30:11
【问题描述】:

当要求用户重新启动时,我在 pygame 中重置我的游戏时遇到问题。程序是这样构造的:

import board as b

class Gui():
    def __init__(self):
        pygame.init()

        self.gamestate = b.GameState()

    def run(self):
        running = True
        while running:
            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_r:
                        running = False
                        pygame.quit()
                        Gui().run

if __name__ == '__main__':
    Gui().run()

当用户尝试重新启动时,会发生 GUI 关闭并且 while 循环按原样退出的情况。然后它会打开一个新窗口,但它没有清除游戏状态,所以我之前运行的游戏状态仍然存在。我认为self.gamestate = b.GameState() 行会为我创建一个新的游戏状态,但事实并非如此。这是板文件中的一个简短的 sn-p:

class GameState:

    def __init__(self):
        self.board = s.start_position

调用它时,我认为它会将板设置为起始位置并将其所有参数设置为初始位置,但有些地方不对劲,我已经 3 天没能解决这个问题了。我希望你能帮助我如何清除游戏状态并重新开始。

【问题讨论】:

    标签: python pygame


    【解决方案1】:

    您使系统过于复杂。您实际上正在做的是将新的Gui 对象和新的应用程序循环递归地实例化为现有的Gui 对象和应用程序循环。 如果GameState 实现正确,那么创建一个新的GameState 对象并继续现有的应用程序循环就足够了,而不是递归地创建一个新的Gui 实例:

    import board as b
    
    class Gui():
        def __init__(self):
            pygame.init()
    
            self.gamestate = b.GameState()
    
        def run(self):
    
            running = True
            while running:
    
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        running = False
                        pygame.quit()
    
                    if event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_r:
                            self.gamestate = b.GameState()
    
                # [...]
    
    if __name__ == '__main__':
        Gui().run()
    

    指令self.board = s.start_position 不会创建新的板对象。 self.boards.start_position 指的是同一个对象。如果您更改其中一个对象,另一个对象似乎也会以相同的方式更改,因为只有一个对象。
    要么您需要在开始游戏时制作棋盘对象的深层副本,要么需要在游戏重新开始时重置对象。

    解决方案可能是使用 Python copy 模块。 deepcopy 可以创建对象的深拷贝:

    import copy
    
    self.board = copy.deepcopy(s.start_position)`
    

    注意,并非所有对象都可以复制。例如,pygame.Surface 不能复制。

    【讨论】:

    • 不幸的是,情况似乎并非如此。我什至尝试将 self.gamestate = b.GameState() 和 self.gamestate.board = s.start_board 放在按键下,但棋盘仍然不受影响。我还在 Gui 中初始化了一些需要重置的参数。
    • @eligolf 无论如何,您的递归方法可能会导致副作用。如果我的方法不起作用,或者您在应用程序中搞砸了一些东西。
    • 我会再看一遍,但我目前 3 天的调试并没有让我有任何结果:( 一切都在重置(移动日志、玩家轮流等)。只有板没有正确更新甚至如果我明确告诉它。
    • 似乎声明 self.board = s.start_board 与我原来的 s.start_board 有所不同。因此,当我重置它时它确实有效,但原始值已经改变。你知道如何解决这个问题。您的解决方案很好,我接受它作为答案,这是其他问题。
    • @eligolf 我已经扩展了答案。
    猜你喜欢
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    相关资源
    最近更新 更多