Я делаю небольшую игру и хочу сделать еще одно окно отдельно от основного.
У меня основная игра находится в главном окне, и я хочу открыть новое окно и сделать небольшую анимацию, когда пользователь что-то делает.
В моем примере кода ниже, когда пользователь нажимает "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", оно всплывало, делало свое дело, а затем закрывалось или, по крайней мере, уходило за главный экран.
Как это сделать? Это вообще возможно?
Ответ 1 · рейтинг 10 · sloth
Вам действительно нужно несколько окон? Я имею ввиду, они тебе действительно нужны?
Если да, то вам, вероятно, следует использовать 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()
Это простой способ четко разделить логику игры и разрешить переключение контекста.
Ответ 2 · рейтинг 3 · TulkinRB
====================================== Редактировать =========== ==============================
На самом деле это не сработает. По-видимому, pygame поддерживает только один экран, и когда вы инициализируете другой, он закроет первый. Вы останетесь с двумя вариантами, которые на самом деле являются одной и той же поверхностью. Вместо этого вы можете заставить игру увеличивать размер окна и воспроизводить сцену битвы сбоку от него, для этого вы можете снова вызвать pygame.display.set_mode () с другими значениями. Переменная, которая ссылается на экран дисплея, по-прежнему будет использоваться, поскольку она меняет свою ссылку на новую. После того, как сцена закончится, вы можете точно так же уменьшить окно.
==================================================================================
В основном происходит то, что вы запускаете цикл, и на каждой его итерации выполняется рендеринг и отображение нового кадра. Когда вы вызываете функцию внутри цикла, она не продолжает выполняться, пока вы не завершите выполнение функции.
Один из способов решить эту проблему - просто продолжать вызывать функцию, которая обновляет сцену битвы в основном цикле. Другой способ - использовать потоки. Threading - это, по сути, одновременное выполнение нескольких сценариев ("потоков").
К счастью, Python уже реализовал это для нас с помощью модуля потоковой передачи. Мне слишком долго объяснять модуль здесь, но вы можете изучить его здесь . Это может быть немного сложно, если вы раньше не использовали потоки, но через некоторое время станет проще. А если вы хотите узнать больше о потоковой передаче, перейдите здесь.
В частности, здесь вы можете иметь два потока, по одному для каждого цикла / окна, и запускать их одновременно.
Надеюсь, я помог тебе!