Is it possible to reset a Timer in PyGame? - python

first time poster here, so I hope you guys can help me :)
I'm working on a project in which I want to play a game of SET. It all works (JEEJ), however I want to be able to use some sort of time function. This will do the following:
at start of game the time starts running
if x:
y
reset timer to zero
elif not x and time == 30:
do some action
I tried a lot of things; using time.time(), but this cannot be reset as far as I know; I found a few stopwatch like classes which I tried using, but they were slow (?); I tried perf_counter()... But now I'm at loss, so I hope any of you may know what to do...
Note that I want to "play" the game and do actions while the time runs...
Many thanks in advance!

There are a few ways to solve this problem. One is using time:
import time
timer_start = time.time()
if x:
y
timer_start = time.time()
if not x and time.time() >= timer_start + 30:
do some action
Note that I use >= because the time is highly unlikely to be exactly 30.0, better to fire it the first time after.
Another way is to use pygame.time.set_timer():
pygame.time.set_timer(pygame.USEREVENT, 30000) #milliseconds
# You cal also use USEREVENT+1, USEREVENT+2 etc. if you want multiple timers
if x:
pygame.time.set_timer(pygame.USEREVENT, 30000) #milliseconds
for event in pygame.event.get(): #merge this with your actual event loop
if event.type == pygame.USEREVENT:
if not x:
y
# reset the timer since it repeats by default
pygame.time.set_timer(pygame.USEREVENT, 0)

Related

How could I make a dash in a 2D pygame python program?

If the pygame program is just a basic entity you can move normally with arrow keys, how could i make it so that if space is pressed, based on the arrow key that was being held at the moment of pressing, a player dashes slightly to the specified direction? My idea is that when the space is pressed, program checks if other keys are being held down and based on that it rapidly increases the x and/or y coordinate and then stops at specific time, but I don't know how to make it stop as all of this is happening inside a main game loop. Any insight is highly appreciated.
You can use time.perf_counter.
So for using that function you will need to import module time
import time
And now you can store the value of time.perf_counter in a variable when space is pressed.
import time
jumping = False
start_time = 0
while True:
if ("space is pressed"): # Replace condition with what you want
jumping = True
start_time = time.perf_counter()
# Add your code here
if jumping:
# change of x, y and other jumping mechanism code here
if jumping and time.perf_counter() - start_time > 1: # Replace 1 with the amount you want this if condition to trigger, also add value in seconds
jumping = False
I'm not sure what your code is like, but this is how I'd go about it:
def dash(self):
keys = pygame.keys.get_pressed()
if keys[pygame.K_SPACE] and not self.dashing and self.jumping:
# ^^ Can be any key
if self.facing_right:
self.x += 20
if self.facing_left:
self.x -= 20
self.dashing = True
Make sure that when you hit the ground it does self.dashing = False else you will be able to dash forever.
Just put this function in the player class if you are doing it OOP.
Else if you are not using classes, put it anywhere in the file and take out all self..

Python Tkinter Tk root.after Delay

I'm trying to do a chess clock using tkinter, and to do so i'm using the root.after method from the class Tk of tkinter. When the program starts, it runs really well, but after a while the clock start to get slower and slower, but if i start shaking my mouse, the clock starts to run fast again. For a clock, time precision is crucial, so i can't afford to run the program in the way that is working now. How can i solve this problem?
def RunClock(self):
"""
Method that runs and change the clock info
"""
#t0 = time.time()
if self.playing:
#Time remaining in milliseconds
clock = self.clock
minutes = clock//60000
clock %= 60000
sec = clock//1000
clock %= 1000
mil = clock//10
#If the turn is of player 1
if self.turn == 1:
self.WriteClock(self.canvas1, self.play1, "%.2i:%.2i:%.2i"%(minutes, sec, mil))
else:
self.WriteClock(self.canvas2, self.play2, "%.2i:%.2i:%.2i"%(minutes, sec, mil))
#tf = time.time()
#deltat = (tf - t0)
#s = 1 - deltat
self.rel -= 1
#if s > 0:
# time.sleep(s/1000)
#else:
# self.rel += s*1000
self.root.after(1, self.RunClock)
Note: The time to run the function is very low (you can calculate it with the commented tf and t0 variables), so i didn't even consider it in the time interval
As Brian pointed out reducing the time interval will likely be the easiest solve to your question. Alternately though, you could try running your timer separately on it's own thread and having it run asynchronously and send it threading events as is discussed here:
Python threading.timer - repeat function every 'n' seconds

How can I add a timer to my game?

I'm working on a game that is sort of like a simple Galaga-esk game. Although, they only move once in a while (something else I can't get working, but that's something different). So, since they don't move on their own, I want a way to add a timer to the game, but I can't seem to find anything on this. Here's what I have for my timer and the surrounding code to reset for each level so far. Will something like this work where I have it?
from livewires import games, color, random, time
start = time.time()
for items in enemies:
items.destroy()
if Enemy_amount > 0:
display_balloons()
elif Enemy_amount == 0 and (time.time() - start <= 120):
start = time.time()
level += 1
Enemy_amount = load_enemies()
#Just telling the code to load the next group of enemies.
The value of start is going to be a number like 1398354442, which is the number of seconds that have passed since January 1, 1970.
If you want to figure out the elapsed time between two events, you'll need to subtract. Perhaps something like this?
elif Enemy_amount == 0 and (time.time() - start <= 120):
start = time.time() # update start variable to the current time

End a loop when current time is something specific

