How to set a cooldown on tkinter keybind input - python

In a basic graphical application I've been working on, there's a problem where holding down a key sends keyboard input extremely quickly, to the point where trying to slow it down with some kind of cooldown doesn't work.
It does work if the cooldown is substantial (>2 seconds cooldown), which is unacceptable for a lot of games.
For any program that automatically links a keypress to a root.move statement will allow extreme speeds across the screen.
Is there a way to limit keypress inputs? If not, is there a way to remove/cancel out the excessive inputs?

This won't be consistent across platforms or other computers due to different input speeds, but using a simple counter to ensure it only fires once every 3 times is more than enough to slow it down to reasonable speeds.
lcounter=0
def left(event):
global leftv,lcounter
leftv=True
if lcounter==2:
playercoords[0]-=1
render(playercoords[0],playercoords[1]+30)
lcounter=0
else:
lcounter+=1
`

Related

how to press the key automatically in the game?

sorry in advance for my bad english.
I'm writing a game automation program , specifically the game requires a key press to start doing (something) , but when i use KeyBoard.press() function from KeyBoard module i have problem where game doesn't recognize my key i tried in game chat box and it still works , it means the key is still pressed down but the game doesn't pick up , i tried using some other functions like " KeyBoard.press_and_release() , KeyBoard.send() " and some other modules but the result is the same,
here is the example code
While True:
if (...):
keyboard.press('e')
keyboard.release('e')
but what confuses me is when i add time.sleep() between the press and release commands it works but what confuses me is when i add time.sleep() between the press and release commands it works but there is a big delay
Anyone have any solution for me?
While True:
if (...):
keyboard.press('e')
time.sleep(0.05)
keyboard.release('e')
If I understand properly (and, I might not, sorry) it could be an issue with the game rather than python. Some games, especially online games, implement features specifically to stop automation.
Have you tried your code in a different context - another game or, seeing as it simulates key presses, a text editor? I think you are saying it works in the chat box but not for game control inputs. If it works as intended outside of the game but not inside that would suggest the problem is something to do with how the game handles key presses.
In that while loop, you might be simulating 20 key presses a second, while a more usual average would be between about 5 and 7 with the world record reported at 16. Perhaps the game detects if the rate is too high and discounts those key presses. Also, a physical keyboard will be subject to repeat rate and repeat delay, which the game may be testing to specifically try and eliminate this type of virtualized automation. Or, something else entirely - without knowing which game you are trying to automate I am left with guess work.
That said, with your reference to an in-game chat box, I strongly suspect you are trying to automate an online multi-player game. Even if you are just doing it for your own personal interest (and not to get an advantage over other players), that kind of thing is frowned upon and can potentially get your game account banned. I would normally suggest you share which game you are trying to automate with the community to get more specific information, but I doubt you will be happy to do that.

How to do a thing if user does something with a certain time limit?

I'm trying to make a 3D game but right now just jumping, I have got the jumping working, but I want to do a thing that (for example if speed=10) but if space is pressed 2x within (for example 0.5 seconds) the speed will go up by (for example 2) and if the player doesn't jump 2x times within the 0.5 seconds the speed stays/resets to normal.
So to simplify character speed becomes faster if you press space in certain time and if you don't for it stays 10, for example if I press space/jump and after 1 second do the same, the speed won't go up, but if I press space/jump within seconds <= 0.5 seconds the speed will go up, until I don't press it within the time, so if I stop pressing it within seconds <= 0.5 seconds the jump resets to 10 and if I jump --> 0.6 seconds =< seconds the speed stays the same.
And to people who don't know ursina, its a python based game engine and you modify the player using this type
----> player=FirstPersonController(gravity = (1), speed=10)
(Not sure but I think the engine is fully based on Python. Just so you know.
The engine I'm learning in is "Ursina Engine"
Sounds like you need to save the timestamp whenever the space is pressed. Then, every time it is pressed, before updating the timestamp, compare now against the previous timestamp... if it is less than 500ms, then speed up!
Reacting to the user doing nothing is harder. I have not used ursula, and a quick look at the documentation, I do not see much in the Ursina Engine to help you.
But I have an idea you could try? When the character is sped up, create an invisible wall to hit. Set the wall up exactly where the character will be in 500ms time, if the user does nothing, they will "collide" with the wall and it will trigger your routine to reduce the speed. If the user does do something, remove the wall. Just an idea. Not sure if that will work. Enjoy!

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.

How to only log valid key presses in simple Psychopy experiment

I'm new to Python and I'm programming a simple psychology experiment. In a nutshell, I'm presenting participants with a series of randomized images and having them to press one key if they detect a face in a given image.
One of my problems is that the program crashes when participant presses the key too fast - that is, I've noticed that the program logs responses even if the participant is pressing a key when there is no image present. Each image will only be present on the screen for 10 seconds. Participant usually takes ~0.5 second on average to make a response.
Is there a key for me to program the experiment so that that Psychopy will only log key presses ONCE, AFTER image is presented on screen? I've pasted my code below.
Thanks so much.
StimList=['Face1.png','Face2.png',]
StimList.extend(['Noise1.png','Noise2.png'])
# randomize lists:
numpy.random.shuffle(StimList)
outstr=""
for TrialNo in range(len(StimList)):
# load our image:
img=visual.ImageStim(
win=win,
image=StimList[TrialNo],
)
# draw the fixation cross and wait for trial start:
win.flip()
time.sleep(1) # wait 1 second on fixation cross
# start a trial: loop until a key has been pressed (or trial times out)
FaceDetected=0 # same as false
Responded=0 #revise
timer=core.Clock()
timer.reset()
while (not Responded) and (timer.getTime()<TimeOut): #remove not responded
img.draw()# outside loop
win.flip() #outside loop
keys=event.getKeys(keyList=['y','Y', 'n','N'], modifiers=False, timeStamped=timer)
if keys:
if (keys[0][0]=='y') | (keys[0][0]=='Y'):
FaceDetected=True
Responded=True
RT=keys[0][1]
elif (keys[0][0]=='n') | (keys[0][0]=='N'):
FaceDetected=False
Responded=True
RT=keys[0][1]
outstr=outstr+str(TrialNo)+", "+ StimList[TrialNo] +", "+str(FaceDetected)+", "+str(RT)+"\n"
print(outstr)
# first open the file:
outfile=open('tmpdata.csv', 'w')
outfile.write(outstr)
outfile.close()
win.close()
There are a bunch of Python issues with the code above, which I suspect are due to negative transfer from another programming language. For example, in Python you should use or in logical comparisons, not |, which in Python is the operator for bitwise 'OR', a different beast. Also, you might want to try out the more Pythonic for TrialNo, stimulus in enumerate(StimList): in place of for TrialNo in range(len(StimList)):, and avoid standard Python functions like time.sleep() when you could have more precise control using PsychoPy's timing classes or screen refresh counting.
But in PsychoPy API-specific terms relevant to your main question, you need to call event.clearEvents() prior to first drawing your stimulus (e.g. when you reset the trial timer). That will clear the keyboard buffer of any previously-pressed keys.
In further PsychoPy-specific hints, avoid creating objects repeatedly. e.g. the timer only needs to be created once, at the start of the script. Then you just reset it once per trial. At the moment, the reset is actually redundant, as the timer is zeroed when it is created. Timers are simple and multiple creation doesn't really impact performance, but stimuli are more complicated and you should definitely avoid creating them over and over again. e.g. here just create your image stimulus once. Then on each trial, just update its image property. That itself takes time to do, as the file needs to be read from disk. So ideally you would be doing that during the fixation stimulus period, or between trials as it is currently.
Your code really shows a few issues rather than just the one you raised in the question. hence, you might find the forum at https://discourse.psychopy.org more useful than the single question and answer format here at SO.

Pygame and Multiprocessing Strategy

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.

Categories

Resources