2012-06-19 3 views
6

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

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

Как это сделать? Возможно ли это?

+0

Вы все равно не должны делать это –

+0

Означает ли это, что я должен это сделать? немного больше объяснений было бы хорошо :) – hammythepig

+0

Сделайте область в существующем окне для анимации. –

ответ

8

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

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

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

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

Лучшим решением, вероятно, является разделение вашей игры на сцены. Создайте несколько сцен, чтобы каждый из них представлял один этап игры, например, MenuScene, MainScene, BattleScene, GameOverScene, OptionScene и т. Д.

Затем пусть каждая из этих сцен обрабатывает ввод/вывод этой самой части игры.

  • MenuScene обрабатывает рисунок и ввод т.д. меню игры
  • MainScene ручки рисования и ввода т.д. запущенной игре
  • BattleScene ручки рисования и ввода и т.д. того, что вы делаете в run_ani

В вашем mainloop просто передайте управление текущей сцене, реализовав методы 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() 

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

+0

О, я вижу, используйте несколько классов. Мне никогда не нравились классы, потому что они выглядели такими запутанными, но я понимаю, что вы там написали. Думаю, я еще больше изучу классы и узнаю больше. Пока я беру на себя ответ, это похоже на простой и эффективный способ сделать то, что я хочу, большое спасибо! :) – hammythepig

+0

Это умная идея, которая делится своими знаниями о таких вещах. Мне нравится учиться всему этому, интересному и интересному одновременно. – hammythepig

1

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

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

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

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

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

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

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

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

Смежные вопросы