10

私は小さなゲームを作っていますが、メインのウィンドウとは別に別のウィンドウを作成したいと思います。

メインウィンドウにメインゲームがあり、新しいウィンドウを開いて、ユーザーが何かをしたときに少しアニメーションを作成したいと思います。

以下の私のサンプルコードでは、ユーザーが「a」を押したときに、新しいウィンドウを開いてそこにブリットします。

ここで2つのウィンドウを設定します:(これが機能しないことはわかっていますが、その方法を尋ねています)

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で複数のウィンドウを使用するには、複数のプロセス(ウィンドウごとに1つ)が必要です。これは実行可能ですが、費用をかける価値はありません。ウィンドウ間でデータを交換するにはIPCが必要ですが、コードはエラーが発生しやすく、見苦しいものになると思います。

複数のウィンドウが必要な場合は、pygletを使用してください。

より良い解決策は、おそらくゲームをシーンに分割することです。MenuScene、MainScene、BattleScene、GameOverScene、OptionSceneなど、それぞれがゲームの1つのステージを表すように、複数のシーンを作成します。

次に、これらの各シーンで、ゲームのその部分の入力/描画を処理します。

  • 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は1つの表示画面しかサポートしておらず、別の画面を初期化すると最初の画面が閉じます。実際には同じ表面である2つの変数を使用します。代わりに、ゲームでウィンドウサイズを大きくし、その横でバトルシーンをプレイすることができます。これを行うには、別の値を使用してpygame.display.set_mode()を再度呼び出すことができます。表示画面を参照する変数は、新しいものへの参照を変更するため、引き続き使用できます。シーンが終わったら、同じ方法でウィンドウを元に戻すことができます。

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

基本的には、ループを実行し、ループを繰り返すたびに新しいフレームがレンダリングおよび表示されます。ループ内で関数を呼び出すと、関数の実行が終了するまで実行が継続されません。

この問題を解決する1つの方法は、メインループの戦闘シーンを更新する関数を呼び出し続けることです。別の方法は、スレッドを使用することです。スレッド化は基本的に同時に複数のスクリプト(「スレッド」)を実行しています。

幸いなことに、Pythonはスレッドモジュールを使用してこれをすでに実装しています。ここでモジュールを説明するには長すぎますが、ここで学ぶことができます。以前にスレッドを使用したことがない場合は少し複雑かもしれませんが、しばらくすると簡単になります。そして、スレッドについてもっと知りたい場合は、ここに行くことができます。

特にここでは、ループ/ウィンドウごとに1つずつ、合計2つのスレッドを作成し、それらを同時に実行できます。

私があなたを助けたことを願っています!

于 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 に答える