Pygame running differently from different python interpreters - python

I recently wrote my first pygame program and am working on a second, and discovered an issue with running the program. I use the editor MuEditor for Python 3.8.6, and when I run the game using this editor it works exactly how I want it to. Although, if I run the program from ANY other editor such as IDLE or PyCharm, it ramps up the game speed and displays the fonts incorrectly, making the game much more difficult to play. My friend wants to be able to play the games I write, so I sent him the code through an email and they ran it through MuEditor, and it still worked incorrectly. The game only runs how it should when I run it from my computer in MuEditor, and I was wondering if anyone else has had this problem or if there's a fix for it? I highly doubt the error here is in my code, but I can provide it if necessary.

Use pygame.time.Clock to control the frames per second and thus the game speed. See pygame.time.Clock.tick():
This method should be called once per frame. It will compute how many milliseconds have passed since the previous call.
The method tick() of a pygame.time.Clock object, delays the game in that way, that every iteration of the loop consumes the same period of time.
That means that the loop:
clock = pygame.time.Clock()
run = True
while run:
clock.tick(60)
runs 60 times per second.

Related

Multiprocessing with Pyglet opens a new window

I am making turn based game in python using Pyglet. The game has a player-vs-AI mode in which the bot calculates a move to play against the player. However, the function which calculates the bot's move takes around 3-5 seconds to run, blocking the game's UI. In order to get around this, I am running the bot's calculation on a second process using multiprocessing.Process. I got it to work well without blocking the UI, however every time I open the second process to run the function a new Pyglet window opens, then closes again when the process is closed. Is there any way to open a second process in a Pyglet program without a second window opening? Let me know if examples of my code is required, and I will try to come up with similar code to share. Thanks in advance to anyone who can help.
You can fix the problem by moving the initialization of the window inside of the main block

Webots NAO controller sequence not working

I am using the NAO_demo_python controller of the latest version of webots on linux (ubuntu 18) to flash leds and open/close the hands.
However only the last part of the sequences are executed, and not in a single simulation run.
e.g. if i ask to just open the hand and light the leds, after 1 run the lights will be on and after 5 runs of the main while loop it will be opened -reaaallly slowly-. However if i ask lit leds, open hand then close hand unlit leds then the simulation will only close hand and unlit leds.
The code should be working, it is on another person's computer. In case you want it here it is (it's really basic, it's a slight modification of nao-demo-python.py):
def run(self):
while robot.step(self.timeStep) != -1:
self.setAllLedsColor(0xff0000) #red leds on
self.setHandsAngle(0.96) #open hand
#rospy.sleep(5) #originally i am to use webots and nao with ros
print("done") #to check how many runs are made
self.setHandsAngle(0.0) #close hand
self.setAllLedsColor(0x000000) #red leds off
Also, something that may be interesting: if i ask to open close the hand N times and each time print something, all the prints will be printed at once and the simulation time jump from 0:0:0 to 0:0:20 after each main loop run (+20 at each run), else, even if the simulation runs the time doesn't flow, it jumps.
I tried to update my drivers, to take off all shadows and stuff from the simulation, as webots advices. No can do. I couldn't find something on Softbank, i can't find an active forum concerning nao and webots anymore...
I have an i5 9th gen and a GTX1050Ti.
May the problem be that the simulation time isn't 1.0x? but at most 0.05x? (after taking off shadows, effect of lights, all objects, using 1 thread etc, as explained here: https://www.cyberbotics.com/doc/guide/speed-performance)
SUMMARY: Only the last sequence of the controller is executed, and if it's a motion it takes several main loops before being fully executed. Meanwhile the time jumps from 0 to +20s after each main loop run.
May someone help me out to make all the sequence work on simulation please :)
all the prints will be printed at once
Only the last sequence of the controller is executed
It sounds like the setHandsAngle function might be asynchronous (doesn't wait for the hand to move to that point before running the next piece of code)? This could be responsible for at least some of the problems you're experiencing. In this case the rospy.sleep(5) should be replaced with robot.step(5000), so the simulator has time to move the hand before sending the next command.
Thank to your indications, this works:
self.CloseHand = Motion('../../motions/closeHand.motion')
def startMotion(self, motion):
if self.currentlyPlaying: #interrupt current motion
self.currentlyPlaying.stop()
motion.play() #start new motion
self.currentlyPlaying = motion
self.startMotion(self.CloseHand)
while not self.CloseHand.isOver():
robot.step(self.timeStep)
And in the CloseHand.motion :
#WEBOTS_MOTION,V1.0,LPhalanx1,RphalanxN (until 9)
00:00:000,Pose1,0.00,0.00 etc
with 00:00:000 the moment of execution and 0.00 the angle of the hand (phalanx by phalanx).
THANK you very much! I couldn't have realized that without your advice.
The synchronization webots/ros is still unresolved but the issue of my initial question is. Thank you!

How can I use Python to detect when my computer/a program is lagging?

I wrote an automated code that basically takes some text from a PDF and then pastes it in a different program. This involves controlling my mouse and keyboard in order to work properly. The code runs fine, but sometimes my computer, or I guess the program I'm using (it's a program run through Citrix) lags a little. When this happens, my code still runs, but because the program is momentarily frozen, it can't click and type correctly.
Is there a way to detect when the program is lagging so that I can pause the code for a few seconds to allow the program to unfreeze? I couldn't find anything similar online
I have done something similar (albeit not from python) and if you know that your lag spikes normally last, say, 3 seconds, you may need to implement a waiting time of 4 seconds between actions, so there is a very good chance that your action has been accepted by the receiving software.
This of course will slow down the actions even when there is no spikes, and won't protect you against larger than usual spikes, but it's a start.

