Несколько дисплеев в 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 меньше, чем главный экран, поэтому при переходе на BATTLE_SCENE он переносится в созданную мной область (240x160) в верхнем углу главного экрана.

Однако я хочу, чтобы BATTLE_SCENE было отдельным окном, чтобы, когда я нажимаю «a», оно всплывало, делало свое дело, а затем закрывалось или, по крайней мере, уходило за главный экран.

Как это сделать? Это вообще возможно?


person hammythepig    schedule 19.06.2012    source источник
comment
Значит ли это, что я должен это сделать? было бы неплохо немного подробнее :)   -  person hammythepig    schedule 19.06.2012
comment
Создайте область в существующем окне для анимации.   -  person Oleh Prypin    schedule 19.06.2012
comment
Итак, что у меня уже есть? Вы знаете, что дальше этого не пойдет?   -  person hammythepig    schedule 19.06.2012


Ответы (2)


Вам действительно нужно несколько окон? Я имею ввиду, они тебе действительно нужны?

Если да, то вам, вероятно, следует использовать pyglet / cocos2d.

Чтобы иметь несколько окон в pygame, вам нужно несколько процессов (по одному для каждого окна). Хотя это выполнимо, но усилий это не стоит. Вам понадобится IPC для обмена данными между окнами, и я думаю, ваш код станет подвержены ошибкам и уродливы.

Используйте пиглет, когда вам нужно более одного окна.

Лучшее решение, вероятно, - разделить вашу игру на сцены. Создайте несколько сцен, чтобы каждая представляла один этап игры, например 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()

Это простой способ четко разделить логику игры и разрешить переключение контекста.

person sloth    schedule 19.06.2012
comment
О, понятно, воспользуйтесь некоторыми классами. Мне никогда не нравились уроки, потому что они выглядели так запутанно, но я понимаю, что вы там написали. Думаю, я даже больше загляну в классы и узнаю больше. А пока я беру ваш ответ, это действительно кажется простым и эффективным способом делать то, что я хочу, большое спасибо! :) - person hammythepig; 19.06.2012
comment
Это умная идея - поделиться своими знаниями о таких вещах. Мне нравится все это изучать, это интересно и весело одновременно. - person hammythepig; 19.06.2012

====================================== Редактировать =========== ==============================

На самом деле это не сработает. По-видимому, pygame поддерживает только один экран, и когда вы инициализируете другой, он закроет первый. Вы останетесь с двумя вариантами, которые на самом деле являются одной и той же поверхностью. Вместо этого вы можете заставить игру увеличивать размер окна и воспроизводить сцену битвы сбоку от него, для этого вы можете снова вызвать pygame.display.set_mode () с другими значениями. Переменная, которая ссылается на экран дисплея, по-прежнему будет использоваться, поскольку она меняет свою ссылку на новую. После того, как сцена закончится, вы можете точно так же уменьшить окно.

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

В основном происходит то, что вы запускаете цикл, и на каждой его итерации выполняется рендеринг и отображение нового кадра. Когда вы вызываете функцию внутри цикла, она не продолжает выполняться, пока вы не завершите выполнение функции.

Один из способов решить эту проблему - просто продолжать вызывать функцию, которая обновляет сцену битвы в основном цикле. Другой способ - использовать потоки. Threading - это, по сути, одновременное выполнение нескольких сценариев («потоков»).

К счастью, Python уже реализовал это для нас с помощью модуля потоковой передачи. Мне слишком долго объяснять модуль здесь, но вы можете изучить его здесь . Это может быть немного сложно, если вы раньше не использовали потоки, но через некоторое время станет проще. А если вы хотите узнать больше о потоковой передаче, перейдите здесь.

В частности, здесь вы можете иметь два потока, по одному для каждого цикла / окна, и запускать их одновременно.

Надеюсь, я помог тебе!

person TulkinRB    schedule 11.12.2014