display surface

This commit is contained in:
Frank DeMarco 2013-03-30 19:18:04 +09:00
parent 0bce7c6973
commit 47b3bc1feb
5 changed files with 99 additions and 35 deletions

View File

@ -7,21 +7,33 @@ class Animation(GameChild):
def __init__(self, parent, method=None, interval=None):
GameChild.__init__(self, parent)
self.default_method = method or self.build_frame
self.accounts = {self.default_method: Account(interval)}
self.accounts = {}
self.register(self.default_method, interval=interval)
self.current_elapsed = 0
self.last_update = 0
def build_frame(self):
pass
def register(self, method, interval=None, delay=0):
if method not in self.accounts:
self.accounts[method] = Account(interval, delay)
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)
else:
self.accounts[method].set_interval(interval)
def play(self, method=None, interval=None, delay=0):
method = self.get_default(method)
self.register(method, interval, delay)
self.accounts[method].play()
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):
if not method:
@ -36,25 +48,44 @@ class Animation(GameChild):
if self.accounts.has_key(method):
self.accounts[method].halt()
def is_playing(self, method=None):
return self.accounts[self.get_default(method)].playing
def update(self):
for method, account in self.accounts.iteritems():
if account.update():
method()
method(**account.args)
class Account:
def __init__(self, interval, delay=0):
self.interval = interval
self.delay = delay
def __init__(self, interval):
self.set_interval(interval)
self.set_delay(0)
self.set_play_once(False)
self.interval_index = 0
self.last_frame = 0
self.last_update = None
self.halt()
def set_interval(self, interval):
if isinstance(interval, int):
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):
@ -64,11 +95,23 @@ class Account:
if not self.delay:
interval = self.interval
if interval:
if ticks - self.last_frame < 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:

View File

@ -31,6 +31,15 @@ class GameChild:
def get_screen(self):
return self.get_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.get_game().audio

View File

@ -1,4 +1,4 @@
from time import time
from time import time as get_secs
from pygame import event, joystick as joy, key as keyboard
from pygame.locals import *
@ -47,8 +47,8 @@ class Input(GameChild):
if key in keys:
self.post_command(cmd)
def post_command(self, cmd):
self.get_delegate().post(cmd)
def post_command(self, cmd, **attributes):
self.get_delegate().post(cmd, **attributes)
def translate_joy_button(self, evt):
if not self.suppressed:
@ -104,9 +104,9 @@ class Input(GameChild):
if last:
limit = self.get_configuration("mouse",
"double-click-time-limit")
if time() - last < limit:
if get_secs() - last < limit:
post("mouse-double-click-left", pos=pos)
last = time()
last = get_secs()
self.last_mouse_down_left = last
post("mouse-down-left", pos=pos)
elif button == 2:

View File

@ -14,3 +14,6 @@ class Point(list):
self[0] += dx
if dy:
self[1] += dy
def place_at_origin(self):
list.__init__(self, (0, 0))

View File

@ -3,6 +3,7 @@ from os.path import isfile, join
from pygame import Color, Rect
from pygame.image import load
from pygame.transform import flip
from pygame.locals import *
from Animation import Animation
@ -14,15 +15,13 @@ class Sprite(Animation):
Animation.__init__(self, parent, self.shift_frame, framerate)
self.frames = []
self.frame_index = 0
self.mirrored = False
self.rect = Rect((0, 0, 0, 0))
self.motion_overflow = Point()
self.deactivate()
self.display_surface = self.get_screen()
def deactivate(self):
self.active = False
def activate(self):
self.active = True
def set_framerate(self, framerate):
self.register(self.shift_frame, interval=framerate)
def load_from_path(self, path, transparency=False):
if isfile(path):
@ -30,13 +29,15 @@ class Sprite(Animation):
else:
paths = [join(path, name) for name in sorted(listdir(path))]
for path in paths:
self.add_frame(load(path), transparency)
img = load(path)
if transparency:
frame = img.convert_alpha()
else:
frame = img.convert()
self.add_frame(frame)
def add_frame(self, frame, transparency=False):
if transparency:
self.frames.append(frame.convert_alpha())
else:
self.frames.append(frame.convert())
def add_frame(self, frame):
self.frames.append(frame)
self.measure_rect()
if len(self.frames) > 1:
self.play()
@ -78,16 +79,24 @@ class Sprite(Animation):
overflow[1] -= int(overflow[1])
return excess
def reset_motion_overflow(self):
self.motion_overflow.place_at_origin()
def collide(self, other):
rect = other
if not isinstance(other, Rect):
rect = other.rect
return self.rect.colliderect(rect)
def mirror(self):
frames = self.frames
for ii, frame in enumerate(frames):
frames[ii] = flip(frame, True, False)
self.mirrored = not self.mirrored
def update(self):
if self.active:
Animation.update(self)
self.draw()
Animation.update(self)
self.draw()
def draw(self):
self.parent.blit(self.get_current_frame(), self.rect)
self.display_surface.blit(self.get_current_frame(), self.rect)