10

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

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

在我下面的示例代码中,当用户按下“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'时它会弹出,做它的事情,然后关闭或至少在主屏幕后面。

这个怎么做?甚至可能吗?

4

3 回答 3

11

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

如果是,那么您可能应该改用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()

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

于 2012-06-19T18:29:32.313 回答
3

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

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

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

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

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

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

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

希望我对你有所帮助!

于 2014-12-11T18:27:58.340 回答
2

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

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

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

于 2021-10-03T05:28:29.830 回答