I have asked a question similar to this before, but this time it is a little different. To me, the following code should work.
import datetime
# run infinitly
while(True):
done = False
while(not done):
#
#main program
#
#stopping condition
if currenttime == '103000':
done = True
#continue with rest of program
However, it doesn't continue with the rest of the program when it hits 10:30:00am.
The following program I KNOW works (on a raspberry pi):
import datetime
done = False
while not done:
currenttime = datetime.datetime.now().strftime('%H%M%S')
if currenttime != '103000':
print currenttime
if currenttime == '103000':
done = True
print 'It is 10:30:00am, the program is done.'
It made logical sense to me what I did in that first example. Does anyone know why it won't exit that loop and continue with the rest?
If the main program takes a long time to run, currenttime could jump from 102958 to 103005. Therefore skipping 103000 entirely.
Maybe you need to set currenttime, before you check? Also, the if statement has to execute exactly at 103000 in order for done = True to execute.
while(True):
done = False
while(not done):
#
#main program
#
# need to set current time
currenttime = datetime.datetime.now().strftime('%H%M%S')
#stopping condition (use >= instead of just ==)
if currenttime >= '103000':
done = True
#continue with rest of program
Note that is not guaranteed that your loop has one iteration in each and every available second. The more load is on your system, the larger the likelihood that the loops skips a second, which potentially would be the termination criterion. There are also cases where seconds may be skipped, e.g. due to time synchronization or daylight saving issues.
Instead of a busy waiting loop, you could pre-compute the timedelta in seconds and then sleep for that many seconds.
Advantages:
You'll save computation power that other processes on your machine could use instead.
It probably increases the lifetime of your hardware.
This will also be more energy efficient.
Example:
import datetime
import time
def wait_until_datetime(target_datetime):
td = target_datetime - datetime.datetime.now()
seconds_to_sleep = td.total_seconds()
if seconds_to_sleep > 0:
time.sleep(seconds_to_sleep)
target_datetime = datetime.datetime(2025, 1, 1)
wait_until_datetime(target_datetime)
print "Happy New Year 2025!"
Note that this may still fail to produce the desired behavior due to arbitrary changes of the systems date and time settings. Probably it would be best to adopt a completely different strategy to execute a specific command at a specific time. Have you considered implementing the desired behavior using a cron job? (You could send a signal to the process and thereby issue it to cancel the loop...)
import datetime
done = False
while True:
currenttime = datetime.datetime.now().strftime('%H%M%S')
if currenttime >= '103000':
break
print currenttime
print 'It is 10:30:00am, the program is done.'
If you can't use break:
import datetime
done = False
while not done:
currenttime = datetime.datetime.now().strftime('%H%M%S')
if currenttime >= '103000':
done = True
else:
print currenttime
print 'It is 10:30:00am, the program is done.'

pygame.time.set_timer confusion?

So, I have a problem, I don't fully understand the event that is needed to be given to a timer command anyway, it doesn't say anywhere online, to where I searched for hours. So I just used what most people seemed to be using 'USEREVENT + 1'. I'm not sure if it is correct, but my timer is not working. Am I using it correctly? Here is my code:
nyansecond=462346
nyanint=0
spin=0
aftin=452345
def nyanmusic(nyansecond,nyanint,spin):
if nyanint == 0:
nyansound.play()
nyanint= 1
elif nyanint == 1:
nyansecond = pygame.time.set_timer(USEREVENT+1,7000)
if nyansecond < 200 and spin == 1:
spin = 0
nyansecond = pygame.time.set_timer(USEREVENT+1,7000)
elif nyansecond > 6500 and nyansecond < 100000 and spin == 0:
spin = 1
nyansoundm.play()
return nyansecond,nyanint,spin
I then def it into my code on the second page I implemented (which works fine). It runs the nyansound, but doesn't run nyansoundm after 6.5 seconds (6500 milliseconds). I'm making this program to help me learn the basics of python and pygame, before moving on to more complex stuff. I can also use it when I want to listen to nyan cat or other looped songs without having to go on youtube and waste precious bandwidth. Don't worry about that, though.
Oh, and here is the code I have put into my loop, although I do not think this matters too much:
#music
nyansecond,nyanint,spin = nyanmusic(nyansecond,nyanint,spin)
Let's recap what pygame.time.set_timer does:
pygame.time.set_timer(eventid, milliseconds): return None
Set an event type to appear on the event queue every given number of milliseconds. The first event will not appear until the amount of time has passed.
Every event type can have a separate timer attached to it. It is best to use the value between pygame.USEREVENT and pygame.NUMEVENTS.
pygame.USEREVENT and pygame.NUMEVENTS are constants (24 and 32), so the argument eventid you pass to pygame.time.set_timer should be any integer between 24 and 32.
pygame.USEREVENT+1 is 25, so it's fine to use.
When you call pygame.time.set_timer(USEREVENT+1,7000), the event with eventid 25 will appear in the event queue every 7000ms. You didn't show your event handling code, but I guess you do not check for this event, which you should do.
As you can see, pygame.time.set_timer returns None, so your line
nyansecond = pygame.time.set_timer(USEREVENT+1,7000)
doesn't make sense since nyansecond will always be None, and hence comparing it against an integer
if nyansecond < 200 ...
is pointless.
If you want to play a sound every 6.5 seconds using the event queue, simpy call pygame.time.set_timer once(!):
PLAYSOUNDEVENT = USEREVENT + 1
...
pygame.time.set_timer(PLAYSOUNDEVENT, 6500)
and check the event queue for this event in your main loop:
while whatever: # main loop
...
# event handling
if pygame.event.get(PLAYSOUNDEVENT): # check event queue contains PLAYSOUNDEVENT
nyansoundm.play() # play the sound

Categories