January 28, 2014♦
☀
E
F
F
L
U
E
N
C
E
☀
import pygame
from pygame.locals import *
from GameChild import GameChild
from Mainloop import Mainloop
from Audio import Audio
from Display import Display
from Configuration import Configuration
from Delegate import Delegate
from Input import Input
from ScreenGrabber import ScreenGrabber
from Profile import Profile
from VideoRecorder import VideoRecorder
from Interpolator import Interpolator
from TimeFilter import TimeFilter
class Game(GameChild):
resource_path = None
def __init__(self, config_rel_path=None, type_declarations=None):
self.profile = Profile(self)
GameChild.__init__(self)
self.print_debug(pygame.version.ver)
self.config_rel_path = config_rel_path
self.type_declarations = type_declarations
self.set_configuration()
pygame.init()
self.set_children()
self.subscribe(self.end, QUIT)
self.subscribe(self.end)
self.delegate.enable()
def set_configuration(self):
self.configuration = Configuration(self.config_rel_path,
self.resource_path,
self.type_declarations)
def set_children(self):
self.time_filter = TimeFilter(self)
self.delegate = Delegate(self)
self.display = Display(self)
self.mainloop = Mainloop(self)
self.input = Input(self)
self.audio = Audio(self)
self.screen_grabber = ScreenGrabber(self)
self.video_recorder = VideoRecorder(self)
self.interpolator = Interpolator(self)
def frame(self):
self.time_filter.update()
self.delegate.dispatch()
if not self.interpolator.is_gui_active():
self.update()
else:
self.interpolator.gui.update()
if self.video_recorder.requested:
self.video_recorder.update()
def run(self):
self.mainloop.run()
def update(self):
pass
def blit(self, source, destination, area=None, special_flags=0):
self.get_screen().blit(source, destination, area, special_flags)
def get_rect(self):
return self.get_screen().get_rect()
def end(self, evt):
if evt.type == QUIT or self.delegate.compare(evt, "quit"):
self.mainloop.stop()
self.profile.end()
from os import makedirs
from os.path import exists, join
from tempfile import TemporaryFile
from time import strftime
from pygame.image import tostring, frombuffer, save
from pygame.time import get_ticks
from GameChild import GameChild
class VideoRecorder(GameChild):
def __init__(self, parent):
GameChild.__init__(self, parent)
self.set_requested()
if self.requested:
self.display_surface = self.get_display_surface()
self.delegate = self.get_delegate()
self.load_configuration()
self.reset()
self.subscribe(self.respond)
def set_requested(self):
self.requested = self.get_configuration("video-recordings")["enable"] \
or self.check_command_line("-enable-video")
def load_configuration(self):
config = self.get_configuration("video-recordings")
self.root = config["path"]
self.directory_name_format = config["directory-name-format"]
self.file_extension = config["file-extension"]
self.frame_format = config["frame-format"]
self.framerate = config["framerate"]
def reset(self):
self.recording = False
self.frame_length = None
self.frames = None
self.last_frame = 0
def respond(self, event):
compare = self.delegate.compare
if compare(event, "record-video"):
self.toggle_record()
elif compare(event, "reset-game"):
self.reset()
def toggle_record(self):
recording = not self.recording
if recording:
self.frame_length = len(self.get_string())
self.frames = TemporaryFile()
else:
self.write_frames()
self.recording = recording
def get_string(self):
return tostring(self.display_surface, self.frame_format)
def write_frames(self):
root = join(self.root, strftime(self.directory_name_format))
if not exists(root):
makedirs(root)
size = self.display_surface.get_size()
frames = self.frames
frames.seek(0)
for ii, frame in enumerate(iter(lambda: frames.read(self.frame_length),
"")):
path = join(root, "%04i.png" % ii)
save(frombuffer(frame, size, self.frame_format), path)
print "wrote video frames to " + root
def update(self):
ticks = get_ticks()
if self.recording and ticks - self.last_frame >= self.framerate:
self.frames.write(self.get_string())
self.last_frame = ticks
from pygame.time import get_ticks
from GameChild import GameChild
class TimeFilter(GameChild):
def __init__(self, parent):
GameChild.__init__(self, parent)
self.ticks = self.unfiltered_ticks = self.last_ticks = get_ticks()
self.open()
def close(self):
self.closed = True
def open(self):
self.closed = False
def get_ticks(self):
return self.ticks
def get_unfiltered_ticks(self):
return self.unfiltered_ticks
def get_last_ticks(self):
return self.last_ticks
def get_last_frame_duration(self):
return self.last_frame_duration
def update(self):
ticks = get_ticks()
self.last_frame_duration = duration = ticks - self.last_ticks
if not self.closed:
self.ticks += duration
self.unfiltered_ticks += duration
self.last_ticks = ticks
class Vector(list):
def __init__(self, x=0, y=0):
list.__init__(self, (x, y))
def __getattr__(self, name):
if name == "x":
return self[0]
elif name == "y":
return self[1]
def __setattr__(self, name, value):
if name == "x":
self[0] = value
elif name == "y":
self[1] = value
else:
list.__setattr__(self, name, value)
def __add__(self, other):
return Vector(self.x + other[0], self.y + other[1])
__radd__ = __add__
def __iadd__(self, other):
self.x += other[0]
self.y += other[1]
return self
def __sub__(self, other):
return Vector(self.x - other[0], self.y - other[1])
def __rsub__(self, other):
return Vector(other[0] - self.x, other[1] - self.y)
def __isub__(self, other):
self.x -= other[0]
self.y -= other[1]
return self
def __mul__(self, other):
return Vector(self.x * other, self.y * other)
__rmul__ = __mul__
def __imul__(self, other):
self.x *= other
self.y *= other
return self
def apply_to_components(self, function):
self.x = function(self.x)
self.y = function(self.y)
def place(self, x=None, y=None):
if x is not None:
self.x = x
if y is not None:
self.y = y
def move(self, dx=0, dy=0):
if dx:
self.x += dx
if dy:
self.y += dy
def place_at_origin(self):
self.x = 0
self.y = 0