TAGS :Viewed: 8 - Published at: a few seconds ago

[ Use pygame to open popup game without closing everything? - Python ]

I am an amateur programmer. I have a small (and urgent) problem. I am working on a text (console) based adventure game for fun. At a certain point, I want a pygame window to open. The player has to click in the window as fast as possible. The reaction time should be returned to the main program, and the pygame window should close. The main program will then continue running.

I've already written the script for the pygame window and it works fine. My main program also works fine. Now how do I call the pygame window from the main program?

I tried importing the pygame script but that didn't work.


Here's my pygame script:

import pygame, sys, time
from pygame.locals import *


#Set up window
screen = pygame.display.set_mode((300,200))
shape = screen.convert_alpha()
pygame.display.set_caption("Sniper Alert")

WHITE = (255, 255, 255)
BLACK = (0,0,0)
RED = (255, 0, 0)

#Draw on surface object

def alert():
    #Create a font
    font = pygame.font.Font(None,50)

    #Render the text
    text = font.render("Sniper Alert", True, RED)

    #Create a rectangle
    textRect = text.get_rect()

    #Center the rectangle
    textRect.centerx = screen.get_rect().centerx
    textRect.centery = screen.get_rect().centery

    #Blit the text
    screen.blit(text, textRect)

    return press()

def press():
    t0 = time.clock()
    dt = 0

    while time.clock() - t0 < 1.5: 
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONDOWN:
                dt = time.clock()- t0
                return dt


#Run the game loop
while True:
    for event in pygame.event.get():
        if event.type == QUIT:

Answer 1

There are three ways I can think of. Here they are:

Solution Number 1:

This way is probably the worst solution and the hardest to implement, but lets get it out of the way. I wouldn't advise using it but you may want to in some circumstances. You could use the threading module. Threading is designed for multitasking like this, and would do what you want. You can create a new thread like so:

import threading

def DoSomething(a,b,c):         #this function will be called in the background, simultaneously to the main program
    #do something here

apple = 1
banana = 2
cat = 3
mythread = threading.thread(target=DoSomething,args=(apple,banana,cat))   #defines a thread
mythread.start()   #tells the thread to start running

Solution Number 2

A much better way to do this would be just to launch it as a different program. You could do that with the subprocess module, used for running command line commands. This would effectively run the program as if you had executed it in a new tab of your terminal (without the new tab). You can then make the program able to communicate with yours using subprocess.comunicate(). I will connect the input and output of the pygame program to your main program from here. Here is an example of this:

import subprocess

input = <insert input>                    #when you run the program and it requires something like a raw_input, this will give it input. You could probably avoid needing to send the pygame program input, because all you really want to do is receive an output from it.

process = subprocess.Popen(["python","<popup filename>"],stdin=subprocess.PIPE,stdout=subprocess.PIPE,shell=False)    #this function is how subprocess runs shell/command prompt commands. On a side note, if you simply want to run a shell command without accessing input or output, just use "subprocess.call(<list of words in command (so ls -a would be ['ls','-a'])>)"
output = process.communicate(input)[0]    #this will return any output the program prints, meaning you can communicate with the program and receive information from it

Using subprocess is probably the best way.

Solution Number 3

The final option, if you want it all in one file and do not want to mess around with threading, would be just to alternate the two programs in a while loop. Basically, you would run a loop that executes code from both programs. This is how it would work:

while True:           #an infinite loop. it doesn't necessarily have to be infinite.
    #call methods or run code to maintain text based game
    #call methods or run code to maintain pygame window

this has worked just fine for me in a pygame game i made which also had a text component, but the subprocess way is probably better...