109 lines
3.9 KiB
Python
109 lines
3.9 KiB
Python
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
|