from pygame import display from pygame.font import Font from pygame.time import get_ticks, wait from GameChild import GameChild class Mainloop(GameChild): def __init__(self, parent): GameChild.__init__(self, parent) self.overflow = 0 self.frame_count = 1 self.actual_frame_duration = 0 self.frames_this_second = 0 self.last_framerate_display = 0 self.load_configuration() self.init_framerate_display() self.last_ticks = get_ticks() self.stopping = False def load_configuration(self): config = self.get_configuration("display") self.target_frame_duration = config["frame-duration"] self.wait_duration = config["wait-duration"] self.skip_frames = config["skip-frames"] self.show_framerate = config["show-framerate"] self.framerate_text_size = config["framerate-text-size"] self.framerate_text_color = config["framerate-text-color"] self.framerate_text_background = config["framerate-text-background"] self.framerate_display_flag = config["framerate-display-flag"] def init_framerate_display(self): if self.framerate_display_active(): screen = self.get_screen() self.last_framerate_count = 0 self.framerate_topright = screen.get_rect().topright self.display_surface = screen self.font = Font(None, self.framerate_text_size) self.font.set_bold(True) self.render_framerate() def framerate_display_active(self): return self.check_command_line(self.framerate_display_flag) or \ self.show_framerate def render_framerate(self): text = self.font.render(str(self.last_framerate_count), False, self.framerate_text_color, self.framerate_text_background) rect = text.get_rect() rect.topright = self.framerate_topright self.framerate_text = text self.framerate_text_rect = rect def run(self): while not self.stopping: self.advance_frame() self.update_frame_duration() self.update_overflow() self.stopping = False def advance_frame(self): refresh = False while self.frame_count > 0: refresh = True self.parent.frame() if self.framerate_display_active(): self.update_framerate() self.frame_count -= 1 if not self.skip_frames: break if refresh: display.update() def update_frame_duration(self): last_ticks = self.last_ticks actual_frame_duration = get_ticks() - last_ticks last_ticks = get_ticks() while actual_frame_duration < self.target_frame_duration: wait(self.wait_duration) actual_frame_duration += get_ticks() - last_ticks last_ticks = get_ticks() self.actual_frame_duration = actual_frame_duration self.last_ticks = last_ticks def update_overflow(self): self.frame_count = 1 target_frame_duration = self.target_frame_duration overflow = self.overflow overflow += self.actual_frame_duration - target_frame_duration while overflow > target_frame_duration: self.frame_count += 1 overflow -= target_frame_duration overflow = self.overflow def update_framerate(self): count = self.frames_this_second + 1 if get_ticks() - self.last_framerate_display > 1000: if count != self.last_framerate_count: self.last_framerate_count = count self.render_framerate() self.last_framerate_display = get_ticks() count = 0 self.display_surface.blit(self.framerate_text, self.framerate_text_rect) self.frames_this_second = count def stop(self): self.stopping = True