interpolator; cubic splines; sprite hide; write user config
This commit is contained in:
parent
b325cbaada
commit
206caee387
17
README
17
README
|
@ -6,11 +6,10 @@ Classes to facilitate creation of Pygame projects
|
|||
|
||||
|
||||
Example
|
||||
=======
|
||||
-------
|
||||
|
||||
Save and run the following script to create a project that redraws a square at a
|
||||
random location every second. This script is also written in the `sample.py`
|
||||
file.
|
||||
Save and run to create a project that redraws a square at a random location
|
||||
every second. This script is also written in the `sample.py` file.
|
||||
|
||||
from time import sleep
|
||||
from random import randint
|
||||
|
@ -21,7 +20,7 @@ class SampleGame(Game):
|
|||
|
||||
square_width = 30
|
||||
|
||||
# update is a special method that runs once every frame
|
||||
# instructions in the update method automatically run once every frame
|
||||
def update(self):
|
||||
sleep(1)
|
||||
screen = self.get_screen()
|
||||
|
@ -37,21 +36,21 @@ if __name__ == '__main__':
|
|||
|
||||
|
||||
License
|
||||
=======
|
||||
-------
|
||||
|
||||
This software is dedicated to the public domain. See
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ for details.
|
||||
|
||||
|
||||
Todo
|
||||
====
|
||||
----
|
||||
|
||||
- Remove unecessary python libraries from windows build
|
||||
- Debug levels
|
||||
|
||||
|
||||
Contact
|
||||
=======
|
||||
-------
|
||||
|
||||
frank dot s dot demarco at gmail
|
||||
http://a-o.in
|
||||
http://A-O.in
|
||||
|
|
|
@ -128,7 +128,11 @@ class Configuration(RawConfigParser):
|
|||
def read_project_config_file(self):
|
||||
path = self.locate_project_config_file()
|
||||
if path:
|
||||
self.read(path)
|
||||
fp = open(path)
|
||||
self.set_modifiable(fp)
|
||||
fp.seek(0)
|
||||
self.readfp(fp)
|
||||
fp.close()
|
||||
else:
|
||||
self.print_debug("No configuration file found")
|
||||
|
||||
|
@ -146,6 +150,17 @@ class Configuration(RawConfigParser):
|
|||
def is_shared_mode(self):
|
||||
return "-s" in argv
|
||||
|
||||
def set_modifiable(self, fp):
|
||||
config = RawConfigParser()
|
||||
config.readfp(fp)
|
||||
modifiable = []
|
||||
for section in config._sections:
|
||||
modifiable.append([section, []])
|
||||
for option in config._sections[section]:
|
||||
if option != "__name__":
|
||||
modifiable[-1][1].append(option)
|
||||
self.modifiable = modifiable
|
||||
|
||||
def print_debug(self, statement):
|
||||
if self.is_debug_mode():
|
||||
print statement
|
||||
|
@ -266,6 +281,25 @@ class Configuration(RawConfigParser):
|
|||
items.append((option, self.get(section, option)))
|
||||
return items
|
||||
|
||||
def write(self, fp):
|
||||
for section in self.modifiable:
|
||||
fp.write("[%s]\n" % section[0])
|
||||
for name in section[1]:
|
||||
value = self.get(section[0], name)
|
||||
fp.write("%s = %s\n" % (name, self.get_raw_value(value)))
|
||||
fp.write("\n")
|
||||
|
||||
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
|
||||
|
||||
|
||||
class TypeDeclarations(dict):
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ from Input import Input
|
|||
from ScreenGrabber import ScreenGrabber
|
||||
from Profile import Profile
|
||||
from VideoRecorder import VideoRecorder
|
||||
from Interpolator import Interpolator
|
||||
|
||||
class Game(GameChild):
|
||||
|
||||
|
@ -43,6 +44,7 @@ class Game(GameChild):
|
|||
self.audio = Audio(self)
|
||||
self.screen_grabber = ScreenGrabber(self)
|
||||
self.video_recorder = VideoRecorder(self)
|
||||
self.interpolator = Interpolator(self)
|
||||
|
||||
def frame(self):
|
||||
self.delegate.dispatch()
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
from GameChild import GameChild
|
||||
|
||||
class Interpolator(dict, GameChild):
|
||||
|
||||
def __init__(self, parent):
|
||||
GameChild.__init__(self, parent)
|
||||
self.read()
|
||||
|
||||
def read(self):
|
||||
for name, value in self.get_configuration("interpolate").iteritems():
|
||||
self[name] = Nodes(value)
|
||||
|
||||
|
||||
class Nodes(list):
|
||||
|
||||
LINEAR, CUBIC = range(2)
|
||||
|
||||
def __init__(self, raw):
|
||||
list.__init__(self, [])
|
||||
self.parse_raw(raw)
|
||||
self.set_splines()
|
||||
|
||||
def parse_raw(self, raw):
|
||||
raw = raw.strip()
|
||||
if raw[0].upper() == "L":
|
||||
self.interpolation_method = self.LINEAR
|
||||
else:
|
||||
self.interpolation_method = self.CUBIC
|
||||
for node in raw[1:].strip().split(","):
|
||||
self.append(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):
|
||||
pass
|
||||
|
||||
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 = [Spline(a[ii], b[ii], c[ii], d[ii], self[ii].x) for \
|
||||
ii in xrange(n)]
|
||||
|
||||
def get_y(self, t):
|
||||
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 __repr__(self):
|
||||
return "<%i, %s>" % (self.interpolation_method, list(self))
|
||||
|
||||
def print_checkpoints(self):
|
||||
start, end = int(self[0].x), int(self[-1].x)
|
||||
step = (end - start) / 8
|
||||
for t in xrange(start, end + step, step):
|
||||
print "%i\t%.3f" % (t, self.get_y(t))
|
||||
|
||||
|
||||
class Node(list):
|
||||
|
||||
def __init__(self, raw):
|
||||
list.__init__(self, (float(value) for value in raw.strip().split()))
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == "x":
|
||||
return self[0]
|
||||
elif name == "y":
|
||||
return self[1]
|
||||
return list.__get__(self, name)
|
||||
|
||||
|
||||
class Spline:
|
||||
|
||||
def __init__(self, a, b, c, d, x):
|
||||
self.a = a
|
||||
self.b = b
|
||||
self.c = c
|
||||
self.d = d
|
||||
self.x = x
|
||||
|
||||
def __repr__(self):
|
||||
x = self.x
|
||||
return ("<%.1e + %.1e * (x - %.1e) + %.1e * (x - %.1e) ** 2 + " + \
|
||||
"%.1e * (x - %.1e) ** 3>") % (self.a, self.b, x, self.c, x,
|
||||
self.d, x)
|
||||
|
||||
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
|
|
@ -19,6 +19,7 @@ class Sprite(Animation):
|
|||
Animation.__init__(self, parent, self.shift_frame, framerate)
|
||||
self.clear_frames()
|
||||
self.mirrored = False
|
||||
self.hidden = False
|
||||
self.alpha = 255
|
||||
self.locations = [Location(self)]
|
||||
self.framesets = [Frameset(self, framerate=framerate)]
|
||||
|
@ -42,6 +43,8 @@ class Sprite(Animation):
|
|||
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,
|
||||
|
@ -161,6 +164,12 @@ class Sprite(Animation):
|
|||
def add_frameset(self, order, framerate=None, name=None):
|
||||
self.framesets.append(Frameset(self, order, framerate, name))
|
||||
|
||||
def hide(self):
|
||||
self.hidden = True
|
||||
|
||||
def unhide(self):
|
||||
self.hidden = False
|
||||
|
||||
def update(self):
|
||||
Animation.update(self)
|
||||
self.draw()
|
||||
|
@ -243,13 +252,16 @@ class Fader(Surface):
|
|||
frame.set_alpha(255)
|
||||
self.blit(frame, (0, 0))
|
||||
frame.set_alpha(sprite.alpha)
|
||||
sprite.display_surface.blit(self, self.location)
|
||||
if not sprite.hidden:
|
||||
self.blit_to_display(self)
|
||||
elif self.fade_remaining is None or self.get_alpha() >= sprite.alpha:
|
||||
if self.fade_remaining >= 0:
|
||||
self.update_alpha()
|
||||
sprite.display_surface.blit(sprite.get_current_frame(),
|
||||
self.location)
|
||||
if not sprite.hidden:
|
||||
self.blit_to_display(sprite.get_current_frame())
|
||||
|
||||
def blit_to_display(self, frame):
|
||||
self.location.sprite.display_surface.blit(frame, self.location)
|
||||
|
||||
def update_alpha(self):
|
||||
remaining = self.fade_remaining = self.fade_length - (get_ticks() - \
|
||||
|
|
Loading…
Reference in New Issue