Source code for usf.animations
################################################################################
# copyright 2008 Gabriel Pettier <gabriel.pettier@gmail.com> #
# #
# This file is part of UltimateSmashFriends #
# #
# UltimateSmashFriends is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# UltimateSmashFriends is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with UltimateSmashFriends. If not, see <http://www.gnu.org/licenses/>.#
################################################################################
'''
This module provide animations for entities, animations are composed of frames,
which are a bit more than an image...
'''
import pygame
import logging
from usf import loaders
[docs]class Frame (object):
"""
A Frame is an image of n animations, plus some information on the player
when on this instant of the animation:
* The hardshape is an inner rectangle than delimitate the area that can
collide the world.
* The agressiv points are the damaginds points of a player/entity when it
hit some other player.
* The Vector indicate the speed and direction taken by the entity when in
this state, this combine with the current direction/speed of the entity.
"""
def __init__(self, image, gametime, hardshape, trails=None):
"""
Load a frame from an image, the current gametime, the deplacement/s of
the player in this frame, it's hardshape.
"""
self.image = image
self.trails = trails
self.time = int(gametime)
if type(hardshape) is str:
self.hardshape = pygame.Rect([int(i) for i in hardshape.split(' ')])
elif type(hardshape) is pygame.Rect:
self.hardshape = hardshape
else:
logging.error('incorrect type for hardshape: ', hardshape)
self.hardshape_reverse = (
loaders.image(self.image)[1][2]
- self.hardshape[0] - self.hardshape[2],
self.hardshape[1],
self.hardshape[2],
self.hardshape[3])
self.agressivpoints = []
self.agressivpoints_reverse = []
[docs] def add_agressiv_point(self, (c_x, c_y), (vect_x, vect_y)):
"""
add an agressive points of coords, and vector specified, to the list of
agressivpoints of the frame
"""
self.agressivpoints.append(((c_x, c_y), (vect_x, vect_y)))
self.agressivpoints_reverse.append(
((self.hardshape[2] - c_x, c_y), (vect_x, vect_y)))
[docs]class PreciseTimedAnimation(object):
"""
This object store the frames of an animation and update the image of the
entity skin.
"""
def __init__(self, frames, attribs, server=False):
self.frames = frames
self.image = frames[0].image
self.rect = loaders.image(self.image, nodisplay=server)[1]
self._start_time = 0
self.playing = 0
self.repeat = int('repeat' in attribs and attribs['repeat'])
self.duration = int('duration' in attribs and attribs['duration'])
self.hardshape = (
('hardshape' in attribs) and
pygame.Rect(
[int(i) for i in attribs['hardshape'].split(' ')]) or 0)
self.update(0, server=server)
self.agressivpoints = []
@property
[docs] def start_time(self):
return self._start_time
[docs] def start(self, gametime):
"""
set the animation start as now, and the animation as started.
"""
self._start_time = gametime
self.playing = 1
[docs] def frame(self, anim_time):
"""
return the current frame depending on the time since the beggining of
the animation.
"""
try:
return filter(lambda x: x.time/1000.0 <= anim_time, self.frames)[-1]
except IndexError:
return self.frames[0]
[docs] def update(self, gametime, reverse=False, server=False):
"""
update the state of the animation.
"""
if self.playing:
if (self.duration != 0
and gametime - self._start_time > self.duration/1000.0):
self.playing = 0
if self.repeat is not 0:
#FIXME: repeat will not reset properly
self.repeat = max(-1, self.repeat - 1)
self.start(gametime)
else:
frame = self.frame(gametime - self._start_time)
self.image = frame.image
self.trails = frame.trails
if reverse:
self.agressivpoints = frame.agressivpoints_reverse
self.hardshape = frame.hardshape_reverse
else:
self.agressivpoints = frame.agressivpoints
self.hardshape = frame.hardshape
self.rect = loaders.image(self.image, nodisplay=server)[1]