Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add subrect property to Actor and 3 new class to do frame animation #278

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

yansnow78
Copy link

@yansnow78 yansnow78 commented Feb 1, 2022

add subrect property to Actor.

the goal of subrect is to be able to load a sprite from a sprite-sheet

this property can be a ZRect or pygame.Rect or an objet accepted by pygame.Rect constructor
this property can be pass as parameter to the constructor or changed directly

it uses 2 caches for better perfomance:
the images loader keep in cache all the subsurface accessed
the _surface_cache in Actor keep in cache all the subsurface accessed with their transformed surface (opacted, rotated, ...)

alien_walk2 = (69, 193, 68, 93)
alien = Actor('alienspritesheet', anchor=("center", "center"), subrect=alien_walk2 )
alien_walk2 = (69, 193, 68, 93)
alien = Actor('alienspritesheet', anchor=("center", "center"))
alien.subrect=alien_walk2 

add 3 new classes to do frame animation

add 3 new classes FramesList, FrameBasicAnimation, FrameBasicAnimation
feel free to change the names

class FramesList
a class use to store frames used by a specific animation
it has 3 functions to add frames, all those can be combined

_addFromSheet(self, sheet_name: str, cols: int, rows: int, cnt: int = 0, subrect: CanBeRect = None)
to load some frames from a spritesheet

balleRotationFrames = FramesList()
balleRotationFrames.addFromSheet('ball_anim', 8, 4)

addFromList(self, frame_images: Sequence[str])
to load some frames from a sequence of image names

walkingFrames = FramesList()
walkingFrames.addFromList(('alien_walk1', 'alien_walk2', 'alien_walk3'))

_add(self, image: str, subrect: CanBeRect = None):
to load one frame from an image or a spritesheet

walkingFrames = FramesList()
walkingFrames.add('alien')
walkingFrames.add('alien_walk_sprite', (0, 0, 66, 92))
walkingFrames.add('alien_walk_sprite', (66, 0, 66, 92))
walkingFrames.add('alien_walk_sprite', (128, 0, 66, 92))

class FrameBasicAnimation*
a class used to apply frame to an actor

class FrameBasicAnimation:
    def __init__(self, actor: Actor, frames: FramesList): ...
    def store_actor_image(self): ...
    def restore_actor_image(self): ...
    def sel_frame(self, idx): ...
    def next_frame(self) -> int: ...
    def prev_frame(self) -> int: ...

usage

walkingFrames = FramesList()
walkingFrames .addFromList(('alien_walk1', 'alien_walk2', 'alien_walk3'))
walkingAnim = FrameBasicAnimation(alien, walkingFrames)
...
walkingAnim.store_actor_image()
...
walkingAnim.next_frame()
...
walkingAnim.next_frame()
...
walkingAnim.restore_actor_image()

class FrameAnimation*
a class used to apply frame to an actor base on fps

class FrameAnimation(FrameBasicAnimation):
    def __init__(self, actor: Actor, frames: FramesList, fps: int, restore_image_at_stop: bool = True)
    def animate(self, dt=-1) -> (int, int):
    def play(self, stop_at_loop: int = -1, stop_at_idx: int = -1, duration: float = 0,
             on_finished: Callable = None) -> bool:  ...
    def play_once(self, on_finished: Callable = None): ...
    def play_several(self, nbr_of_loops: int, on_finished: Callable = None): ...
    def play_during(self, duration: int, on_finished: Callable = None): ...
    def play_infinite(self): ...
    def pause(self): ...
    def unpause(self):  ...
    def stop(self, call_on_finished: bool = False): ...

usage:
example 1 : # play a ball 3d rotation animation during 5 second

balle = Actor('ball', center=(200, 200))
...
balleRotationFrames = FramesList()
balleRotationFrames.addFromSheet('ball_anim', 8, 4)
...
balle.rotationAnim = FrameAnimation(balle, balleRotationFrames, fps=32)
....
# make the ball rotating during 5 second
balle.rotationAnim.play_during(5)

example 2 : # play 3 complete animation loop

balle.rotationAnim.play_several(3)

example 2 : # play infinite animation loop

balle.rotationAnim.play_infinite()

example 3 : # go to the correct next animation based on delta time

balle.rotationAnim.animate(dt)

@yansnow78 yansnow78 changed the title add subrect property to Actor add subrect property to Actor and 3 new class to do frame animation Feb 10, 2022
@yansnow78
Copy link
Author

yansnow78 commented Feb 10, 2022

my proposal is based on pgzhelper
originally there was just some extra function in pgzhelper.Actor but i think it's better to handle that outside Actor classes
this is how it looks like in pgzhelper

@property
def images(self):
@images.setter
def images(self, images):
def load_images(self, sheet_name:str, cols:int, rows:int, cnt:int=0, subrect:pygame.Rect=None):
def sel_image(self, newimage:str):
def sel_image_idx(self, newimage_idx:int):
def next_image(self)-> int:
def animate(self):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant