import threading import time import random class GameLoop(): """Implements a loop that calls tick every 1/fps tick gets called with the time delta to the last call as parameter if fixed_dt is True the tick function gets called with 1/fps """ def __init__(self, fps=1, tick=None, fixed_dt=False, args=None): self.fps = fps self.tick = tick if tick is not None else self.default_tick self.args = args or tuple() self.fixed_dt = fixed_dt self.running = False self.last_frame_time = time.time() self.thread = threading.Thread(target=self.loop) def loop(self): while self.running: current_time = time.time() dt = current_time - self.last_frame_time self.last_frame_time = current_time if self.fixed_dt: self.tick(1 / self.fps, *self.args) else: self.tick(dt, *self.args) sleep_time = (1 / self.fps) - (time.time() - self.last_frame_time) if sleep_time > 0: time.sleep(sleep_time) def start(self): self.running = True self.thread.start() def stop(self): self.running = False def default_tick(self, dt): print('ticked. Last tick was %.2f seconds ago' % dt) time.sleep(random.choice([0.4, 0.5, 0.6, 1.4, 2.1]) * 1/self.fps)