【问题标题】:Multiple Displays in PygamePygame 中的多个显示
【发布时间】:2012-06-21 18:42:51
【问题描述】:

我正在制作一个小游戏,我想制作另一个与主窗口分开的窗口。

我在一个主窗口中有主游戏,我想打开一个新窗口并在用户做某事时做一些动画。

在下面的示例代码中,当用户按下“a”时,我希望它打开一个新窗口并快速跳转到那里。

在这里我设置了两个窗口:(我知道这不起作用,我要问的是怎么做)

SCREEN_X = 400
SCREEN_Y = 400
BSCREEN_X = 240
BSCREEN_Y = 160

BATTLE_SCENE = pygame.display.set_mode((BSCREEN_X, BSCREEN_Y))
SCREEN = pygame.display.set_mode((SCREEN_X, SCREEN_Y))

然后是程序:

def run_ani ():
    #Do animation, blitting to BATTLE_SCENE
    return

def main_game():
    ending=False
    while ending==False:
        clock.tick(30)
        for event in pygame.event.get():
            if event.type == pygame.QUIT: ending=True
            if event.type == KEYDOWN: # key down or up?
                if event.key == K_ESCAPE:
                    ending=True # Time to leave
                    print("Stopped Early by user")
                elif event.key == K_a:
                    run_ani()
        #Normal screen motion, blitting to SCREEN
        if ending: pygame.quit()
    return

到目前为止,它所做的是绘制主屏幕,然后当按下 A 时,它停止绘制主屏幕动画,但仍然在主屏幕上绘制其他动画并在左上角绘制。

我很确定它会这样做,因为我将 BATTLE_SCENE 设置为小于主屏幕,因此当传送到BATTLE_SCENE 时,它会传送到我在主屏幕上角创建的区域 (240x160)屏幕。

但是我希望BATTLE_SCENE 成为一个单独的窗口,这样当我按“a”时它会弹出,做它的事情,然后关闭或至少在主屏幕后面。

如何做到这一点?有没有可能?

【问题讨论】:

  • 这是否意味着我有办法做到这一点?多一点解释会很好:)
  • 在现有窗口中为动画创建一个区域。
  • 基本上,我已经拥有了什么?没有比这更远的了,你知道吗?

标签: python-3.x pygame


【解决方案1】:

是的,这是可能的。 SDL2 能够打开多个窗口。在示例文件夹中,您可以查看“video.py”。

https://github.com/pygame/pygame/blob/main/examples/video.py

“这个例子需要 pygame 2 和 SDL2。_sdl2 是实验性的,会改变。”

【讨论】:

    【解决方案2】:

    =======================================编辑======== ===================================

    实际上它不会起作用。显然pygame只支持一个显示屏幕,当你初始化另一个时,它会关闭第一个。您将使用两个变量,它们实际上是相同的表面。相反,您可以让游戏增加窗口大小并在其一侧播放战斗场景,为此,您可以使用不同的值再次调用 pygame.display.set_mode()。引用显示屏幕的变量仍然可用,因为它更改了对新屏幕的引用。场景结束后,您可以以同样的方式将窗口缩小。

    ================================================ ====================================

    基本上发生的是你运行一个循环,它的每次迭代都在渲染和显示一个新帧。 当你在循环中调用一个函数时,它不会继续运行,直到你完成函数运行。

    解决这个问题的一种方法是在主循环中不断调用更新战斗场景的函数。 另一种方法是使用线程。线程基本上是同时运行多个脚本(“线程”)。

    幸运的是,python 已经使用 threading 模块为我们实现了这一点。 我在这里解释模块太长了,但你可以学习它here。如果您以前没有使用过线程,这可能会有点复杂,但过一段时间会更容易。 如果你想了解更多关于线程的信息,你可以去here

    具体来说,你可以有两个线程,每个循环/窗口一个,同时运行它们。

    希望能帮到你!

    【讨论】:

      【解决方案3】:

      您真的需要多个窗口吗?我的意思是,你真的需要它们吗?

      如果是,那么您应该改用pyglet/cocos2d

      要在 pygame 中有多个窗口,您需要多个进程(每个窗口一个)。虽然这是可行的,但不值得付出努力。你需要IPC 在窗口之间交换数据,我猜你的代码会变得容易出错和丑陋。

      当您需要多个窗口时使用 pyglet。

      更好的解决方案可能是将您的游戏划分为场景。创建多个场景,每个场景代表游戏的一个阶段,例如 MenuScene、MainScene、BattleScene、GameOverScene、OptionScene 等。

      然后让这些场景中的每一个处理游戏的那个部分的输入/绘图。

      • MenuScene 处理游戏菜单的绘制和输入等操作
      • MainScene 处理运行游戏的绘制和输入等操作
      • BattleScene 处理您在run_ani 中所做的任何事情的绘制和输入等

      在您的主循环中,只需通过实现方法draw()handle_event()update() 将控制权传递给当前场景。

      一些示例代码来理解这个想法:

      scenes = {'Main': MainScene(),
                'Battle': BattleScene()} #etc
      
      scene = scenes['Main']
      
      class MainScene():
        ...
        def handle_event(self, event):
          if event.type == KEYUP:
            if event.key == K_a:
              scene = scenes['Battle']
        ...
      
      class BattleScene():
        ...
        def draw(self):
          # draw your animation
      
        def update(self):
          # if animation is over:
          scene = scenes['Main']
      
      ...
      
      def main_game():
        ending=False
        While Not ending:
            clock.tick(30)
            for event in pygame.event.get():
              scene.handle_event(event)
              scene.update()
              scene.draw()
      

      这是一种清晰分离游戏逻辑并允许上下文切换的简单方法。

      【讨论】:

      • 哦,我明白了,使用一些类。我从不喜欢课程,因为它们看起来很混乱,但我理解你在那里写的内容。我想我什至会更多地去上课,学到更多东西。现在我带你回答,这似乎是一种简单而有效的方法来做我想做的事,非常感谢! :)
      • 这是一个聪明的想法,分享你对这些事情的了解。我喜欢学习所有这些东西,它既有趣又有趣。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多