I'm developing a game in pygame and i don't know which tasks should go to which process.
I have two processes connected by a pipe, one will have the window another will do calculations.
My question is: Which parts of the main loop should go to the other process?
In my game i will have to do event handling, collision detection, AI, drawing and heavy calculations(2D lighting system).
I'm afraid that if i put to much stuff on the other process the main one will have to wait for input and the FPS will freeze.
PS: For now i'm just starting to code the game so i can't show you much code.
There is the observer pattern
I would suggest the following architecture for creating a PyGame with two processes:
You divide your program into two parts:
model
all the game logic is kept in the subprocess, computing the whole game.
Whenever there is something noteworthy changed, it notifies the other process.
responsibilities:
update the game e.g. in a loop
do physics
send updates to the gui
gui
The gui is in the main process because it starts several games.
When a game is started it starts to observe important parts of the game.
responsibilities
handle user input e.g. right arrow pressed
send modifications to the model e.g. player walks righth
render views of model elements when updates are received
Note that I do not really know much of PyGame.
But keeping model and view apart is possible.
You can have a look at the MVC pattern, too. But it is really heavy. Just merging View and Controller is enough if the program shall not be distributed across computers.
Then I heard about MVVM pattern. Not sure whether this is too much again since you only need to split your game into two parts and not three.
Related
So I'm very new to Python so I'm not sure of the correct way to do what I need.
Basically I am creating a laser tag game. The whole game is controlled by some python code that runs on a PC, the hardware is basically just inputs and outputs for this code.
I want to have game files that are simple files with just the code for the game itself, that way it is fairly easy for anyone to make their own game modes.
Then there needs to be a main program with a GUI (Probably Tkinter) and code to handle sending/receiving information from the hardware (Laser tag guns). I need some way to select a game file from the GUI and run it, but I still need the main server code to be running (to take care of sending and receiving information from the guns, displaying live scores on the GUI, etc).
What would be the best (preferably fairly simple) way to go about doing something like this? Thanks!
Cool project! Generally you let TkInter run in the main thread, and have the other tasks executed in other threads or processes. Brace for some hacking, parallelism is unfortunately pretty difficult to do right.
I was experimenting with pygame and noticed it raised a VideoExpose event when I press alt+tab and the window is fullscreen. when I switch press alt+tab again, everything on the screen is moved to the bottom left.
I know that this is supposed to mean that 'portions of the window must be redrawn', but how am I supposed to redraw them and what why does pygame even have this event in the first place?
If you are writing a program to use the windowing Event Model, the windowing environment sends the program events to notify it of environmental changes - window resize, mouse move, need to re-paint, etc.
Not handling these events will cause your application to be considered "non responsive" by the environment. Here on SO, there's about one question a week with PyGame and exactly this issue.
When working with PyGame re-drawing event handling may seem superfluous as the majority of PyGame games redraw the entire screen every frame, e.g.: 60 FPS. But if unnecessary, this method is a complete waste of resources (CPU-time, electricity, etc.) It is quite simple though, so good for beginners.
Say you were writing a card game like Solitaire... the screen updates only when interacting with the user. In terms of CPU, it's doing nothing 99.9% of the time while the user contemplates their next move. In this case, the program could be written to only re-draw the screen when necessary. When is it necessary? When the player gives input, or the program receives a pygame.VIDEOEXPOSE event from the widowing environment.
If your program is redrawing the window constantly, you can simply ignore the message. If not, when receiving the message call whatever block of code is normally used to render the window. The expose message may come with the region of the screen that needs to be re-drawn, in this case a really good application would only update that section of the display.
Hey I started to use the graphical orange canvas toolbox for data mining. Connecting nodes on the workspace can cause the execution of the associated tasks. I know that these automatic apply can be disabled, but in the case I missed that and accidently start a realy heavy process like outliner detection on a big dataset is there a way to stop the current pipeline task without killing the hole system process?
Unfortunately there is no such stopping functionality in Orange yet.
The developers of Orange are working towards making widgets compute in threads, which can let us control stopping. The Test & Learn widget, for example, already works in a separate thread. There, if the user changes options while widget is already working, it stops the current computation and starts a new one. But even there, there is no GUI option to just stop the computation.
I am building an app that, when the user hits a 'run' button, generates a table of buttons.
Because this process takes a while, I want to add a popup or progress bar to alert the user that the function is running and not frozen. To do this I decided to create a popup and call my function using threading so that the screen will be updated when the function starts (as opposed to once it is done).
mythread = threading.Thread(target=run_function)
mythread.start()
The trouble is that when I call my function from the above code it works very strangely: the columns of my table are the wrong width, some of my buttons are arbitrarily empty, and others have the wrong fill color. To fix this, all I need to do is to remove the threading operation and simply call run_function()
Any idea why this is happening?
I am new to Python, so it is likely some dumb mistake, but I have no idea. What is different between a process running as a thread and its default operation?
Disclaimer: I haven't worked with Kivy.
Not every framework works well with multithreading.
But most of the GUI frameworks have an event loop which is responsible for managing user events (mouse clicks, keyboard) and queued drawing operations (widgets).
In your case if don't want the UI to be freezed, you should regularly give control to your framework's event loop.
I guess kivy.base.EventLoopBase.dispatch_input is what you need to call to show an added widget or to handle user events.
I am writing an app in kivy which does cpu-heavy calculations at launch. I want the app to display what it's doing at the moment along with the progress, however, since the main loop is not reached yet, it just displays empty white screen until it finishes working. Can I force kivy to update the interface?
Basically I'm looking for kivy's equivalent of Tkinter's root.update()
I could create a workaround by defining a series of functions with each calling the next one through Clock.schedule_once(nextFunction, 1), but that would be very sloppy.
Thanks in advance.
Leaving aside the question of whether you should be using threading or something instead (which possibly you should), the answer is just that you should move your cpu calculations to somewhere else. Display something simple initially (i.e. returning a simple widget from your build method), then do the calculations after that, such as by clock scheduling them.
Your calculations will still block the gui in this case. You can work around this by doing them in a thread or by manually breaking them up into small pieces that can be sequentially scheduled.
It might be possible to update the gui by manually calling something like Clock.tick(), but I'm not sure if this will work right, and even if so it won't be able to display graphics before they have been initialised.