I'm working on a laser tag game project that uses pygame and Raspberry Pi. In the game, I need a background timer in order to keep track of game time. Currently I'm using the following to do this but doesnt seem to work correctly:
pygame.timer.get_ticks()
My second problem is resetting this timer when the game is restarted. The game should restart without having to restart the program and that is only likely to be done with resetting the timer, I guess.
What I need, in brief, is to have a background timer variable and be able to reset it any time in a while loop.
I'm a real beginner to python and pygame, but the solution of this problem will give a great boost to my knowledge and the progress of the project. Any help will be greately appreciated.
You don't necessarily need Pygame for this -- time.time() should work just as well as pygame.time.get_ticks(), though it reports seconds since the Unix Epoch instead of milliseconds since the Pygame was initialized.
You want to measure the time has elapsed since the last reset (or since the game started, which you can think of as the first reset). The two functions you've got both return the time elapsed since some arbitrary reference point. The simplest way to achieve this to keep a variable t0. This variable will hold the time value at the last reset (or game start).
Here's an example that loops infinitely and constantly prints the value of such a timer, resetting it whenever it reaches 3 seconds:
# import the builtin time module, this is always available
import time
# initialize the t0 variable, "starting the stopwatch"
t0 = time.time()
while True:
# calculate the time since some reference point (here the Unix Epoch)
t1 = time.time()
# calculate the difference, i.e. the time elapsed
dt = t1 - t0
if dt >= 3:
print "Three seconds reached, resetting timer"
t0 = t1
else:
print "Time elapsed is", dt, "seconds"
If you want to get to know the object-oriented features of Python, this is a good opportunity for an exercise. The above behaviour can be neatly encapsulated in a Stopwatch class, e.g. with get_seconds() and reset() methods.
If you write such a class, your high-level timing logic code can be very simple and readable:
my_timer = Stopwatch()
print my_timer.get_seconds(), "seconds have elapsed since start/reset"
my_timer.reset()
The details of the underlying implementation are hidden away in the code for the Stopwatch class.
After pygame.init() is called the pygame timer starts.
So suppose you run your program once and then start making different game sessions in the same run then you can use a reference variable to keep track of timer and resetting it.
Example:
#your game
import pygame
from pygame import time as T
#do your stuffs
pygame.init()
while True: #this loop never ends and you want to reset timer in this loop if I am not wrong.
if(new_session):
tim_var=T.get_ticks()
new_session=0
#do your stuffs
print 'time elaspsed in this session upto now '+str(T.get_ticks()-tim_var)+' millisecs'
if(game_ended):
new_session=1
#restart_your_new_game by resetting your variables or whatever
Related
I am having a python function that has loop which may fall into infinte loop.
I want to kill the function and print error if it exceeds the time limit let's say 10 sec.
For eg. this is the function that contains infinite loop
def myfunc(data):
while True:
data[0]+=10
return data
data=[57,6,879,79,79,]
On calling from here
print(myfunc(data))
I want it to completely kill the process and print the message. I am working on windows.
Any reference or resource will be helpful.
Thanks
Maybe you can try with func-timeout Python package.
You can install it with the following command:
pip install func-timeout
This code will resolve your problem "I want to kill the function and print error if it exceeds the time limit let's say 10 sec."
from time import process_time as timer
def whatever(function):
start = timer()
infinite loop here:
end = timer()
(your code here)
if end >= 10:
print(whatever)
return
Breakdown: there are a few options for doing this with the time module
At the start of your program import the method
At the beginning of your (infinite loop) start = timer() will call process_time and save the value as start.
end = timer() will continue to send the call to process_time storing new value
put w/e code you want in your loop
if end >= 10: will keep checking the count each loop iteration
print(whatever)
return will automatically terminate the function by escaping if time runs 10 seconds when it is checked next loop.
This doesn't say "how to stop the process_time" from running once its called idk if it continues to run in the background and you have to stop it on your on. But this should answer your question. And you can investigate a bit further with what I've given you.
note: This is not designed to generate "precision" timing for that a more complex method will need to be found
I'm an amateur coder. I'm working on a small little game for a project in biology, but I have come across an issue in my code. I have a loop that adds +1 to the variable sunlight every two seconds. However, all code below the loop is non-functional now that I have made the loop. I'm guessing it's because it's waiting for the loop to finish. Any way to have the loop always run but allow the code to run through it's sequence at the same time?
print("Game started!")
sunlight = 0
while True:
time.sleep(2)
sunlight += 1
commands = input("Type stats to see which molecules you have, type carbon to get carbon\ndioxide, and type water to get water: ")
if commands == ("stats"):
print("Sunlight: ",sunlight,"")
As you are beginner, i would not recommend to use multithreading or asyncio. Instead just start the time and when user enter "stats", elapsed time//2 will be equal to sunlight.
import time
start_time = time.time()
while True:
commands = input("Type stats to see which molecules you have, type carbon to get carbon\ndioxide, and type water to get water: ")
if commands == ("stats"):
sunlight = (time.time()-start_time)//2 # elapsed time // 2
print("Sunlight: ", sunlight, "")
Your sunlight variable basically functions as a clock; it counts half of the number of seconds since the program begins. Rather than implement your own clock using time.sleep(), it's better to just use an existing clock from the time library.
The function time.monotonic returns a number of seconds, so you can use this to get the current sunlight by saving the start time, then each time you want to know the value of sunlight, take the difference between the current time and the start time, divided by 2.
start_time = time.monotonic()
def get_sunlight():
current_time = time.monotonic()
return int(current_time - start_time) // 2
It is better to use the monotonic() function than the clock() function for this purpose, since the clock() function is deprecated as of Python 3.3:
The time.clock() function is deprecated because it is not portable: it behaves differently depending on the operating system.
It's also better than the time() function for this purpose, because changes to the system clock (such as going forwards or back due to daylight savings time) will affect the result of time():
While this function normally returns non-decreasing values, it can return a lower value than a previous call if the system clock has been set back between the two calls.
You should look into the multithreading library. That's probably a good resource. You can fire off a thread running your sunlight incrementer that updates a global variable (not a good idea but you seem to have just 1 writer, so you can get by till you have time to pick up more advanced parallel processing concepts).
Reference: https://www.geeksforgeeks.org/multithreading-python-set-1/
I am making a Who Wants to be a Millionare game in Python using graphics. I want the user to get 45 seconds per question to answer it. However, whenever I put a timer in my code it waits for 45 seconds first, then lets the user answer, instead of running in the background and letting the user answer at the same time.
Using the threading module to run multiple threads at once
You could use the Python threading module to make two things happen at once, thereby allowing the user to answer while the timer ticks down.
Some example code utilizing this:
from threading import Thread
from time import sleep
import sys
def timer():
for i in range(45):
sleep(1) #waits 45 seconds
sys.exit() #stops program after timer runs out, you could also have it print something or keep the user from attempting to answer any longer
def question():
answer = input("foo?")
t1 = Thread(target=timer)
t2 = Thread(target=question)
t1.start() #Calls first function
t2.start() #Calls second function to run at same time
It's not perfect, but this code should start two different threads, one asking a question and one timing out 45 seconds before terminating the program. More information on threading can be found in the docs. Hope this helps with your project!
Try using time.time(). This returns a the amount of seconds since January 1, 1970 in UNIXTime. You can then create a while loop such that:
initial_time = time.time()
while time.time()-initial_time < 45:
#Code
Hope this helped!
I know this question has been asked before, but I could not find one for pygame. I have a coin power-up that increases my points by 5000 every time it is picked up. However, as soon as I pick up the coin, another one appears. I don't want it to appear for another 30 seconds. How can this be accomplished without pausing the entire program?
if coin.collidepoint(x,y):
points+=5000
coin=makecoin()
Since you are using pygame, you have built in functions.
pygame.time.get_ticks() get time in milliseconds
pygame.time.set_timer() set repeating timer.
Your game has a main loop. When you pick up a coin you should save the time that you picked it up and set coin = None, then in that main loop you should have something like the following:
if coin is None and current_time > coin_picked_up + 30:
coin = makecoin()
I would recommend a timer. It should be as simple as that.
from threading import Timer
if coin.collidepoint(x,y):
points+=5000
t = Timer(30.0, makecoin)
t.start()
Take a look at the sched module. You could use this to defer the creation of the new coin.
Assuming that you have a scheduler called s, defined as follows (just like the example in the Python manual)...
import sched, time
s = sched.scheduler(time.time, time.sleep)
Then you'd schedule your coin to be created like this...
if coin.collidepoint(x,y):
points+=5000
s.enter(30, 1, make_coin, ())
And you'd call s.run() periodically to run anything that is due to be run. It is unlikely that you will need to call it on every tick unless you really need fine grained timing.
i have a loop that runs for up to a few hours at a time. how could I have it tell me how long it has been at a set interval?
just a generic...question
EDIT: it's a while loop that runs permutations, so can i have it print the time running every 10 seconds?
Instead of checking the time on every loop, you can use a Timer object
import time
from threading import Timer
def timeout_handler(timeout=10):
print time.time()
timer = Timer(timeout, timeout_handler)
timer.start()
timeout_handler()
while True:
print "loop"
time.sleep(1)
As noted, this is a little bit of a nasty hack, as it involves checking the time every iteration. In order for it to work, you need to have tasks that run for a small percentage of the timeout - if your loop only iterates every minute, it won't print out every ten seconds. If you want to be interrupted, you might consider multithreading, or preferably if you are on linux/mac/unix, signals. What is your platform?
import time
timeout = 10
first_time = time.time()
last_time = first_time
while(True):
pass #do something here
new_time = time.time()
if new_time - last_time > timeout:
last_time = new_time
print "Its been %f seconds" % (new_time - first_time)
Output:
Its been 10.016000 seconds
Its been 20.031000 seconds
Its been 30.047000 seconds
There's a very hacky way to do this by using time.asctime(). You store the asctime before entering the while loop and somewhere in the loop itself. Calculate the time difference between the stored time and the current time and if that difference is 10 seconds, then update the stored time to the current time and print that it's been running.
However, that's a very hacky way to do it as it requires some twisted and boring math.
If your aim is to check the runtime of a specific algorithm, then you're better off using the timeit module
Hope this Helps