[python] Timer for Python game

I'm trying to create a simple game where the point is to collect as many blocks as you can in a certain amount of time, say 10 seconds. How can I get a timer to begin ticking at the start of the program and when it reaches 10 seconds, do something (in this case, exit a loop)?

This question is related to python time

The answer is


This is the Shortest Way I know of doing it:

def stopWatch():
        import time
        a = 0
        hours = 0
        while a < 1:
            for minutes in range(0, 60):
                for seconds in range(0, 60):
                    time.sleep(1)
                    print(hours,":", minutes,":", seconds)
        hours = hours + 1

The threading.Timer object (documentation) can count the ten seconds, then get it to set an Event flag indicating that the loop should exit.

The documentation indicates that the timing might not be exact - you'd have to test whether it's accurate enough for your game.


New to the python world!
I need a System Time independent Stopwatch so I did translate my old C++ class into Python:

from ctypes.wintypes import DWORD
import win32api
import datetime

class Stopwatch:

    def __init__(self):
        self.Restart()

    def Restart(self):
        self.__ulStartTicks = DWORD(win32api.GetTickCount()).value

    def ElapsedMilliSecs(self):
        return DWORD(DWORD(win32api.GetTickCount()).value-DWORD(self.__ulStartTicks).value).value

    def ElapsedTime(self):
        return datetime.timedelta(milliseconds=self.ElapsedMilliSecs())

This has no 49 days run over issue due to DWORD math but NOTICE that GetTickCount has about 15 milliseconds granularity so do not use this class if your need 1-100 milliseconds elapsed time ranges.

Any improvement or feedback is welcome!


As a learning exercise for myself, I created a class to be able to create several stopwatch timer instances that you might find useful (I'm sure there are better/simpler versions around in the time modules or similar)

import time as tm
class Watch:
    count = 0
    description = "Stopwatch class object (default description)"
    author = "Author not yet set"
    name = "not defined"
    instances = []
    def __init__(self,name="not defined"):
        self.name = name
        self.elapsed = 0.
        self.mode = 'init'
        self.starttime = 0.
        self.created = tm.strftime("%Y-%m-%d %H:%M:%S", tm.gmtime())
        Watch.count += 1

    def __call__(self):
        if self.mode == 'running':
            return tm.time() - self.starttime
        elif self.mode == 'stopped':
            return self.elapsed
        else:
            return 0.

    def display(self):
        if self.mode == 'running':
            self.elapsed = tm.time() - self.starttime
        elif self.mode == 'init':
            self.elapsed = 0.
        elif self.mode == 'stopped':
            pass
        else:
            pass
        print "Name:       ", self.name
        print "Address:    ", self
        print "Created:    ", self.created
        print "Start-time: ", self.starttime
        print "Mode:       ", self.mode
        print "Elapsed:    ", self.elapsed
        print "Description:", self.description
        print "Author:     ", self.author

    def start(self):
        if self.mode == 'running':
            self.starttime = tm.time()
            self.elapsed = tm.time() - self.starttime
        elif self.mode == 'init':
            self.starttime = tm.time()
            self.mode = 'running'
            self.elapsed = 0.
        elif self.mode == 'stopped':
            self.mode = 'running'
            #self.elapsed = self.elapsed + tm.time() - self.starttime
            self.starttime = tm.time() - self.elapsed
        else:
            pass
        return

    def stop(self):
        if self.mode == 'running':
            self.mode = 'stopped'
            self.elapsed = tm.time() - self.starttime
        elif self.mode == 'init':
            self.mode = 'stopped'
            self.elapsed = 0.
        elif self.mode == 'stopped':
            pass
        else:
            pass
        return self.elapsed

    def lap(self):
        if self.mode == 'running':
            self.elapsed = tm.time() - self.starttime
        elif self.mode == 'init':
            self.elapsed = 0.
        elif self.mode == 'stopped':
            pass
        else:
            pass
        return self.elapsed

    def reset(self):
        self.starttime=0.
        self.elapsed=0.
        self.mode='init'
        return self.elapsed

def WatchList():
    return [i for i,j in zip(globals().keys(),globals().values()) if '__main__.Watch instance' in str(j)]

  1. Asks you when to stop [seconds]
  2. Adds '0' at starting [1-9]
import time
import sys

stop = int(input('> '))
second = 0
print('> Stopwatch Started.')

while stop > second:
    if second < 9:
        second = second + 1
        time.sleep(1)
        sys.stdout.write('\r> ' + '0' + str(second))
    else:
        second += 1
        time.sleep(1)
        sys.stdout.write('\r' + '> ' + str(second))

print('\n> Stopwatch Stopped.')

In this example the loop is run every second for ten seconds:

import datetime, time
then = datetime.datetime.now() + datetime.timedelta(seconds=10)
while then > datetime.datetime.now():
    print 'sleeping'
    time.sleep(1)

I use this function in my python programs. The input for the function is as example:
value = time.time()

def stopWatch(value):
    '''From seconds to Days;Hours:Minutes;Seconds'''

    valueD = (((value/365)/24)/60)
    Days = int (valueD)

    valueH = (valueD-Days)*365
    Hours = int(valueH)

    valueM = (valueH - Hours)*24
    Minutes = int(valueM)

    valueS = (valueM - Minutes)*60
    Seconds = int(valueS)


    print Days,";",Hours,":",Minutes,";",Seconds




start = time.time() # What in other posts is described is

***your code HERE***

end = time.time()         
stopWatch(end-start) #Use then my code

For a StopWatch helper class, here is my solution which gives you precision on output and also access to the raw start time:

class StopWatch:
    def __init__(self):
        self.start()
    def start(self):
        self._startTime = time.time()
    def getStartTime(self):
        return self._startTime
    def elapsed(self, prec=3):
        prec = 3 if prec is None or not isinstance(prec, (int, long)) else prec
        diff= time.time() - self._startTime
        return round(diff, prec)
def round(n, p=0):
    m = 10 ** p
    return math.floor(n * m + 0.5) / m

Using time.time()/datetime.datetime.now() will break if the system time is changed (the user changes the time, it is corrected by a timesyncing services such as NTP or switching from/to dayligt saving time!).

time.monotonic() or time.perf_counter() seems to be the correct way to go, however they are only available from python 3.3. Another possibility is using threading.Timer. Whether or not this is more reliable than time.time() and friends depends on the internal implementation. Also note that creating a new thread is not completely free in terms of system resources, so this might be a bad choice in cases where a lot of timers has to be run in parallel.