0

I'm trying to create a pygame program with a 2d drawable grid and methods that run for a long time. I want the main game loop to be able to process while the methods are running so I opted for the threading module and it worked fine but I found out that the multiprocessing module is better suited for CPU-heavy programs so I wanted to switch. The code below is an example or representative of my actual code

# importing the necessary libraries

class Board:
    # class representing the actual 2d grid or board on screen

class Graph:
    # class for drawing methods that take a long time to run
    # Graph's methods call q.get() to get the Board object then 
    # make appropriate changes to it then call q.put() to put it back in the Queue

def draw_board(surface, rects):
    # surface: pygame.display
    # rects: list of pygame rectangle objects
    # draw every rectangle in rects to the display surface.

def main():
    # main game loop
    board = Board(*args)
    q = multiprocessing.Queue()
    q.put(board)
    graph = Graph(q)
    while True:
        draw_board(*args)
        for event in pygame.event.get():
            # checking some conditions and keypresses here
            elif event.type == KEYDOWN:
                if event.key == pygame.K_r:
                   t = multiprocessing.Process(target=graph.draw_sth)
                   t.start()
        pygame.display.update()
        # fps clock ticks for 60 FPS here

if __name__ == "__main__":
    main()

I use multiprocessing.Queue to transfer resources from the main process to the processes spawned inside main() and back. When I run this and click the key "r", nothing happens and the terminal prints the introduction line when main is first called, namely

pygame 2.0.1 (SDL 2.0.14, Python 3.9.5)
Hello from the pygame community. https://www.pygame.org/contribute.html

This doesn't happen when I use threading so I assume that this is due to my usage of Queue or I might have misunderstood and misused multiprocessing instead. Any help is appreciated on the matter. For simplicity, some lines of code have been omitted.

endeavor
  • 145
  • 4
  • Apparently pygame does not support multi processing very well or there are specified rules you have to follow –  Aug 26 '21 at 22:56
  • @user16038533 can you provide me with materials about said rules ? – endeavor Aug 26 '21 at 23:01
  • Its just something I read somewhere and I am not familiar with it myself. It might not be entirely correct. Just thought I would let you know in case something doesn't work and you have no idea why, you will have something to investigate. –  Aug 26 '21 at 23:12
  • You can suppress the "Hello from the pygame..." message. https://stackoverflow.com/questions/51464455/why-when-import-pygame-it-prints-the-version-and-welcome-message-how-delete-it – Oli Aug 27 '21 at 00:14
  • the reason it prints the prompt again is because the spawned process runs the whole script again, meaning it imports pygame which in turn prints the prompt, now it would be great if you provided a [mre], second, all your runnable code (imports not really since they should be safe) that you don't want the other process to run should be put in a function or sth, basically in the `if __name__ == '__main__':` block, third, would be great if you showed the `draw_sth` method of `Graph` class, also please provide a [mre] so that we fully can understand the problem – Matiiss Aug 27 '21 at 05:36
  • 1
    All direct interactions with pygame have to happen inside a single Process (and even a single Thread). It will be very hard to impossible to split it up over multiple, unless you reimplement the rendering stuff yourself and pass around `numpy` arrays or something. Non-rendering stuff that doesn't need pygame should be run in a way so that pygame is not even imported. – MegaIng Aug 27 '21 at 15:53
  • @MegaIng i did this successfully with `threading` but not `multiprocess` – endeavor Aug 28 '21 at 17:24
  • @endeavor That changes nothing I said. – MegaIng Aug 28 '21 at 17:50
  • @endeavor If you got it working split over multiple Threads, you got lucky. – MegaIng Aug 28 '21 at 18:02
  • [This is btw the first result for pygame multiprocessing](https://stackoverflow.com/questions/66018977/using-multiprocessing-with-pygame) – MegaIng Aug 28 '21 at 18:25

1 Answers1

0

Try calling this function before your event loop. ( I don't know if this will apply to multiprocessing )

def continue_pygame_loop():
    pygame.mainloop(0.1)
    yield

This post can do a better job of explaining the mechanics behind it : pyGame in a thread

Luth
  • 51
  • 1
  • 3