Pygame Write to other terminal?

I was wondering if it is possible to write the pygame code to a separate terminal so that you can still do things like print to the terminal. When pygame's display becomes initialized it seems to be impossible to put any input into the terminal. Any way to get around this?
I also want to know that if this is possible can one the other terminal edit the one running pygame to change certain things?
Github
Ok, once you initialize pygame and start your pygame loop in startDisplay() in Commands.py, you are essentially leaving your main() loop in game.py. So your repeated request for input won't happen again. If you want to call for input during the loop in startDisplay() you'll need to do it expressly there. As I stated above, this will pause your game until you enter a command, which obviously isn't very good. You could build a little logic around it and only request input during a break in the action or implement a Pause event (using a key event) which would subsequently call the prompt for a command.

Running Python graphics and code

I have a program that I'm just adding graphics to, but I'm having trouble running my main code along with the graphics. Basically I have something like this:
def mainFunction():
while True:
run code in here
root = Tk()
board = Canvas(root, height=710, width=1000)
board_image = PhotoImage(file="/path/example.jpg")
photo = board.create_image(0,0, anchor=NW, image=board_image)
board.pack()
mainFunction
root.mainloop()
I can only run either the mainFunction or the graphics because whichever one I make run first in the code is the only that runs. It doesn't stop to allow the next code to run. There has to be a simple way to get graphics and code to run together side by side. Thanks!
Use Tk.after_idle() to register a function that will do a piece of the work required. Keep doing piece after piece until all the work is done.
Generally speaking, you cannot put an infinite loop inside a Tkinter application. Why? It's already running an infinite loop: the event loop. Your code is the equivalent of this:
while <there are more events to service>:
while True:
<run code in here>
<get the next event>
<service the event>
See the problem? You're preventing the code from ever servicing events, and events are the life blood of a GUI.
Instead, you need to take advantage of the already-running infinite loop by adding code to be run inside the loop. You do this with after (and after_idle). This will put one even on the queue. If, during the processing of that event you again call after_idle, you've effectively set up an infinite loop that works within the event loop.
For example:
def do_one_iteration(self):
<run code in here>
self.after(100, self.do_one_iteration)
Then, somewhere in your main logic, or in response to a button, you call do_one_iteration. It will do one iteration of your previously-infinite-loop. When it is done it instructs Tkinter to call itself again 100 milliseconds later. When that time period elapses your code is run, it schedules another iteration in 100 milliseconds, etc. etc. You can change the interval to whatever you want; the smaller the interval the faster your code runs, but the greater the chance that you starve the GUI for events.
Note that this only works if <run code in here> runs relatively fast. While it is running your GUI will freeze. If it can complete one iteration in a couple hundred milliseconds then the user will never know. If it takes a second or more it will be noticeable.
Note: this example assumes your main application is an object that inherits from a Tkinter widget. If that's not the case it will still work, you just have to remove the self parameter. An even better solution is to refactor your GUI to use objects -- it's a much more flexible way of implementing GUIs.

Categories

Resources