From ffebbcd2dee04b8c06e90432618e0e013ac5b7dc Mon Sep 17 00:00:00 2001 From: Alex Xu Date: Sun, 30 Mar 2014 13:42:48 -0400 Subject: unrpyc -> ast2json --- unrpyc/renpy/display/anim.py | 634 ------------------------------------------- 1 file changed, 634 deletions(-) delete mode 100644 unrpyc/renpy/display/anim.py (limited to 'unrpyc/renpy/display/anim.py') diff --git a/unrpyc/renpy/display/anim.py b/unrpyc/renpy/display/anim.py deleted file mode 100644 index de1398a..0000000 --- a/unrpyc/renpy/display/anim.py +++ /dev/null @@ -1,634 +0,0 @@ -# Copyright 2004-2013 Tom Rothamel -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation files -# (the "Software"), to deal in the Software without restriction, -# including without limitation the rights to use, copy, modify, merge, -# publish, distribute, sublicense, and/or sell copies of the Software, -# and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -# This file contains support for state-machine controlled animations. - -import renpy.display -import random - -class State(object): - """ - This creates a state that can be used in a SMAnimation. - """ - - - def __init__(self, name, image, *atlist, **properties): - """ - @param name: A string giving the name of this state. - - @param image: The displayable that is shown to the user while - we are in (entering) this state. For convenience, this can - also be a string or tuple, which is interpreted with Image. - - image should be None when this State is used with motion, - to indicate that the image will be replaced with the child of - the motion. - - @param atlist: A list of functions to call on the image. (In - general, if something can be used in an at clause, it can be - used here as well.) - - If any keyword arguments are given, they are used to construct a - Position object, that modifies the position of the image. - """ - - if image and not isinstance(image, renpy.display.core.Displayable): - image = renpy.easy.displayable(image) - - self.name = name - self.image = image - self.atlist = atlist - self.properties = properties - - - def add(self, sma): - sma.states[self.name] = self - - def get_image(self): - rv = self.image - - for i in self.atlist: - rv = i(rv) - - if self.properties: - rv = renpy.display.layout.Position(rv, **self.properties) - - return rv - - def motion_copy(self, child): - - if self.image is not None: - child = self.image - - return State(self.name, child, *self.atlist) - - -class Edge(object): - """ - This creates an edge that can be used with a SMAnimation. - """ - - def __init__(self, old, delay, new, trans=None, prob=1): - """ - @param old: The name (a string) of the state that this transition is from. - - @param delay: The number of seconds that this transition takes. - - @param new: The name (a string) of the state that this transition is to. - - @param trans: The transition that will be used to show the - image found in the new state. If None, the image is show - immediately. - - When used with an SMMotion, the transition should probably be - move. - - @param prob: The number of times this edge is added. This can - be used to make a transition more probable then others. For - example, if one transition out of a state has prob=5, and the - other has prob=1, then the one with prob=5 will execute 5/6 of - the time, while the one with prob=1 will only occur 1/6 of the - time. (Don't make this too large, as memory use is proportional to - this value.) - """ - - self.old = old - self.delay = delay - self.new = new - self.trans = trans - self.prob = prob - - def add(self, sma): - for _i in range(0, self.prob): - sma.edges.setdefault(self.old, []).append(self) - - -class SMAnimation(renpy.display.core.Displayable): - """ - This creates a state-machine animation. Such an animation is - created by randomly traversing the edges between states in a - defined state machine. Each state corresponds to an image shown to - the user, with the edges corresponding to the amount of time an - image is shown, and the transition it is shown with. - - Images are shown, perhaps with a transition, when we are - transitioning into a state containing that image. - """ - - def __init__(self, initial, *args, **properties): - """ - @param initial: The name (a string) of the initial state we - start in. - - @param showold: If the keyword parameter showold is True, then - the old image is shown instead of the new image when in an - edge. - - @param anim_timebase: If True, we use the animation - timebase. If False, we use the displayable timebase. - - This accepts as additional arguments the anim.State and - anim.Edge objects that are used to make up this state - machine. - """ - - if 'delay' in properties: - self.delay = properties['delay'] - del properties['delay'] - else: - self.delay = None - - if 'showold' in properties: - self.showold = properties['showold'] - del properties['showold'] - else: - self.showold = False - - if 'anim_timebase' in properties: - self.anim_timebase = properties['anim_timebase'] - del properties['anim_timebase'] - else: - self.anim_timebase = True - - super(SMAnimation, self).__init__(**properties) - - self.properties = properties - - # The initial state. - self.initial = initial - - # A map from state name to State object. - self.states = { } - - # A map from state name to list of Edge objects. - self.edges = { } - - for i in args: - i.add(self) - - # The time at which the current edge started. If None, will be - # set to st by render. - self.edge_start = None - - # A cache for what the current edge looks like when rendered. - self.edge_cache = None - - # The current edge. - self.edge = None - - # The state we're in. - self.state = None - - def visit(self): - return [ i.image for i in self.states.values() ] - - def pick_edge(self, state): - """ - This randomly picks an edge out of the given state, if - one exists. It updates self.edge if a transition has - been selected, or returns None if none can be found. It also - updates self.image to be the new image on the selected edge. - """ - - if state not in self.edges: - self.edge = None - return - - edges = self.edges[state] - self.edge = random.choice(edges) - self.state = self.edge.new - - def update_cache(self): - """ - Places the correct Displayable into the edge cache, based on - what is contained in the given edge. This takes into account - the old and new states, and any transition that is present. - """ - - - if self.edge.trans: - im = self.edge.trans(old_widget=self.states[self.edge.old].get_image(), - new_widget=self.states[self.edge.new].get_image()) - elif self.showold: - im = self.states[self.edge.old].get_image() - else: - im = self.states[self.edge.new].get_image() - - self.edge_cache = im - - def get_placement(self): - - if self.edge_cache: - return self.edge_cache.get_placement() - - if self.state: - return self.states[self.state].get_image().get_placement() - - return super(SMAnimation, self).get_placement() - - def render(self, width, height, st, at): - - if self.anim_timebase: - t = at - else: - t = st - - if self.edge_start is None or t < self.edge_start: - self.edge_start = t - self.edge_cache = None - self.pick_edge(self.initial) - - while self.edge and t > self.edge_start + self.edge.delay: - self.edge_start += self.edge.delay - self.edge_cache = None - self.pick_edge(self.edge.new) - - # If edge is None, then we have a permanent, static picture. Deal - # with that. - - if not self.edge: - im = renpy.display.render.render(self.states[self.state].get_image(), - width, height, - st - self.edge_start, at) - - - # Otherwise, we have another edge. - - else: - if not self.edge_cache: - self.update_cache() - - im = renpy.display.render.render(self.edge_cache, width, height, t - self.edge_start, at) - - if not renpy.game.less_updates: - renpy.display.render.redraw(self.edge_cache, self.edge.delay - (t - self.edge_start)) - - - iw, ih = im.get_size() - - rv = renpy.display.render.Render(iw, ih) - rv.blit(im, (0, 0)) - - return rv - - def __call__(self, child=None, new_widget=None, old_widget=None): - """ - Used when this SMAnimation is used as a SMMotion. This creates - a duplicate of the animation, with all states containing None - as the image having that None replaced with the image that is provided here. - """ - - if child is None: - child = new_widget - - args = [ ] - - for state in self.states.values(): - args.append(state.motion_copy(child)) - - for edges in self.edges.values(): - args.extend(edges) - - return SMAnimation(self.initial, delay=self.delay, *args, **self.properties) - - -# class Animation(renpy.display.core.Displayable): -# """ -# A Displayable that draws an animation, which is a series of images -# that are displayed with time delays between them. -# """ - -# def __init__(self, *args, **properties): -# """ -# Odd (first, third, fifth, etc.) arguments to Animation are -# interpreted as image filenames, while even arguments are the -# time to delay between each image. If the number of arguments -# is odd, the animation will stop with the last image (well, -# actually delay for a year before looping). Otherwise, the -# animation will restart after the final delay time. - -# @param anim_timebase: If True, the default, use the animation -# timebase. Otherwise, use the displayable timebase. -# """ - -# properties.setdefault('style', 'animation') -# self.anim_timebase = properties.pop('anim_timebase', True) - -# super(Animation, self).__init__(**properties) - -# self.images = [ ] -# self.delays = [ ] - -# for i, arg in enumerate(args): - -# if i % 2 == 0: -# self.images.append(renpy.easy.displayable(arg)) -# else: -# self.delays.append(arg) - -# if len(self.images) > len(self.delays): -# self.delays.append(365.25 * 86400.0) # One year, give or take. - -# def render(self, width, height, st, at): - -# if self.anim_timebase: -# t = at % sum(self.delays) -# else: -# t = st % sum(self.delays) - -# for image, delay in zip(self.images, self.delays): -# if t < delay: -# renpy.display.render.redraw(self, delay - t) - -# im = renpy.display.render.render(image, width, height, t, at) -# width, height = im.get_size() -# rv = renpy.display.render.Render(width, height) -# rv.blit(im, (0, 0)) - -# return rv - -# else: -# t = t - delay - -# def visit(self): -# return self.images - -def Animation(*args, **kwargs): - newargs = [ ] - - for i, a in enumerate(args): - newargs.append(a) - if i % 2 == 1: - newargs.append(None) - - return TransitionAnimation(*newargs, **kwargs) - - -class TransitionAnimation(renpy.display.core.Displayable): - """ - A displayable that draws an animation with each frame separated - by a transition. - """ - - def __init__(self, *args, **properties): - """ - This takes arguments such that the 1st, 4th, 7th, ... - arguments are displayables, the 2nd, 5th, 8th, ... on arguments - are times, and the 3rd, 6th, 9th, ... are transitions. - - This displays the first displayable for the given time, then - transitions to the second displayable using the given - transition, and shows it for the given time (the time of the - transition is taken out of the time the frame is shown), and - so on. - - The last argument may be a displayable (in which case that - displayable is used to transition back to the first frame), or - a displayable (which is shown forever). - - There is one keyword argument, apart from the style properties: - - @param anim_timebase: If True, the default, use the animation - timebase. Otherwise, use the displayable timebase. - """ - - properties.setdefault('style', 'animation') - self.anim_timebase = properties.pop('anim_timebase', True) - - super(TransitionAnimation, self).__init__(**properties) - - images = [ ] - delays = [ ] - transitions = [ ] - - for i, arg in enumerate(args): - - if i % 3 == 0: - images.append(renpy.easy.displayable(arg)) - elif i % 3 == 1: - delays.append(arg) - else: - transitions.append(arg) - - if len(images) > len(delays): - delays.append(365.25 * 86400.0) # One year, give or take. - if len(images) > len(transitions): - transitions.append(None) - - self.images = images - self.prev_images = [ images[-1] ] + images[:-1] - self.delays = delays - self.transitions = [ transitions[-1] ] + transitions[:-1] - - - def render(self, width, height, st, at): - - if self.anim_timebase: - orig_t = at - else: - orig_t = st - - t = orig_t % sum(self.delays) - - for image, prev, delay, trans in zip(self.images, self.prev_images, self.delays, self.transitions): - if t < delay: - if not renpy.game.less_updates: - renpy.display.render.redraw(self, delay - t) - - if trans and orig_t >= self.delays[0]: - image = trans(old_widget=prev, new_widget=image) - - im = renpy.display.render.render(image, width, height, t, at) - width, height = im.get_size() - rv = renpy.display.render.Render(width, height) - rv.blit(im, (0, 0)) - - return rv - - else: - t = t - delay - - def visit(self): - return self.images - -class Blink(renpy.display.core.Displayable): - """ - """ - - def __init__(self, image, on=0.5, off=0.5, rise=0.5, set=0.5, #@ReservedAssignment - high=1.0, low=0.0, offset=0.0, anim_timebase=False, **properties): - - """ - This takes as an argument an image or widget, and blinks that image - by varying its alpha. The sequence of phases is - on - set - off - rise - on - ... All times are given in seconds, all - alphas are fractions between 0 and 1. - - @param image: The image or widget that will be blinked. - - @param on: The amount of time the widget spends on, at high alpha. - - @param off: The amount of time the widget spends off, at low alpha. - - @param rise: The amount time the widget takes to ramp from low to high alpha. - - @param set: The amount of time the widget takes to ram from high to low. - - @param high: The high alpha. - - @param low: The low alpha. - - @param offset: A time offset, in seconds. Use this to have a - blink that does not start at the start of the on phase. - - @param anim_timebase: If True, use the animation timebase, if false, the displayable timebase. - """ - - super(Blink, self).__init__(**properties) - - self.image = renpy.easy.displayable(image) - self.on = on - self.off = off - self.rise = rise - self.set = set - self.high = high - self.low = low - self.offset = offset - self.anim_timebase = anim_timebase - - self.cycle = on + set + off + rise - - - def visit(self): - return [ self.image ] - - def render(self, height, width, st, at): - - if self.anim_timebase: - t = at - else: - t = st - - time = (self.offset + t) % self.cycle - alpha = self.high - - if 0 <= time < self.on: - delay = self.on - time - alpha = self.high - - time -= self.on - - if 0 <= time < self.set: - delay = 0 - frac = time / self.set - alpha = self.low * frac + self.high * (1.0 - frac) - - time -= self.set - - if 0 <= time < self.off: - delay = self.off - time - alpha = self.low - - time -= self.off - - if 0 <= time < self.rise: - delay = 0 - frac = time / self.rise - alpha = self.high * frac + self.low * (1.0 - frac) - - - rend = renpy.display.render.render(self.image, height, width, st, at) - w, h = rend.get_size() - rv = renpy.display.render.Render(w, h) - - rv.blit(rend, (0, 0)) - rv.alpha = alpha - - if not renpy.game.less_updates: - renpy.display.render.redraw(self, delay) - - return rv - - - -def Filmstrip(image, framesize, gridsize, delay, frames=None, loop=True, **properties): - """ - This creates an animation from a single image. This image - must consist of a grid of frames, with the number of columns and - rows in the grid being taken from gridsize, and the size of each - frame in the grid being taken from framesize. This takes frames - and sticks them into an Animation, with the given delay between - each frame. The frames are taken by going from left-to-right - across the first row, left-to-right across the second row, and - so on until all frames are consumed, or a specified number of - frames are taken. - - @param image: The image that the frames must be taken from. - - @param framesize: A (width, height) tuple giving the size of - each of the frames in the animation. - - @param gridsize: A (columns, rows) tuple giving the number of - columns and rows in the grid. - - @param delay: The delay, in seconds, between frames. - - @param frames: The number of frames in this animation. If None, - then this defaults to colums * rows frames, that is, taking - every frame in the grid. - - @param loop: If True, loop at the end of the animation. If False, - this performs the animation once, and then stops. - - Other keyword arguments are as for anim.SMAnimation. - """ - - width, height = framesize - cols, rows = gridsize - - if frames is None: - frames = cols * rows - - i = 0 - - # Arguments to Animation - args = [ ] - - for r in range(0, rows): - for c in range(0, cols): - - x = c * width - y = r * height - - args.append(renpy.display.im.Crop(image, x, y, width, height)) - args.append(delay) - - i += 1 - if i == frames: - break - - if i == frames: - break - - if not loop: - args.pop() - - return Animation(*args, **properties) -- cgit v1.2.3-54-g00ecf