Pygame中的多个显示

时间:2012-06-19 17:04:04

标签: python-3.x pygame

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

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

在我下面的示例代码中,当用户按下" 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设置为小于主屏幕,因此当blitting到BATTLE_SCENE时,它会突然显示我创建的区域(240x160)主屏幕的顶角。

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

怎么做?它甚至可能吗?

2 个答案:

答案 0 :(得分:9)

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

如果是,那么您应该使用pyglet / cocos2d代替。

要在pygame中拥有多个窗口,您需要多个进程(每个窗口一个)。虽然这是可行的,但是不值得efford。你需要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()

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

答案 1 :(得分:1)

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

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

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

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

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

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

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

希望我帮助过你!