Multiple displays in pygame

I am making a small game, and I want to make another window separate from my main one.

I have the main game in the main window, and I want to open a new window and make a little animation when the user does something.

In the code example below, when the user presses "a", I want him to open a new window and blit there.

Here I installed two windows: (I know that this does not work, its what I ask, how to do it)

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)) 

and then the program:

 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 

For now, he does the main screen, then when A is pressed, he stops drawing the main screen animation, but still draws other animations on the main screen and draws in the upper left corner.

I'm sure this is because I set BATTLE_SCENE smaller than the main screen, so when blitting to BATTLE_SCENE , it is close to the area I created (240x160) in the upper corner of the main screen.

However, I want BATTLE_SCENE be a separate window, so when I press 'a' it pops up, does its job, then closes, or at least leaves the main screen.

How to do it? Is it possible?

+6
source share
2 answers

Do you really need some windows? I mean, do you really need them?

If so, then you should probably use pyglet / cocos2d instead.

To have multiple windows in pygame, you need several processes (one for each window). Although it is doable, it is not worth it. You will need IPC to exchange data between windows, and I think your code will become error prone and ugly.

Go with a picket if you need more than one window.

The best solution is probably to split your game into scenes. Create multiple scenes so that each of them represents one stage of the game, for example, MenuScene, MainScene, BattleScene, GameOverScene, OptionScene, etc.

Then let each of these scenes process the input / output of this very part of the game.

  • MenuScene handles drawing and input, etc. game menu.
  • MainScene handles drawing and input, etc. current game
  • BattleScene handles drawing and input, etc. of what you do in run_ani

In your mainloop, just take control of the current scene by implementing the draw() , handle_event() and update() methods.

Sample code to get the idea:

 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() 

This is an easy way to clear the game logic and enable context switching.

+8
source

======================================== Edit ============ ================================

In fact, this will not work. Apperantly pygame only supports one screen, and when you initialize another, it closes the first. You will be left with two variables that are actually the same surface. Instead, you can increase the size of the window and play the battle scene from the side, to do this, you can again call pygame.display.set_mode () with different values. The variability that refers to the display screen will continue to be used, as it will change its link to a new one. After completing the scene, you can reduce the window back in the same way.

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

What basically happens is that you run the loop, and each iteration is the rendering and display of the new frame. When you call a function inside a loop, it does not continue to work until you finish executing the function.

One way to solve this problem is to simply call a function that updates the battle scene in the main loop. Another way is to use threads. Threading basically runs multiple scripts ("Threads") at the same time.

Fortunately, python has already implemented this for us using the streaming module. It takes me too long to explain the module here, but you can find out here here . It can be a little tricky if you haven't used threads before, but after a while it will be easier. And if you want to know more about streaming you can go here .

Specifically, here you can have two threads: one for each cycle / window and run them at the same time.

I hope I helped you!

+1
source

Source: https://habr.com/ru/post/918501/


All Articles