--- /dev/null
+[submodule "lib/pgfw"]
+ path = lib/pgfw
+ url = makar:/var/www/git/pgfw
-#!/usr/bin/python
+#!/usr/bin/env python
from os import environ, execvp, chdir, getcwd
from os.path import exists, join, dirname
quit = K_ESCAPE
advance = K_RETURN
+[joy]
+release-left = 0
+release-right = 1
+advance = 9
+
[image]
plateau = img/B59-plus.png
paddle = img/Old-Bag-of-Bones.png
from pygame.event import clear
from pygame.locals import *
-from lake_of_heavenly_wind.pgfw.Game import Game
-from lake_of_heavenly_wind.pgfw.GameChild import GameChild
-from lake_of_heavenly_wind.pgfw.Sprite import Sprite
-from lake_of_heavenly_wind.pgfw.Animation import Animation
+from lib.pgfw.pgfw.Game import Game
+from lib.pgfw.pgfw.GameChild import GameChild
+from lib.pgfw.pgfw.Sprite import Sprite
+from lib.pgfw.pgfw.Animation import Animation
class LakeOfHeavenlyWind(Game):
caption = self.caption = Sprite(self, 5000)
font = Font(self.get_resource("display", "font"), 12)
color = Color(0, 0, 0)
- if random() < .92:
- texts = ["Wind Off of Heaven's Lake", u"澤 天 風"]
- else:
- texts = ["Pleasure in Strong Penetration", u"兌 乾 巽"]
+ texts = ["Wind Off of Heaven's Lake", u"澤 天 風"]
for text in texts:
spaced = text[0]
for ch in text[1:]:
def respond(self, event):
if self.active:
- if self.delegate.compare(event, "any"):
+ if self.delegate.compare(event, "advance"):
self.deactivate()
self.parent.game_screen.activate()
self.start_fx.play()
def respond(self, event):
if self.active and self.ending and self.game_over_elapsed > 3000 and \
- self.delegate.compare(event, "any"):
+ self.delegate.compare(event, "advance"):
self.parent.book.hide_explanations()
self.parent.book.hide_indicators()
self.deactivate()
flip_length = 1500
self.flip_elapsed += self.time_filter.get_last_frame_duration()
if self.flip_elapsed > flip_length:
- self.coins[self.flips].stop()
+ self.coins[self.flips].end_flip()
self.flips += 1
self.flip_elapsed -= flip_length
if self.flips == 3:
self.display_surface.get_rect().centerx
self.hide()
- def stop(self):
+ def end_flip(self):
if randint(0, 1):
self.side = self.HEADS
else:
+++ /dev/null
-from GameChild import GameChild
-
-class Animation(GameChild):
-
- def __init__(self, parent, method=None, interval=None, unfiltered=False):
- GameChild.__init__(self, parent)
- self.unfiltered = unfiltered
- self.default_method = method or self.build_frame
- self.accounts = {}
- self.register(self.default_method, interval=interval)
- self.last_update = 0
-
- def build_frame(self):
- pass
-
- def register(self, *args, **kwargs):
- interval = None
- if kwargs.has_key("interval"):
- interval = kwargs["interval"]
- for method in args:
- if method not in self.accounts:
- self.accounts[method] = Account(interval, self)
- else:
- self.accounts[method].set_interval(interval)
-
- def play(self, method=None, interval=None, delay=0, play_once=False,
- **kwargs):
- account = self.accounts[self.get_default(method)]
- account.set_delay(delay)
- account.set_args(kwargs)
- account.set_play_once(play_once)
- if interval:
- account.set_interval(interval)
- account.play()
-
- def get_default(self, method=None):
- if not method:
- method = self.default_method
- return method
-
- def halt(self, method=None):
- if not method:
- for account in self.accounts.values():
- account.halt()
- else:
- if self.accounts.has_key(method):
- self.accounts[method].halt()
-
- def is_playing(self, method=None, check_all=False, include_delay=False):
- if check_all:
- return any(self.is_account_playing(account, include_delay) for \
- method, account in self.accounts.iteritems())
- return self.is_account_playing(self.accounts[self.get_default(method)],
- include_delay)
-
- def is_account_playing(self, account, include_delay):
- return account.playing and (not include_delay or not account.delay)
-
- def update(self):
- for method, account in self.accounts.iteritems():
- if account.update():
- method(**account.args)
-
-
-class Account:
-
- def __init__(self, interval, animation):
- self.animation = animation
- self.time_filter = animation.get_game().time_filter
- self.set_interval(interval)
- self.set_delay(0)
- self.set_play_once(False)
- self.interval_index = 0
- self.last_frame = 0
- self.halt()
-
- def set_interval(self, interval):
- if isinstance(interval, int) or isinstance(interval, str):
- interval = [interval]
- self.interval = interval
-
- def set_delay(self, delay):
- self.delay = delay
-
- def set_play_once(self, play_once):
- self.play_once = play_once
-
- def set_args(self, args):
- self.args = args
-
- def play(self):
- self.playing = True
-
- def halt(self):
- self.last_update = None
- self.playing = False
-
- def update(self):
- if self.playing:
- if self.animation.unfiltered:
- ticks = self.time_filter.get_unfiltered_ticks()
- else:
- ticks = self.time_filter.get_ticks()
- self.update_delay(ticks)
- if not self.delay:
- interval = self.interval
- if interval:
- if ticks - self.last_frame < self.get_current_interval():
- return False
- self.last_frame = ticks
- self.increment_interval_index()
- if self.play_once:
- self.halt()
- return True
-
- def get_current_interval(self):
- return self.interval[self.interval_index]
-
- def increment_interval_index(self):
- index = self.interval_index + 1
- if index >= len(self.interval):
- index = 0
- self.interval_index = index
-
- def update_delay(self, ticks):
- delay = self.delay
- if delay > 0:
- last_update = self.last_update or ticks
- delay -= ticks - last_update
- if delay < 0:
- delay = 0
- self.last_update = ticks
- self.delay = delay
+++ /dev/null
-from os import listdir
-from os.path import join
-
-from pygame.mixer import Channel, Sound, music, find_channel
-
-from GameChild import *
-from Input import *
-
-class Audio(GameChild):
-
- current_channel = None
- paused = False
- muted = False
-
- def __init__(self, game):
- GameChild.__init__(self, game)
- self.delegate = self.get_delegate()
- self.load_fx()
- self.subscribe(self.respond)
-
- def load_fx(self):
- fx = {}
- if self.get_configuration().has_option("audio", "sfx-path"):
- root = self.get_resource("audio", "sfx-path")
- if root:
- for name in listdir(root):
- fx[name.split(".")[0]] = Sound(join(root, name))
- self.fx = fx
-
- def respond(self, event):
- if self.delegate.compare(event, "mute"):
- self.mute()
-
- def mute(self):
- self.muted = True
- self.set_volume()
-
- def unmute(self):
- self.muted = False
- self.set_volume()
-
- def set_volume(self):
- volume = int(not self.muted)
- music.set_volume(volume)
- if self.current_channel:
- self.current_channel.set_volume(volume)
-
- def play_bgm(self, path, stream=False):
- self.stop_current_channel()
- if stream:
- music.load(path)
- music.play(-1)
- else:
- self.current_channel = Sound(path).play(-1)
- self.set_volume()
-
- def stop_current_channel(self):
- music.stop()
- if self.current_channel:
- self.current_channel.stop()
- self.current_channel = None
- self.paused = False
-
- def play_fx(self, name, panning=.5):
- if not self.muted:
- channel = find_channel(True)
- if panning != .5:
- offset = 1 - abs(panning - .5) * 2
- if panning < .5:
- channel.set_volume(1, offset)
- else:
- channel.set_volume(offset, 1)
- channel.play(self.fx[name])
-
- def pause(self):
- channel = self.current_channel
- paused = self.paused
- if paused:
- music.unpause()
- if channel:
- channel.unpause()
- else:
- music.pause()
- if channel:
- channel.pause()
- self.paused = not paused
-
- def is_bgm_playing(self):
- current = self.current_channel
- if current and current.get_sound():
- return True
- return music.get_busy()
+++ /dev/null
-from os import sep, getcwd
-from os.path import join, exists, basename, dirname, expanduser
-from sys import argv
-from re import match
-from pprint import pformat
-
-from ConfigParser import RawConfigParser
-
-class Configuration(RawConfigParser):
-
- default_project_file_rel_path = "config"
- default_resource_paths = [".", "resource"]
-
- def __init__(self, project_file_rel_path=None, resource_path=None,
- type_declarations=None):
- RawConfigParser.__init__(self)
- self.project_file_rel_path = project_file_rel_path
- self.resource_path = resource_path
- self.modifiable = {}
- self.order = []
- self.set_type_declarations(type_declarations)
- self.set_defaults()
- self.read_project_config_file()
- self.modify_defaults()
- self.print_debug(self)
-
- def set_type_declarations(self, type_declarations):
- if type_declarations is None:
- type_declarations = TypeDeclarations()
- self.type_declarations = type_declarations
-
- def translate_path(self, path):
- new = ""
- if path and path[0] == sep:
- new += sep
- return expanduser("{0}{1}".format(new, join(*path.split(sep))))
-
- def set_defaults(self):
- add_section = self.add_section
- set_option = self.set
- section = "setup"
- add_section(section)
- set_option(section, "package-root", basename(getcwd()), False)
- set_option(section, "additional-packages", "", False)
- set_option(section, "title", "", False)
- set_option(section, "classifiers", "", False)
- set_option(section, "resource-search-path", "./, resource/", False)
- set_option(section, "installation-dir", "/usr/local/share/games/",
- False)
- set_option(section, "changelog", "changelog", False)
- set_option(section, "description-file", "", False)
- set_option(section, "init-script", "", False)
- set_option(section, "version", "", False)
- set_option(section, "summary", "", False)
- set_option(section, "license", "", False)
- set_option(section, "platforms", "", False)
- set_option(section, "contact-name", "", False)
- set_option(section, "contact-email", "", False)
- set_option(section, "url", "", False)
- set_option(section, "requirements", "", False)
- set_option(section, "main-object", "pgfw/Game.py", False)
- set_option(section, "resource-path-identifier", "resource_path", False)
- set_option(section, "special-char-placeholder", "_", False)
- set_option(section, "whitespace-placeholder", "-", False)
- set_option(section, "windows-dist-path", "dist/win/", False)
- set_option(section, "windows-icon-path", "", False)
- set_option(section, "lowercase-boolean-true", "yes", False)
- section = "display"
- add_section(section)
- set_option(section, "dimensions", "480, 360", False)
- set_option(section, "frame-duration", "40", False)
- set_option(section, "wait-duration", "2", False)
- set_option(section, "caption", "", False)
- set_option(section, "centered", "yes", False)
- set_option(section, "icon-path", "", False)
- set_option(section, "skip-frames", "no", False)
- set_option(section, "fullscreen", "no", False)
- set_option(section, "windowed-flag", "wi", False)
- set_option(section, "show-framerate", "no", False)
- set_option(section, "framerate-display-flag", "fr", False)
- set_option(section, "framerate-text-size", "16", False)
- set_option(section, "framerate-text-color", "0, 0, 0", False)
- set_option(section, "framerate-text-background", "255, 255, 255", False)
- section = "input"
- add_section(section)
- set_option(section, "release-suffix", "-release", False)
- section = "sprite"
- add_section(section)
- set_option(section, "transparent-color", "magenta", False)
- section = "screen-captures"
- add_section(section)
- set_option(section, "rel-path", "caps", False)
- set_option(section, "file-name-format", "%Y%m%d%H%M%S", False)
- set_option(section, "file-extension", "png", False)
- section = "video-recordings"
- add_section(section)
- set_option(section, "rel-path", "vids", False)
- set_option(section, "directory-name-format", "%Y%m%d%H%M%S", False)
- set_option(section, "file-extension", "png", False)
- set_option(section, "frame-format", "RGB", False)
- set_option(section, "framerate", "100", False)
- section = "mouse"
- add_section(section)
- set_option(section, "visible", "yes", False)
- set_option(section, "double-click-time-limit", ".5", False)
- section = "keys"
- add_section(section)
- set_option(section, "up", "K_UP, K_w", False)
- set_option(section, "right", "K_RIGHT, K_d", False)
- set_option(section, "down", "K_DOWN, K_s", False)
- set_option(section, "left", "K_LEFT, K_a", False)
- set_option(section, "capture-screen", "K_F9", False)
- set_option(section, "toggle-fullscreen", "K_F11", False)
- set_option(section, "reset-game", "K_F8", False)
- set_option(section, "record-video", "K_F10", False)
- set_option(section, "mute", "K_F12", False)
- set_option(section, "toggle-interpolator", "K_F7", False)
- section = "joy"
- add_section(section)
- set_option(section, "advance", "7", False)
- set_option(section, "pause", "7", False)
- set_option(section, "select", "6", False)
- section = "event"
- add_section(section)
- set_option(section, "user-event-id", "USEREVENT", False)
- set_option(section, "command-id-offset", "1", False)
- set_option(section, "command-key", "command", False)
- set_option(section, "cancel-flag-key", "cancel", False)
- section = "audio"
- add_section(section)
- set_option(section, "sfx-path", "aud/fx/", False)
- section = "interpolator-gui"
- add_section(section)
- set_option(section, "margin", "80", False)
- set_option(section, "marker-color", "255, 0, 0", False)
- set_option(section, "marker-size", "11", False)
- set_option(section, "curve-color", "0, 255, 0", False)
- set_option(section, "label-size", "16", False)
- set_option(section, "label-precision", "2", False)
- set_option(section, "axis-label-count", "8", False)
- set_option(section, "prompt-size", "380, 60", False)
- set_option(section, "prompt-border-color", "255, 0, 0", False)
- set_option(section, "prompt-border-width", "3", False)
- set_option(section, "prompt-character-limit", "21", False)
- set_option(section, "prompt-text-size", "42", False)
- set_option(section, "template-nodeset", "L 0 0, 1000 1", False)
- set_option(section, "template-nodeset-name", "template", False)
- set_option(section, "flat-y-range", "1", False)
-
- def add_section(self, name):
- if name not in self.order:
- self.order.append(name)
- RawConfigParser.add_section(self, name)
-
- def set(self, section, option, value, modifiable=True):
- if modifiable:
- if section not in self.order:
- self.order.append(section)
- if section not in self.modifiable:
- self.modifiable[section] = []
- if option not in self.modifiable[section]:
- self.modifiable[section].append(option)
- RawConfigParser.set(self, section, option, value)
-
- def read_project_config_file(self):
- path = self.locate_project_config_file()
- if path:
- fp = open(path)
- self.set_modifiable(fp)
- fp.seek(0)
- self.readfp(fp)
- fp.seek(0)
- self.set_order(fp)
- fp.close()
- else:
- self.print_debug("No configuration file found")
-
- def locate_project_config_file(self):
- rel_path = self.project_file_rel_path
- if not rel_path:
- rel_path = self.default_project_file_rel_path
- if exists(rel_path) and not self.is_shared_mode():
- return rel_path
- if self.resource_path:
- installed_path = join(self.resource_path, rel_path)
- if exists(installed_path):
- return installed_path
-
- def set_order(self, fp):
- self.order = order = []
- for line in file(self.locate_project_config_file()):
- result = match("^\s*\[(.*)\]\s*$", line)
- if result:
- order.append(result.group(1))
-
- def set_modifiable(self, fp):
- config = RawConfigParser()
- config.readfp(fp)
- modifiable = self.modifiable
- for section in config._sections:
- if section not in modifiable:
- modifiable[section] = []
- for option in config._sections[section]:
- if option != "__name__" and option not in modifiable[section]:
- modifiable[section].append(option)
-
- def is_shared_mode(self):
- return "-s" in argv
-
- def print_debug(self, statement):
- if self.is_debug_mode():
- print statement
-
- def is_debug_mode(self):
- return "-d" in argv
-
- def modify_defaults(self):
- self.set_installation_path()
- self.set_resource_search_path()
- self.set_screen_captures_path()
- self.set_video_recordings_path()
- self.set_data_exclusion_list()
- self.set_requirements()
-
- def set_installation_path(self):
- self.set("setup", "installation-path",
- join(self.get("setup", "installation-dir"),
- self.get("setup", "package-root")), False)
-
- def set_resource_search_path(self):
- section, option = "setup", "resource-search-path"
- search_path = self.get(section, option)
- if self.resource_path:
- search_path.append(self.resource_path)
- else:
- search_path.append(self.get("setup", "installation-path"))
- self.set(section, option, search_path, False)
-
- def get(self, section, option):
- value = RawConfigParser.get(self, section, option)
- if value is None:
- value = self.get_substitute(section, option)
- return self.cast_value(section, option, value)
-
- def get_substitute(self, section, option):
- if section == "display":
- if option == "caption":
- return self.get("setup", "title")
-
- def cast_value(self, section, option, value):
- pair = section, option
- types = self.type_declarations
- if type(value) == str:
- if pair in types["bool"]:
- if value.lower() == self.get("setup", "lowercase-boolean-true"):
- return True
- return False
- elif pair in types["int"]:
- return int(value)
- elif pair in types["float"]:
- return float(value)
- elif pair in types["path"]:
- return self.translate_path(value)
- elif pair in types["list"]:
- if value == "":
- return []
- else:
- return map(str.strip, value.split(types.list_member_sep))
- elif pair in types["int-list"]:
- return map(int, value.split(types.list_member_sep))
- elif pair in types["float-list"]:
- return map(float, value.split(types.list_member_sep))
- return value
-
- def set_screen_captures_path(self):
- section, option = "screen-captures", "path"
- if not self.has_option(section, option):
- self.set(section, option, join(self.build_home_path(),
- self.get(section, "rel-path")),
- False)
-
- def build_home_path(self):
- return join("~", "." + self.get("setup", "package-root"))
-
- def set_video_recordings_path(self):
- section, option = "video-recordings", "path"
- if not self.has_option(section, option):
- self.set(section, option, join(self.build_home_path(),
- self.get(section, "rel-path")),
- False)
-
- def set_data_exclusion_list(self):
- section, option = "setup", "data-exclude"
- exclude = []
- if self.has_option(section, option):
- exclude = self.get(section, option)
- exclude += [".git", ".gitignore", "README", "build/", "dist/",
- "setup.py", "MANIFEST", "PKG-INFO",
- self.get("setup", "changelog"),
- self.get("setup", "package-root")]
- for location in self.get("setup", "additional-packages"):
- exclude.append(location)
- self.set(section, option, exclude, False)
-
- def set_requirements(self):
- section, option = "setup", "requirements"
- requirements = []
- if self.has_option(section, option):
- requirements = self.get(section, option)
- if "pygame" not in requirements:
- requirements.append("pygame")
- self.set(section, option, requirements, False)
-
- def get_section(self, section):
- assignments = {}
- for option in self.options(section):
- assignments[option] = self.get(section, option)
- return assignments
-
- def __repr__(self):
- config = {}
- for section in self.sections():
- config[section] = self.get_section(section)
- return pformat(config, 2, 1)
-
- def items(self, section):
- items = []
- for option in self.options(section):
- items.append((option, self.get(section, option)))
- return items
-
- def write(self, fp=None):
- modifiable = self.modifiable
- use_main = fp is None
- if use_main:
- path = self.locate_project_config_file()
- if not path:
- path = join(self.resource_path or "",
- self.default_project_file_rel_path)
- fp = open(path, "w")
- break_line = False
- for section in self.order:
- if section in modifiable:
- break_line and fp.write("\n")
- fp.write("[%s]\n" % section)
- for option in modifiable[section]:
- if self.has_option(section, option):
- value = self.get(section, option)
- fp.write("%s = %s\n" % (option,
- self.get_raw_value(value)))
- break_line = True
- if use_main:
- fp.close()
-
- def get_raw_value(self, value):
- if isinstance(value, list):
- raw = ""
- for ii, value in enumerate(value):
- if ii:
- raw += ", "
- raw += str(value)
- else:
- raw = str(value)
- return raw
-
- def clear_section(self, section):
- if self.has_section(section):
- for option in self.options(section):
- self.remove_option(section, option)
-
-
-class TypeDeclarations(dict):
-
- list_member_sep = ','
-
- defaults = {
-
- "display": {"int": ["frame-duration", "wait-duration",
- "framerate-text-size"],
-
- "bool": ["centered", "skip-frames", "fullscreen",
- "show-framerate"],
-
- "int-list": ["dimensions", "framerate-text-color",
- "framerate-text-background"]},
-
- "screen-captures": {"path": ["rel-path", "path"]},
-
- "video-recordings": {"path": ["rel-path", "path"],
-
- "int": "framerate"},
-
- "setup": {"list": ["classifiers", "resource-search-path",
- "requirements", "data-exclude",
- "additional-packages"],
-
- "path": ["installation-dir", "changelog", "description-file",
- "main-object", "icon-path", "windows-dist-path",
- "package-root"]},
-
- "mouse": {"float": "double-click-time-limit",
-
- "bool": "visible"},
-
- "keys": {"list": ["up", "right", "down", "left"]},
-
- "joy": {"int": ["advance", "pause", "select"]},
-
- "audio": {"path": "sfx-path"},
-
- "event": {"int": "command-id-offset"},
-
- "interpolator-gui": {"int": ["margin", "marker-size", "label-size",
- "axis-label-count", "label-precision",
- "prompt-border-width",
- "prompt-character-limit",
- "prompt-text-size", "flat-y-range"],
-
- "int-list": ["marker-color", "curve-color",
- "prompt-size",
- "prompt-border-color"]},
-
- }
-
- additional_defaults = {}
-
- def __init__(self):
- dict.__init__(self, {"bool": [], "int": [], "float": [], "path": [],
- "list": [], "int-list": [], "float-list": []})
- self.add_chart(self.defaults)
- self.add_chart(self.additional_defaults)
-
- def add(self, cast, section, option):
- self[cast].append((section, option))
-
- def add_chart(self, chart):
- for section, declarations in chart.iteritems():
- for cast, options in declarations.iteritems():
- if type(options) != list:
- options = [options]
- for option in options:
- self.add(cast, section, option)
+++ /dev/null
-from pygame.event import get, pump, Event, post
-from pygame.locals import *
-
-from GameChild import GameChild
-from Input import Input
-
-class Delegate(GameChild):
-
- def __init__(self, game):
- GameChild.__init__(self, game)
- self.subscribers = dict()
- self.load_configuration()
- self.disable()
-
- def load_configuration(self):
- config = self.get_configuration("event")
- self.cancel_flag_key = config["cancel-flag-key"]
- self.command_key = config["command-key"]
- self.command_event_id = config["command-id-offset"] + \
- globals()[config["user-event-id"]]
-
- def disable(self):
- self.enabled = False
-
- def enable(self):
- self.enabled = True
- self.interpolator = self.get_game().interpolator
-
- def dispatch(self):
- if self.enabled:
- subscribers = self.subscribers
- for evt in get():
- kind = evt.type
- if kind in subscribers:
- for subscriber in subscribers[kind]:
- if not self.interpolator.is_gui_active() or \
- hasattr(subscriber, "im_class") and \
- (subscriber.im_class == Input or \
- subscriber.im_class == \
- self.interpolator.gui.__class__):
- self.print_debug("Passing %s to %s" % (evt,
- subscriber))
- subscriber(evt)
- else:
- pump()
-
- def add_subscriber(self, callback, kind=None):
- self.print_debug("Subscribing %s to %s" % (callback, kind))
- if kind is None:
- kind = self.command_event_id
- subscribers = self.subscribers
- if kind not in subscribers:
- subscribers[kind] = list()
- subscribers[kind].append(callback)
-
- def is_command(self, event):
- return event.type == self.command_event_id
-
- def remove_subscriber(self, callback, kind=None):
- if kind is None:
- kind = self.command_event_id
- self.subscribers[kind].remove(callback)
-
- def compare(self, evt, commands=None, cancel=False, **attributes):
- if evt.type == self.command_event_id:
- self.add_cancel_flag_to_attributes(attributes, cancel)
- if commands is not None and not isinstance(commands, list):
- commands = [commands]
- if commands is not None:
- if not self.command_in_list(evt, commands):
- return False
- return all(key in evt.dict and evt.dict[key] == value for \
- key, value in attributes.iteritems())
-
- def add_cancel_flag_to_attributes(self, attributes, cancel):
- attributes[self.cancel_flag_key] = cancel
-
- def command_in_list(self, evt, commands):
- return self.get_command_attribute(evt) in commands
-
- def get_command_attribute(self, evt):
- return evt.dict[self.command_key]
-
- def post(self, command=None, cancel=False, **attributes):
- attributes[self.command_key] = command
- self.add_cancel_flag_to_attributes(attributes, cancel)
- post(Event(self.command_event_id, attributes))
+++ /dev/null
-from os import environ
-
-from pygame import display, image, mouse
-from pygame.locals import *
-
-from GameChild import *
-
-class Display(GameChild):
-
- def __init__(self, game):
- GameChild.__init__(self, game)
- self.delegate = self.get_delegate()
- self.load_configuration()
- self.align_window()
- self.init_screen()
- self.set_caption()
- self.set_icon()
- self.set_mouse_visibility()
- self.subscribe(self.toggle_fullscreen)
-
- def load_configuration(self):
- config = self.get_configuration("display")
- self.centered = config["centered"]
- self.fullscreen_enabled = config["fullscreen"]
- self.caption = config["caption"]
- self.windowed_flag = config["windowed-flag"]
- self.icon_path = self.get_resource("display", "icon-path")
- self.mouse_visibility = self.get_configuration("mouse", "visible")
-
- def align_window(self):
- if self.centered:
- environ["SDL_VIDEO_CENTERED"] = "1"
-
- def init_screen(self):
- flags = 0
- if self.fullscreen_requested():
- flags = FULLSCREEN
- self.set_screen(flags)
-
- def fullscreen_requested(self):
- return not self.check_command_line(self.windowed_flag) and \
- self.fullscreen_enabled
-
- def set_screen(self, flags=0, dimensions=None):
- self.dimensions_changed = dimensions is not None
- if dimensions is None:
- if display.get_surface():
- dimensions = display.get_surface().get_size()
- else:
- dimensions = self.get_configuration("display", "dimensions")
- self.screen = display.set_mode(dimensions, flags)
- if self.dimensions_changed:
- interpolator = self.get_game().interpolator
- if interpolator.gui_enabled:
- interpolator.gui.rearrange()
-
- def set_caption(self):
- display.set_caption(self.caption)
-
- def set_icon(self):
- if self.icon_path:
- print self.icon_path
- display.set_icon(image.load(self.icon_path).convert_alpha())
-
- def set_mouse_visibility(self, visibility=None):
- if visibility is None:
- visibility = self.mouse_visibility
- return mouse.set_visible(visibility)
-
- def get_screen(self):
- return self.screen
-
- def get_size(self):
- return self.screen.get_size()
-
- def toggle_fullscreen(self, event):
- if self.delegate.compare(event, "toggle-fullscreen"):
- screen = self.screen
- cpy = screen.convert()
- self.set_screen(self.screen.get_flags() ^ FULLSCREEN)
- screen.blit(cpy, (0, 0))
+++ /dev/null
-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()
- 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()
+++ /dev/null
-from os.path import exists, join, basename, normpath, abspath
-from sys import argv
-
-from pygame import mixer, event, time
-from pygame.locals import *
-
-import Game
-
-class GameChild:
-
- def __init__(self, parent=None):
- self.parent = parent
- self.game = self.get_game()
-
- def get_game(self):
- current = self
- while not isinstance(current, Game.Game):
- current = current.parent
- return current
-
- def get_configuration(self, section=None, option=None):
- config = self.game.configuration
- if option and section:
- return config.get(section, option)
- if section:
- return config.get_section(section)
- return config
-
- def get_input(self):
- return self.game.input
-
- def get_screen(self):
- return self.game.display.get_screen()
-
- def get_display_surface(self):
- current = self
- attribute = "display_surface"
- while not isinstance(current, Game.Game):
- if hasattr(current, attribute):
- return getattr(current, attribute)
- current = current.parent
- return current.display.get_screen()
-
- def get_audio(self):
- return self.game.audio
-
- def get_delegate(self):
- return self.game.delegate
-
- def get_resource(self, path_or_section, option=None):
- config = self.get_configuration()
- rel_path = path_or_section
- if option is not None:
- rel_path = config.get(path_or_section, option)
- if rel_path:
- for root in config.get("setup", "resource-search-path"):
- if self.is_shared_mode() and not self.is_absolute_path(root):
- continue
- path = join(root, rel_path)
- if exists(path):
- return path
- self.print_debug("Couldn't find resource: {0} {1}".\
- format(path_or_section, option))
-
- def is_shared_mode(self):
- return self.check_command_line("s")
-
- def check_command_line(self, flag):
- return "-" + flag in argv
-
- def print_debug(self, statement):
- if self.is_debug_mode():
- print statement
-
- def is_debug_mode(self):
- return self.check_command_line("d")
-
- def is_absolute_path(self, path):
- return normpath(path) == abspath(path)
-
- def subscribe(self, callback, kind=None):
- self.game.delegate.add_subscriber(callback, kind)
-
- def unsubscribe(self, callback, kind=None):
- self.game.delegate.remove_subscriber(callback, kind)
+++ /dev/null
-from time import time as get_secs
-
-from pygame import joystick as joy
-from pygame.key import get_pressed
-from pygame.locals import *
-
-from GameChild import *
-
-class Input(GameChild):
-
- def __init__(self, game):
- GameChild.__init__(self, game)
- self.last_mouse_down_left = None
- self.joystick = Joystick()
- self.delegate = self.get_delegate()
- self.load_configuration()
- self.set_any_press_ignore_list()
- self.unsuppress()
- self.subscribe_to_events()
- self.build_key_map()
- self.build_joy_button_map()
-
- def load_configuration(self):
- self.release_suffix = self.get_configuration("input", "release-suffix")
- self.key_commands = self.get_configuration().items("keys")
- self.double_click_time_limit = self.get_configuration(
- "mouse", "double-click-time-limit")
-
- def set_any_press_ignore_list(self):
- self.any_press_ignored = set(["capture-screen", "toggle-fullscreen",
- "reset-game", "record-video", "quit",
- "mute", "toggle-interpolator"])
- self.any_press_ignored_keys = set()
-
- def unsuppress(self):
- self.suppressed = False
-
- def subscribe_to_events(self):
- self.subscribe(self.translate_key, KEYDOWN)
- self.subscribe(self.translate_key, KEYUP)
- self.subscribe(self.translate_joy_button, JOYBUTTONDOWN)
- self.subscribe(self.translate_joy_button, JOYBUTTONUP)
- self.subscribe(self.translate_axis_motion, JOYAXISMOTION)
- self.subscribe(self.translate_mouse_input, MOUSEBUTTONDOWN)
- self.subscribe(self.translate_mouse_input, MOUSEBUTTONUP)
-
- def build_key_map(self):
- key_map = {}
- for command, keys in self.key_commands:
- key_map[command] = []
- if type(keys) == str:
- keys = [keys]
- for key in keys:
- key_map[command].append(globals()[key])
- self.key_map = key_map
-
- def build_joy_button_map(self):
- self.joy_button_map = self.get_configuration("joy")
-
- def suppress(self):
- self.suppressed = True
-
- def translate_key(self, event):
- if not self.suppressed:
- cancel = event.type == KEYUP
- posted = None
- key = event.key
- for cmd, keys in self.key_map.iteritems():
- if key in keys:
- self.post_command(cmd, cancel=cancel)
- posted = cmd
- if (not posted or posted not in self.any_press_ignored) and \
- key not in self.any_press_ignored_keys:
- self.post_any_command(key, cancel)
-
- def post_command(self, cmd, **attributes):
- self.delegate.post(cmd, **attributes)
-
- def post_any_command(self, id, cancel=False):
- self.post_command("any", id=id, cancel=cancel)
-
- def translate_joy_button(self, event):
- if not self.suppressed:
- cancel = event.type == JOYBUTTONUP
- posted = None
- for command, button in self.joy_button_map.iteritems():
- if button == event.button:
- self.post_command(command, cancel=cancel)
- posted = command
- if not posted or posted not in self.any_press_ignored:
- self.post_any_command(event.button, cancel)
-
- def translate_axis_motion(self, event):
- if not self.suppressed:
- axis = event.axis
- value = event.value
- if not value:
- for command in "up", "right", "down", "left":
- self.post_command(command, cancel=True)
- if command not in self.any_press_ignored:
- self.post_any_command(command, True)
- else:
- if axis == 1:
- if value < 0:
- command = "up"
- elif value > 0:
- command = "down"
- else:
- if value > 0:
- command = "right"
- elif value < 0:
- command = "left"
- self.post_command(command)
- if command not in self.any_press_ignored:
- self.post_any_command(command)
-
- def is_command_active(self, command):
- if not self.suppressed:
- if self.is_key_pressed(command):
- return True
- joystick = self.joystick
- joy_map = self.joy_button_map
- if command in joy_map and joystick.get_button(joy_map[command]):
- return True
- if command == "up":
- return joystick.is_direction_pressed(Joystick.up)
- elif command == "right":
- return joystick.is_direction_pressed(Joystick.right)
- elif command == "down":
- return joystick.is_direction_pressed(Joystick.down)
- elif command == "left":
- return joystick.is_direction_pressed(Joystick.left)
-
- def is_key_pressed(self, command):
- poll = get_pressed()
- for key in self.key_map[command]:
- if poll[key]:
- return True
-
- def translate_mouse_input(self, event):
- button = event.button
- pos = event.pos
- post = self.post_command
- if event.type == MOUSEBUTTONDOWN:
- if button == 1:
- last = self.last_mouse_down_left
- if last:
- limit = self.double_click_time_limit
- if get_secs() - last < limit:
- post("mouse-double-click-left", pos=pos)
- last = get_secs()
- self.last_mouse_down_left = last
-
- def get_axes(self):
- axes = {}
- for direction in "up", "right", "down", "left":
- axes[direction] = self.is_command_active(direction)
- return axes
-
- def register_any_press_ignore(self, *args, **attributes):
- self.any_press_ignored.update(args)
- self.any_press_ignored_keys.update(self.extract_keys(attributes))
-
- def extract_keys(self, attributes):
- keys = []
- if "keys" in attributes:
- keys = attributes["keys"]
- if type(keys) == int:
- keys = [keys]
- return keys
-
- def unregister_any_press_ignore(self, *args, **attributes):
- self.any_press_ignored.difference_update(args)
- self.any_press_ignored_keys.difference_update(
- self.extract_keys(attributes))
-
-
-class Joystick:
-
- (up, right, down, left) = range(4)
-
- def __init__(self):
- js = None
- if joy.get_count() > 0:
- js = joy.Joystick(0)
- js.init()
- self.js = js
-
- def is_direction_pressed(self, direction):
- js = self.js
- if not js or direction > 4:
- return False
- if direction == 0:
- return js.get_axis(1) < 0
- elif direction == 1:
- return js.get_axis(0) > 0
- elif direction == 2:
- return js.get_axis(1) > 0
- elif direction == 3:
- return js.get_axis(0) < 0
-
- def get_button(self, id):
- if self.js:
- return self.js.get_button(id)
+++ /dev/null
-from re import match
-from os.path import join
-from tempfile import gettempdir
-
-from pygame import Surface
-from pygame.font import Font
-from pygame.draw import aaline
-from pygame.locals import *
-
-from GameChild import GameChild
-from Sprite import Sprite
-from Animation import Animation
-
-class Interpolator(list, GameChild):
-
- def __init__(self, parent):
- GameChild.__init__(self, parent)
- self.set_nodesets()
- self.gui_enabled = self.check_command_line("-interpolator")
- if self.gui_enabled:
- self.gui = GUI(self)
-
- def set_nodesets(self):
- config = self.get_configuration()
- if config.has_section("interpolate"):
- for name, value in config.get_section("interpolate").iteritems():
- self.add_nodeset(name, value)
-
- def add_nodeset(self, name, value, method=None):
- self.append(Nodeset(name, value, method))
- return len(self) - 1
-
- def is_gui_active(self):
- return self.gui_enabled and self.gui.active
-
- def get_nodeset(self, name):
- for nodeset in self:
- if nodeset.name == name:
- return nodeset
-
- def remove(self, outgoing):
- for ii, nodeset in enumerate(self):
- if nodeset.name == outgoing.name:
- self.pop(ii)
- break
-
-
-class Nodeset(list):
-
- LINEAR, CUBIC = range(2)
-
- def __init__(self, name, nodes, method=None):
- list.__init__(self, [])
- self.name = name
- if isinstance(nodes, str):
- self.parse_raw(nodes)
- else:
- self.interpolation_method = method
- self.parse_list(nodes)
- self.set_splines()
-
- def parse_raw(self, raw):
- raw = raw.strip()
- if raw[0].upper() == "L":
- self.set_interpolation_method(self.LINEAR, False)
- else:
- self.set_interpolation_method(self.CUBIC, False)
- for node in raw[1:].strip().split(","):
- self.add_node(map(float, node.strip().split()), False)
-
- def set_interpolation_method(self, method, refresh=True):
- self.interpolation_method = method
- if refresh:
- self.set_splines()
-
- def add_node(self, coordinates, refresh=True):
- x = coordinates[0]
- inserted = False
- index = 0
- for ii, node in enumerate(self):
- if x < node.x:
- self.insert(ii, Node(coordinates))
- inserted = True
- index = ii
- break
- elif x == node.x:
- return None
- if not inserted:
- self.append(Node(coordinates))
- index = len(self) - 1
- if refresh:
- self.set_splines()
- return index
-
- def parse_list(self, nodes):
- for node in nodes:
- self.add_node(node)
-
- def set_splines(self):
- if self.interpolation_method == self.LINEAR:
- self.set_linear_splines()
- else:
- self.set_cubic_splines()
-
- def set_linear_splines(self):
- self.splines = splines = []
- for ii in xrange(len(self) - 1):
- x1, y1, x2, y2 = self[ii] + self[ii + 1]
- m = float(y2 - y1) / (x2 - x1)
- splines.append(LinearSpline(x1, y1, m))
-
- def set_cubic_splines(self):
- n = len(self) - 1
- a = [node.y for node in self]
- b = [None] * n
- d = [None] * n
- h = [self[ii + 1].x - self[ii].x for ii in xrange(n)]
- alpha = [None] + [(3.0 / h[ii]) * (a[ii + 1] - a[ii]) - \
- (3.0 / h[ii - 1]) * (a[ii] - a[ii - 1]) \
- for ii in xrange(1, n)]
- c = [None] * (n + 1)
- l = [None] * (n + 1)
- u = [None] * (n + 1)
- z = [None] * (n + 1)
- l[0] = 1
- u[0] = z[0] = 0
- for ii in xrange(1, n):
- l[ii] = 2 * (self[ii + 1].x - self[ii - 1].x) - \
- h[ii - 1] * u[ii - 1]
- u[ii] = h[ii] / l[ii]
- z[ii] = (alpha[ii] - h[ii - 1] * z[ii - 1]) / l[ii]
- l[n] = 1
- z[n] = c[n] = 0
- for jj in xrange(n - 1, -1, -1):
- c[jj] = z[jj] - u[jj] * c[jj + 1]
- b[jj] = (a[jj + 1] - a[jj]) / h[jj] - \
- (h[jj] * (c[jj + 1] + 2 * c[jj])) / 3
- d[jj] = (c[jj + 1] - c[jj]) / (3 * h[jj])
- self.splines = [CubicSpline(self[ii].x, a[ii], b[ii], c[ii],
- d[ii]) for ii in xrange(n)]
-
- def get_y(self, t, loop=False, reverse=False, natural=False):
- if loop or reverse:
- if reverse and int(t) / int(self[-1].x) % 2:
- t = self[-1].x - t
- t %= self[-1].x
- elif not natural:
- if t < self[0].x:
- t = self[0].x
- elif t > self[-1].x:
- t = self[-1].x
- splines = self.splines
- for ii in xrange(len(splines) - 1):
- if t < splines[ii + 1].x:
- return splines[ii].get_y(t)
- return splines[-1].get_y(t)
-
- def remove(self, node, refresh=True):
- list.remove(self, node)
- if refresh:
- self.set_splines()
-
- def resize(self, left, length, refresh=True):
- old_left = self[0].x
- old_length = self.get_length()
- for node in self:
- node.x = left + length * (node.x - old_left) / old_length
- if refresh:
- self.set_splines()
-
- def get_length(self):
- return self[-1].x - self[0].x
-
-
-class Node(list):
-
- def __init__(self, coordinates):
- list.__init__(self, coordinates)
-
- def __getattr__(self, name):
- if name == "x":
- return self[0]
- elif name == "y":
- return self[1]
- return list.__get__(self, name)
-
- def __setattr__(self, name, value):
- if name == "x":
- list.__setitem__(self, 0, value)
- elif name == "y":
- list.__setitem__(self, 1, value)
- else:
- list.__setattr__(self, name, value)
-
-
-class Spline:
-
- def __init__(self, x):
- self.x = x
-
-
-class CubicSpline(Spline):
-
- def __init__(self, x, a, b, c, d):
- Spline.__init__(self, x)
- self.a = a
- self.b = b
- self.c = c
- self.d = d
-
- def get_y(self, t):
- x = self.x
- return self.a + self.b * (t - x) + self.c * (t - x) ** 2 + self.d * \
- (t - x) ** 3
-
-
-class LinearSpline(Spline):
-
- def __init__(self, x, y, m):
- Spline.__init__(self, x)
- self.y = y
- self.m = m
-
- def get_y(self, t):
- return self.m * (t - self.x) + self.y
-
-
-class GUI(Animation):
-
- B_DUPLICATE, B_WRITE, B_DELETE, B_LINEAR, B_CUBIC, B_SPLIT = range(6)
- S_NONE, S_LEFT, S_RIGHT = range(3)
-
- def __init__(self, parent):
- Animation.__init__(self, parent, unfiltered=True)
- self.audio = self.get_audio()
- self.display = self.get_game().display
- self.display_surface = self.get_display_surface()
- self.time_filter = self.get_game().time_filter
- self.delegate = self.get_delegate()
- self.split = self.S_NONE
- self.success_indicator_active = True
- self.success_indicator_blink_count = 0
- self.load_configuration()
- self.font = Font(None, self.label_size)
- self.prompt = Prompt(self)
- self.set_temporary_file()
- self.set_background()
- self.set_success_indicator()
- self.set_plot_rect()
- self.set_marker_frame()
- self.set_buttons()
- self.active = False
- self.set_nodeset_index()
- self.set_y_range()
- self.set_markers()
- self.subscribe(self.respond_to_command)
- self.subscribe(self.respond_to_mouse_down, MOUSEBUTTONDOWN)
- self.subscribe(self.respond_to_key, KEYDOWN)
- self.register(self.show_success_indicator, interval=100)
- self.register(self.save_temporary_file, interval=10000)
- self.play(self.save_temporary_file)
-
- def load_configuration(self):
- config = self.get_configuration("interpolator-gui")
- self.label_size = config["label-size"]
- self.axis_label_count = config["axis-label-count"]
- self.margin = config["margin"]
- self.curve_color = config["curve-color"]
- self.marker_size = config["marker-size"]
- self.marker_color = config["marker-color"]
- self.label_precision = config["label-precision"]
- self.template_nodeset = config["template-nodeset"]
- self.template_nodeset_name = config["template-nodeset-name"]
- self.flat_y_range = config["flat-y-range"]
-
- def set_temporary_file(self):
- self.temporary_file = open(join(gettempdir(), "pgfw-config"), "w")
-
- def set_background(self):
- surface = Surface(self.display_surface.get_size())
- surface.fill((0, 0, 0))
- self.background = surface
-
- def set_success_indicator(self):
- surface = Surface((10, 10))
- surface.fill((0, 255, 0))
- rect = surface.get_rect()
- rect.topleft = self.display_surface.get_rect().topleft
- self.success_indicator, self.success_indicator_rect = surface, rect
-
- def set_plot_rect(self):
- margin = self.margin
- self.plot_rect = self.display_surface.get_rect().inflate(-margin,
- -margin)
-
- def set_marker_frame(self):
- size = self.marker_size
- surface = Surface((size, size))
- transparent_color = (255, 0, 255)
- surface.fill(transparent_color)
- surface.set_colorkey(transparent_color)
- line_color = self.marker_color
- aaline(surface, line_color, (0, 0), (size - 1, size - 1))
- aaline(surface, line_color, (0, size - 1), (size - 1, 0))
- self.marker_frame = surface
-
- def set_buttons(self):
- self.buttons = buttons = []
- text = "Duplicate", "Write", "Delete", "Linear", "Cubic", "Split: No"
- x = 0
- for instruction in text:
- buttons.append(Button(self, instruction, x))
- x += buttons[-1].location.w + 10
-
- def set_nodeset_index(self, increment=None, index=None):
- parent = self.parent
- if index is None:
- if not increment:
- index = 0
- else:
- index = self.nodeset_index + increment
- limit = len(parent) - 1
- if index > limit:
- index = 0
- elif index < 0:
- index = limit
- self.nodeset_index = index
- self.set_nodeset_label()
-
- def set_nodeset_label(self):
- surface = self.font.render(self.get_nodeset().name, True, (0, 0, 0),
- (255, 255, 255))
- rect = surface.get_rect()
- rect.bottomright = self.display_surface.get_rect().bottomright
- self.nodeset_label, self.nodeset_label_rect = surface, rect
-
- def get_nodeset(self):
- if not len(self.parent):
- self.parent.add_nodeset(self.template_nodeset_name,
- self.template_nodeset)
- self.set_nodeset_index(0)
- return self.parent[self.nodeset_index]
-
- def set_y_range(self):
- width = self.plot_rect.w
- nodeset = self.get_nodeset()
- self.y_range = y_range = [nodeset[0].y, nodeset[-1].y]
- x = 0
- while x < width:
- y = nodeset.get_y(self.get_function_coordinates(x)[0])
- if y < y_range[0]:
- y_range[0] = y
- elif y > y_range[1]:
- y_range[1] = y
- x += width * .01
- if y_range[1] - y_range[0] == 0:
- y_range[1] += self.flat_y_range
- if self.split:
- self.adjust_for_split(y_range, nodeset)
- self.set_axis_labels()
-
- def get_function_coordinates(self, xp=0, yp=0):
- nodeset = self.get_nodeset()
- x_min, x_max, (y_min, y_max) = nodeset[0].x, nodeset[-1].x, self.y_range
- rect = self.plot_rect
- x = float(xp) / (rect.right - rect.left) * (x_max - x_min) + x_min
- y = float(yp) / (rect.bottom - rect.top) * (y_min - y_max) + y_max
- return x, y
-
- def adjust_for_split(self, y_range, nodeset):
- middle = nodeset[0].y if self.split == self.S_LEFT else nodeset[-1].y
- below, above = middle - y_range[0], y_range[1] - middle
- if below > above:
- y_range[1] += below - above
- else:
- y_range[0] -= above - below
-
- def set_axis_labels(self):
- self.axis_labels = labels = []
- nodeset, formatted, render, rect, yr = (self.get_nodeset(),
- self.get_formatted_measure,
- self.font.render,
- self.plot_rect, self.y_range)
- for ii, node in enumerate(nodeset[0::len(nodeset) - 1]):
- xs = render(formatted(node.x), True, (0, 0, 0), (255, 255, 255))
- xsr = xs.get_rect()
- xsr.top = rect.bottom
- if not ii:
- xsr.left = rect.left
- else:
- xsr.right = rect.right
- ys = render(formatted(yr[ii]), True, (0, 0, 0), (255, 255, 255))
- ysr = ys.get_rect()
- ysr.right = rect.left
- if not ii:
- ysr.bottom = rect.bottom
- else:
- ysr.top = rect.top
- labels.append(((xs, xsr), (ys, ysr)))
-
- def get_formatted_measure(self, measure):
- return "%s" % float(("%." + str(self.label_precision) + "g") % measure)
-
- def deactivate(self):
- self.active = False
- self.time_filter.open()
- self.audio.muted = self.saved_mute_state
- self.display.set_mouse_visibility(self.saved_mouse_state)
-
- def respond_to_command(self, event):
- compare = self.delegate.compare
- if compare(event, "toggle-interpolator"):
- self.toggle()
- elif self.active:
- if compare(event, "reset-game"):
- self.deactivate()
- elif compare(event, "quit"):
- self.get_game().end(event)
-
- def toggle(self):
- if self.active:
- self.deactivate()
- else:
- self.activate()
-
- def activate(self):
- self.active = True
- self.time_filter.close()
- self.saved_mute_state = self.audio.muted
- self.audio.mute()
- self.draw()
- self.saved_mouse_state = self.display.set_mouse_visibility(True)
-
- def respond_to_mouse_down(self, event):
- redraw = False
- if self.active and not self.prompt.active:
- nodeset_rect = self.nodeset_label_rect
- plot_rect = self.plot_rect
- if event.button == 1:
- pos = event.pos
- if nodeset_rect.collidepoint(pos):
- self.set_nodeset_index(1)
- redraw = True
- elif self.axis_labels[0][0][1].collidepoint(pos):
- text = "{0} {1}".format(*map(self.get_formatted_measure,
- self.get_nodeset()[0]))
- self.prompt.activate(text, self.resize_nodeset, 0)
- elif self.axis_labels[1][0][1].collidepoint(pos):
- text = "{0} {1}".format(*map(self.get_formatted_measure,
- self.get_nodeset()[-1]))
- self.prompt.activate(text, self.resize_nodeset, -1)
- else:
- bi = self.collide_buttons(pos)
- if bi is not None:
- if bi == self.B_WRITE:
- self.get_configuration().write()
- self.play(self.show_success_indicator)
- elif bi in (self.B_LINEAR, self.B_CUBIC):
- nodeset = self.get_nodeset()
- if bi == self.B_LINEAR:
- nodeset.set_interpolation_method(Nodeset.LINEAR)
- else:
- nodeset.set_interpolation_method(Nodeset.CUBIC)
- self.store_in_configuration()
- redraw = True
- elif bi == self.B_DUPLICATE:
- self.prompt.activate("", self.add_nodeset)
- elif bi == self.B_DELETE and len(self.parent) > 1:
- self.parent.remove(self.get_nodeset())
- self.set_nodeset_index(1)
- self.store_in_configuration()
- redraw = True
- elif bi == self.B_SPLIT:
- self.toggle_split()
- redraw = True
- elif plot_rect.collidepoint(pos) and \
- not self.collide_markers(pos):
- xp, yp = pos[0] - plot_rect.left, pos[1] - plot_rect.top
- self.get_nodeset().add_node(
- self.get_function_coordinates(xp, yp))
- self.store_in_configuration()
- redraw = True
- elif event.button == 3:
- pos = event.pos
- if nodeset_rect.collidepoint(pos):
- self.set_nodeset_index(-1)
- redraw = True
- elif plot_rect.collidepoint(pos):
- marker = self.collide_markers(pos)
- if marker:
- self.get_nodeset().remove(marker.node)
- self.store_in_configuration()
- redraw = True
- elif self.active and self.prompt.active and \
- not self.prompt.rect.collidepoint(event.pos):
- self.prompt.deactivate()
- redraw = True
- if redraw:
- self.set_y_range()
- self.set_markers()
- self.draw()
-
- def resize_nodeset(self, text, index):
- result = match("^\s*(-{,1}\d*\.{,1}\d*)\s+(-{,1}\d*\.{,1}\d*)\s*$",
- text)
- if result:
- try:
- nodeset = self.get_nodeset()
- x, y = map(float, result.group(1, 2))
- if (index == -1 and x > nodeset[0].x) or \
- (index == 0 and x < nodeset[-1].x):
- nodeset[index].y = y
- if index == -1:
- nodeset.resize(nodeset[0].x, x - nodeset[0].x)
- else:
- nodeset.resize(x, nodeset[-1].x - x)
- self.store_in_configuration()
- self.set_y_range()
- self.set_axis_labels()
- self.set_markers()
- self.draw()
- return True
- except ValueError:
- return False
-
- def collide_buttons(self, pos):
- for ii, button in enumerate(self.buttons):
- if button.location.collidepoint(pos):
- return ii
-
- def store_in_configuration(self):
- config = self.get_configuration()
- section = "interpolate"
- config.clear_section(section)
- for nodeset in self.parent:
- code = "L" if nodeset.interpolation_method == Nodeset.LINEAR else \
- "C"
- for ii, node in enumerate(nodeset):
- if ii > 0:
- code += ","
- code += " {0} {1}".format(*map(self.get_formatted_measure,
- node))
- if not config.has_section(section):
- config.add_section(section)
- config.set(section, nodeset.name, code)
-
- def toggle_split(self):
- self.split += 1
- if self.split > self.S_RIGHT:
- self.split = self.S_NONE
- self.buttons[self.B_SPLIT].set_frame(["Split: No", "Split: L",
- "Split: R"][self.split])
-
- def add_nodeset(self, name):
- nodeset = self.get_nodeset()
- self.set_nodeset_index(index=self.parent.add_nodeset(\
- name, nodeset, nodeset.interpolation_method))
- self.store_in_configuration()
- self.draw()
- return True
-
- def collide_markers(self, pos):
- for marker in self.markers:
- if marker.location.collidepoint(pos):
- return marker
-
- def set_markers(self):
- self.markers = markers = []
- for node in self.get_nodeset()[1:-1]:
- markers.append(Marker(self, node))
- markers[-1].location.center = self.get_plot_coordinates(*node)
-
- def get_plot_coordinates(self, x=0, y=0):
- nodeset = self.get_nodeset()
- x_min, x_max, (y_min, y_max) = nodeset[0].x, nodeset[-1].x, self.y_range
- x_ratio = float(x - x_min) / (x_max - x_min)
- rect = self.plot_rect
- xp = x_ratio * (rect.right - rect.left) + rect.left
- y_ratio = float(y - y_min) / (y_max - y_min)
- yp = rect.bottom - y_ratio * (rect.bottom - rect.top)
- return xp, yp
-
- def draw(self):
- display_surface = self.display_surface
- display_surface.blit(self.background, (0, 0))
- display_surface.blit(self.nodeset_label, self.nodeset_label_rect)
- self.draw_axes()
- self.draw_function()
- self.draw_markers()
- self.draw_buttons()
-
- def draw_axes(self):
- display_surface = self.display_surface
- for xl, yl in self.axis_labels:
- display_surface.blit(*xl)
- display_surface.blit(*yl)
-
- def draw_function(self):
- rect = self.plot_rect
- surface = self.display_surface
- nodeset = self.get_nodeset()
- step = 1
- for x in xrange(rect.left, rect.right + step, step):
- ii = x - rect.left
- fx = nodeset.get_y(self.get_function_coordinates(ii)[0])
- y = self.get_plot_coordinates(y=fx)[1]
- if ii > 0:
- aaline(surface, self.curve_color, (x - step, last_y), (x, y))
- last_y = y
-
- def draw_markers(self):
- for marker in self.markers:
- marker.update()
-
- def draw_buttons(self):
- for button in self.buttons:
- button.update()
-
- def respond_to_key(self, event):
- if self.prompt.active:
- prompt = self.prompt
- if event.key == K_RETURN:
- if prompt.callback[0](prompt.text, *prompt.callback[1]):
- prompt.deactivate()
- elif event.key == K_BACKSPACE:
- prompt.text = prompt.text[:-1]
- prompt.update()
- prompt.draw_text()
- elif (event.unicode.isalnum() or event.unicode.isspace() or \
- event.unicode in (".", "-", "_")) and len(prompt.text) < \
- prompt.character_limit:
- prompt.text += event.unicode
- prompt.update()
- prompt.draw_text()
-
- def show_success_indicator(self):
- self.draw()
- if self.success_indicator_blink_count > 1:
- self.success_indicator_blink_count = 0
- self.halt(self.show_success_indicator)
- else:
- if self.success_indicator_active:
- self.display_surface.blit(self.success_indicator,
- self.success_indicator_rect)
- if self.success_indicator_active:
- self.success_indicator_blink_count += 1
- self.success_indicator_active = not self.success_indicator_active
-
- def save_temporary_file(self):
- fp = self.temporary_file
- fp.seek(0)
- fp.truncate()
- self.get_configuration().write(fp)
-
- def rearrange(self):
- self.set_background()
- self.set_success_indicator()
- self.set_plot_rect()
- self.set_markers()
- self.set_nodeset_label()
- self.set_axis_labels()
- self.set_buttons()
- self.prompt.reset()
-
-class Marker(Sprite):
-
- def __init__(self, parent, node):
- Sprite.__init__(self, parent)
- self.add_frame(parent.marker_frame)
- self.node = node
-
-
-class Button(Sprite):
-
- def __init__(self, parent, text, left):
- Sprite.__init__(self, parent)
- self.set_frame(text)
- self.location.bottomleft = left, \
- self.get_display_surface().get_rect().bottom
-
- def set_frame(self, text):
- self.clear_frames()
- self.add_frame(self.parent.font.render(text, True, (0, 0, 0),
- (255, 255, 255)))
-
-
-class Prompt(Sprite):
-
- def __init__(self, parent):
- Sprite.__init__(self, parent)
- self.load_configuration()
- self.font = Font(None, self.text_size)
- self.reset()
- self.deactivate()
-
- def deactivate(self):
- self.active = False
-
- def load_configuration(self):
- config = self.get_configuration("interpolator-gui")
- self.size = config["prompt-size"]
- self.border_color = config["prompt-border-color"]
- self.border_width = config["prompt-border-width"]
- self.character_limit = config["prompt-character-limit"]
- self.text_size = config["prompt-text-size"]
-
- def reset(self):
- self.set_frame()
- self.place()
-
- def set_frame(self):
- self.clear_frames()
- surface = Surface(self.size)
- self.add_frame(surface)
- surface.fill(self.border_color)
- width = self.border_width * 2
- surface.fill((0, 0, 0), surface.get_rect().inflate(-width, -width))
-
- def place(self):
- self.location.center = self.display_surface.get_rect().center
-
- def activate(self, text, callback, *args):
- self.active = True
- self.text = str(text)
- self.callback = callback, args
- self.update()
- self.draw_text()
-
- def draw_text(self):
- surface = self.font.render(self.text, True, (255, 255, 255), (0, 0, 0))
- rect = surface.get_rect()
- rect.center = self.location.center
- self.display_surface.blit(surface, rect)
+++ /dev/null
-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
+++ /dev/null
-import cProfile
-from time import strftime
-from os import mkdir
-from os.path import join, exists
-
-from GameChild import GameChild
-
-class Profile(cProfile.Profile, GameChild):
-
- def __init__(self, parent):
- GameChild.__init__(self, parent)
- cProfile.Profile.__init__(self)
- if self.requested():
- self.enable()
-
- def requested(self):
- return self.check_command_line("p")
-
- def end(self):
- if self.requested():
- root = "stat/"
- if not exists(root):
- mkdir(root)
- self.disable()
- self.create_stats()
- self.dump_stats(join(root, strftime("%Y%m%d-%H%M_%S.stat")))
+++ /dev/null
-from os import makedirs
-from os.path import exists, join
-from sys import exc_info
-from time import strftime
-
-from pygame import image
-
-from GameChild import *
-from Input import *
-
-class ScreenGrabber(GameChild):
-
- def __init__(self, game):
- GameChild.__init__(self, game)
- self.delegate = self.get_delegate()
- self.load_configuration()
- self.subscribe(self.save_display)
-
- def load_configuration(self):
- config = self.get_configuration("screen-captures")
- self.save_path = config["path"]
- self.file_name_format = config["file-name-format"]
- self.file_extension = config["file-extension"]
-
- def save_display(self, event):
- if self.delegate.compare(event, "capture-screen"):
- directory = self.save_path
- try:
- if not exists(directory):
- makedirs(directory)
- name = self.build_name()
- path = join(directory, name)
- capture = image.save(self.get_screen(), path)
- self.print_debug("Saved screen capture to %s" % (path))
- except:
- self.print_debug("Couldn't save screen capture to %s, %s" %\
- (directory, exc_info()[1]))
-
- def build_name(self):
- return "{0}.{1}".format(strftime(self.file_name_format),
- self.file_extension)
+++ /dev/null
-from os import walk, remove
-from os.path import sep, join, exists, normpath
-from re import findall, sub
-from distutils.core import setup
-from distutils.command.install import install
-from pprint import pprint
-from fileinput import FileInput
-from re import sub, match
-
-from Configuration import *
-
-class Setup:
-
- config = Configuration()
- manifest_path = "MANIFEST"
-
- def __init__(self):
- pass
-
- def remove_old_mainfest(self):
- path = self.manifest_path
- if exists(path):
- remove(path)
-
- def build_package_list(self):
- packages = []
- config = self.config.get_section("setup")
- locations = [config["package-root"]] + config["additional-packages"]
- for location in locations:
- if exists(location):
- for root, dirs, files in walk(location, followlinks=True):
- packages.append(root.replace(sep, "."))
- return packages
-
- def build_data_map(self):
- include = []
- config = self.config.get_section("setup")
- exclude = map(normpath, config["data-exclude"])
- for root, dirs, files in walk("."):
- dirs = self.remove_excluded(dirs, root, exclude)
- files = [join(root, f) for f in self.remove_excluded(files, root,
- exclude)]
- if files:
- include.append((normpath(join(config["installation-path"],
- root)), files))
- return include
-
- def remove_excluded(self, paths, root, exclude):
- removal = []
- for path in paths:
- if normpath(join(root, path)) in exclude:
- removal.append(path)
- for path in removal:
- paths.remove(path)
- return paths
-
- def translate_title(self):
- config = self.config.get_section("setup")
- title = config["title"].replace(" ", config["whitespace-placeholder"])
- return sub("[^\w-]", config["special-char-placeholder"], title)
-
- def build_description(self):
- description = ""
- path = self.config.get("setup", "description-file")
- if exists(path):
- description = "\n%s\n%s\n%s" % (file(path).read(),
- "Changelog\n=========",
- self.translate_changelog())
- return description
-
- def translate_changelog(self):
- translation = ""
- path = self.config.get("setup", "changelog")
- if exists(path):
- lines = file(path).readlines()
- package_name = lines[0].split()[0]
- for line in lines:
- line = line.strip()
- if line.startswith(package_name):
- version = findall("\((.*)\)", line)[0]
- translation += "\n%s\n%s\n" % (version, "-" * len(version))
- elif line and not line.startswith("--"):
- if line.startswith("*"):
- translation += line + "\n"
- else:
- translation += " " + line + "\n"
- return translation
-
- def setup(self, windows=[], options={}):
- print "running setup..."
- self.remove_old_mainfest()
- config = self.config.get_section("setup")
- scripts = []
- if config["init-script"]:
- scripts.append(config["init-script"])
- setup(cmdclass={"install": insert_resource_path},
- name=self.translate_title(),
- packages=self.build_package_list(),
- scripts=scripts,
- data_files=self.build_data_map(),
- requires=config["requirements"],
- version=config["version"],
- description=config["summary"],
- classifiers=config["classifiers"],
- long_description=self.build_description(),
- license=config["license"],
- platforms=config["platforms"],
- author=config["contact-name"],
- author_email=config["contact-email"],
- url=config["url"],
- windows=windows,
- options=options)
-
-
-class insert_resource_path(install):
-
- def run(self):
- install.run(self)
- self.edit_game_object_file()
-
- def edit_game_object_file(self):
- config = Configuration().get_section("setup")
- for path in self.get_outputs():
- if path.endswith(config["main-object"]):
- for line in FileInput(path, inplace=True):
- pattern = "^ *{0} *=.*".\
- format(config["resource-path-identifier"])
- if match(pattern, line):
- line = sub("=.*$", "= \"{0}\"".\
- format(config["installation-path"]), line)
- print line.strip("\n")
+++ /dev/null
-from os import makedirs, walk, sep, remove
-from os.path import join, dirname, basename, exists
-from shutil import rmtree, copy, rmtree
-from itertools import chain
-from zipfile import ZipFile
-
-import py2exe
-
-from Setup import Setup
-
-class SetupWin(Setup):
-
- def __init__(self):
- Setup.__init__(self)
- self.replace_isSystemDLL()
-
- def replace_isSystemDLL(self):
- origIsSystemDLL = py2exe.build_exe.isSystemDLL
- def isSystemDLL(pathname):
- if basename(pathname).lower() in ("libogg-0.dll", "sdl_ttf.dll"):
- return 0
- return origIsSystemDLL(pathname)
- py2exe.build_exe.isSystemDLL = isSystemDLL
-
- def setup(self):
- config = self.config.get_section("setup")
- windows = [{}]
- if config["init-script"]:
- windows[0]["script"] = config["init-script"]
- if config["windows-icon-path"]:
- windows[0]["icon-resources"] = [(1, config["windows-icon-path"])]
- Setup.setup(self, windows,
- {"py2exe": {"packages": self.build_package_list(),
- "dist_dir": config["windows-dist-path"]}})
- rmtree("build")
- self.copy_data_files()
- self.create_archive()
-
- def copy_data_files(self):
- root = self.config.get("setup", "windows-dist-path")
- for path in chain(*zip(*self.build_data_map())[1]):
- dest = join(root, dirname(path))
- if not exists(dest):
- makedirs(dest)
- copy(path, dest)
- self.include_readme(root)
-
- def include_readme(self, root):
- name = "README"
- if exists(name):
- readme = open(name, "r")
- reformatted = open(join(root, name + ".txt"), "w")
- for line in open(name, "r"):
- reformatted.write(line.rstrip() + "\r\n")
-
- def create_archive(self):
- config = self.config.get_section("setup")
- title = self.translate_title() + "-" + config["version"] + "-win"
- archive_name = title + ".zip"
- archive = ZipFile(archive_name, "w")
- destination = config["windows-dist-path"]
- for root, dirs, names in walk(destination):
- for name in names:
- path = join(root, name)
- archive.write(path, path.replace(destination, title + sep))
- archive.close()
- copy(archive_name, "dist")
- remove(archive_name)
- rmtree(destination)
+++ /dev/null
-from os import listdir
-from os.path import isfile, join
-from sys import exc_info, stdout
-from glob import glob
-from traceback import print_exc, print_stack
-
-from pygame import Color, Rect, Surface
-from pygame.image import load
-from pygame.transform import flip
-from pygame.locals import *
-
-from Animation import Animation
-from Vector import Vector
-
-class Sprite(Animation):
-
- def __init__(self, parent, framerate=None):
- Animation.__init__(self, parent, self.shift_frame, framerate)
- self.frames = []
- self.mirrored = False
- self.alpha = 255
- self.locations = []
- self.framesets = [Frameset(self, framerate=framerate)]
- self.set_frameset(0)
- self.locations.append(Location(self))
- self.motion_overflow = Vector()
- self.display_surface = self.get_display_surface()
-
- def __getattr__(self, name):
- if name in ("location", "rect"):
- return self.locations[0]
- if hasattr(Animation, "__getattr__"):
- return Animation.__getattr__(self, name)
- raise AttributeError, name
-
- def set_frameset(self, identifier):
- if isinstance(identifier, str):
- for ii, frameset in enumerate(self.framesets):
- if frameset.name == identifier:
- identifier = ii
- break
- self.frameset_index = identifier
- self.register_interval()
- self.update_location_size()
- if self.get_current_frameset().length() > 1:
- self.play()
-
- def register_interval(self):
- self.register(self.shift_frame,
- interval=self.get_current_frameset().framerate)
-
- def get_current_frameset(self):
- return self.framesets[self.frameset_index]
-
- def update_location_size(self):
- size = self.get_current_frameset().rect.size
- for location in self.locations:
- location.size = size
- location.fader.init_surface()
-
- def set_framerate(self, framerate):
- self.get_current_frameset().set_framerate(framerate)
- self.register_interval()
-
- def load_from_path(self, path, transparency=False, ppa=True, key=None,
- extension=None, omit=False):
- if isfile(path):
- paths = [path]
- else:
- if extension:
- paths = sorted(glob(join(path, "*." + extension)))
- else:
- paths = [join(path, name) for name in sorted(listdir(path))]
- for path in paths:
- img = load(path)
- if transparency:
- if ppa:
- frame = img.convert_alpha()
- else:
- frame = self.fill_colorkey(img, key)
- else:
- frame = img.convert()
- self.add_frame(frame, omit)
-
- def fill_colorkey(self, img, key=None):
- if not key:
- key = (255, 0, 255)
- img = img.convert_alpha()
- frame = Surface(img.get_size())
- frame.fill(key)
- frame.set_colorkey(key)
- frame.blit(img, (0, 0))
- return frame
-
- def add_frame(self, frame, omit=False):
- self.frames.append(frame)
- frame.set_alpha(self.alpha)
- if not omit:
- frameset = self.get_current_frameset()
- frameset.add_index(self.frames.index(frame))
- self.update_location_size()
- if frameset.length() > 1:
- self.play()
-
- def shift_frame(self):
- self.get_current_frameset().shift()
-
- def get_current_frame(self):
- return self.frames[self.get_current_frameset().get_current_id()]
-
- def move(self, dx=0, dy=0):
- for location in self.locations:
- location.move_ip(dx, dy)
-
- def reset_motion_overflow(self):
- for location in self.locations:
- location.reset_motion_overflow()
-
- def collide(self, other):
- if not isinstance(other, Rect):
- other = other.rect
- for location in self.locations:
- if location.colliderect(other):
- return location
-
- def mirror(self):
- frames = self.frames
- for ii, frame in enumerate(frames):
- frames[ii] = flip(frame, True, False)
- self.mirrored = not self.mirrored
-
- def clear_frames(self):
- self.frames = []
- for frameset in self.framesets:
- frameset.order = []
- frameset.reset()
- frameset.measure_rect()
-
- def add_location(self, topleft=None, offset=(0, 0), count=1, base=0):
- if topleft is not None:
- for ii in xrange(count):
- self.locations.append(Location(
- self, Rect(topleft, self.locations[0].size)))
- else:
- base = self.locations[base]
- current_offset = list(offset)
- for ii in xrange(count):
- self.locations.append(Location(self,
- base.move(*current_offset)))
- current_offset[0] += offset[0]
- current_offset[1] += offset[1]
- return self.locations[-1]
-
- def fade(self, length=0, out=None, index=None):
- if index is None:
- for location in self.locations:
- location.fader.start(length, out)
- else:
- self.locations[index].fader.start(length, out)
-
- def set_alpha(self, alpha):
- self.alpha = alpha
- for frame in self.frames:
- frame.set_alpha(alpha)
- for location in self.locations:
- location.fader.set_alpha()
-
- def add_frameset(self, order=[], framerate=None, name=None, switch=False):
- frameset = Frameset(self, order, framerate, name)
- self.framesets.append(frameset)
- if switch:
- self.set_frameset(len(self.framesets) - 1)
- return frameset
-
- def hide(self):
- for location in self.locations:
- location.hide()
-
- def unhide(self):
- for location in self.locations:
- location.unhide()
-
- def is_hidden(self):
- return all(location.is_hidden() for location in self.locations)
-
- def remove_locations(self, location=None):
- if location:
- self.locations.remove(location)
- else:
- self.locations = self.locations[:1]
-
- def reverse(self, frameset=None):
- if frameset:
- frameset.reverse()
- else:
- for frameset in self.framesets:
- frameset.reverse()
-
- def update(self, flags=0):
- Animation.update(self)
- self.draw(flags)
-
- def draw(self, flags=0):
- for location in self.locations:
- location.fader.draw(flags)
-
-
-class Location(Rect):
-
- def __init__(self, sprite, rect=(0, 0, 0, 0)):
- self.sprite = sprite
- Rect.__init__(self, rect)
- self.motion_overflow = Vector()
- self.fader = Fader(self)
- self.unhide()
-
- def move_ip(self, dx, dy):
- if isinstance(dx, float) or isinstance(dy, float):
- excess = self.update_motion_overflow(dx, dy)
- Rect.move_ip(self, int(dx) + excess[0], int(dy) + excess[1])
- else:
- Rect.move_ip(self, dx, dy)
-
- def update_motion_overflow(self, dx, dy):
- overflow = self.motion_overflow
- overflow.move(dx - int(dx), dy - int(dy))
- excess = map(int, overflow)
- overflow[0] -= int(overflow[0])
- overflow[1] -= int(overflow[1])
- return excess
-
- def reset_motion_overflow(self):
- self.motion_overflow.place_at_origin()
-
- def hide(self):
- self.hidden = True
-
- def unhide(self):
- self.hidden = False
-
- def is_hidden(self):
- return self.hidden
-
-
-class Fader(Surface):
-
- def __init__(self, location):
- self.location = location
- self.time_filter = location.sprite.get_game().time_filter
- self.reset()
-
- def reset(self):
- self.init_surface()
- self.fade_remaining = None
-
- def init_surface(self):
- Surface.__init__(self, self.location.size)
- if self.location.sprite.get_current_frameset().length():
- background = Surface(self.get_size())
- sprite = self.location.sprite
- key = sprite.get_current_frame().get_colorkey() or (255, 0, 255)
- self.set_colorkey(key)
- background.fill(key)
- self.background = background
- self.set_alpha()
-
- def set_alpha(self, alpha=None):
- if alpha is None:
- alpha = self.location.sprite.alpha
- Surface.set_alpha(self, alpha)
-
- def start(self, length, out=None):
- if self.fade_remaining <= 0:
- alpha = self.get_alpha()
- maximum = self.location.sprite.alpha
- if out is None:
- out = alpha == maximum
- if out and alpha > 0 or not out and alpha < maximum:
- self.fade_length = self.fade_remaining = length
- self.start_time = self.time_filter.get_ticks()
- self.fading_out = out
-
- def draw(self, flags):
- sprite = self.location.sprite
- if self.fade_remaining >= 0:
- self.update_alpha()
- self.clear()
- frame = sprite.get_current_frame()
- frame.set_alpha(255)
- self.blit(frame, (0, 0))
- frame.set_alpha(sprite.alpha)
- if not self.location.hidden:
- self.blit_to_display(self, flags)
- elif self.fade_remaining is None or self.get_alpha() >= sprite.alpha:
- if self.fade_remaining >= 0:
- self.update_alpha()
- if not self.location.hidden:
- self.blit_to_display(sprite.get_current_frame(), flags)
-
- def blit_to_display(self, frame, flags):
- self.location.sprite.display_surface.blit(frame, self.location, None,
- flags)
-
- def update_alpha(self):
- remaining = self.fade_remaining = self.fade_length - \
- (self.time_filter.get_ticks() - self.start_time)
- ratio = self.fade_length and float(remaining) / self.fade_length
- if not self.fading_out:
- ratio = 1 - ratio
- maximum = self.location.sprite.alpha
- alpha = int(ratio * maximum)
- if alpha > maximum:
- alpha = maximum
- elif alpha < 0:
- alpha = 0
- self.set_alpha(alpha)
-
- def clear(self):
- self.blit(self.background, (0, 0))
-
-
-class Frameset():
-
- def __init__(self, sprite, order=[], framerate=None, name=None):
- self.sprite = sprite
- self.name = name
- self.reversed = False
- self.order = []
- self.rect = Rect(0, 0, 0, 0)
- self.add_index(order)
- self.set_framerate(framerate)
- self.reset()
-
- def add_index(self, order):
- if isinstance(order, int):
- order = [order]
- self.order += order
- self.measure_rect()
-
- def set_framerate(self, framerate):
- self.framerate = framerate
-
- def reset(self):
- self.current_index = 0
-
- def get_current_id(self):
- return self.order[self.current_index]
-
- def measure_rect(self):
- max_width, max_height = 0, 0
- frames = self.sprite.frames
- for index in self.order:
- frame = frames[index]
- width, height = frame.get_size()
- max_width = max(width, max_width)
- max_height = max(height, max_height)
- self.rect.size = max_width, max_height
-
- def shift(self):
- if len(self.order) > 1:
- self.increment_index()
-
- def increment_index(self):
- increment = 1 if not self.reversed else -1
- index = self.current_index + increment
- if index < 0:
- index = self.length() - 1
- elif index >= self.length():
- index = 0
- self.current_index = index
-
- def length(self):
- return len(self.order)
-
- def reverse(self):
- self.reversed = not self.reversed
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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.display_surface = self.get_display_surface()
- self.delegate = self.get_delegate()
- self.load_configuration()
- self.reset()
- self.subscribe(self.respond)
-
- 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
--- /dev/null
+Subproject commit a0aba9a0bb527ec7f3d7269cdd522448560a99c3
1913
1709
2442
+3940
+676