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

Fix #336: Animation system for actors #337

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

Conversation

Mambouna
Copy link

@Mambouna Mambouna commented Mar 19, 2025

Adds a new animation system for actors to utilize (fixes #336, replaces #219, #278).

Allows for

  • automatically running sprite animations on actors (with different lengths and spacial offsets for each frame)
  • loading animations via a new resource folder animations in which each animation with its frames is located in a folder
  • multiple modes of animation: simple running of single animations, running an animation queue, having a base animation that is run whenever no other animations are active

The system exposes an easy to use API with different levels of use from very simple with sensible defaults to completely custom control over animation frames, durations, offsets and callbacks. Comprehensive warning and error messages should make working through problems easy.

Changes are non-breaking to old projects and no changes have been made to existing APIs that prevent the same usage being continued. Specifically important for this: Manipulating the static image of an actor always supersedes any animations.

The PR is currently a WIP and should be reviewed. At this point, it should not be pulled without more work.

Preparation for actor animation system:
- New AnimationLoader subclass of ResourceLoader to load and cache
  animation frames.

Implementation:
- New file actor_animation.py with two new classes for the animation
  system.
- ActorAnimationSystem to manage animations.
- ActorAnimation for individual animations.
- Changes to actor.py for initial system capability to load and remove
  animations from the pool and play a single animation.
  NOTE: This simple implementation still has many visual issues and
  state transitions in actor to accomodate having both a static image
  and animation images are not polished.
Added last warning for loading of animations.

Implemented basic capability to switch between animations and return to
base animation.

Implemented basic setup of animation queue.
Base animation works. Transitions to and from base animation work.

Frame offsets work for centered anchor.
- Offsets have to be specified by imagining both pictures overlayed on
  their center. The offset currently is the vector to move the frame to
  the correct location from this centered state.
- This is unintuitive. Before further work to make other anchors
  possible, a single approach of how to define an offset should be
  decided on.

Started work on pausing and unpausing animations, currently not
functional.

Added .time() function to clock to get elapsed game time.
@Mambouna
Copy link
Author

Before continuing work on offsets, we should decide how an offset is to be defined.

Since the anchor of an actor can move in the game, the offset should ideally be defined only by the animation frame sizes.
One possible example: "An offset is the amount of pixels an animation frame has to be shifted when placing the top left corner of it over the top left corner of the base image to align their content as desired." Another option would be the same but when placing the center of both images over each other.

As I'm not a professional in the games field, I don't know if there's already an agreed upon convention for this. If there is, we should use it. Otherwise, we just need to settle on something that will be easy to communicate and hopefully intuitive (I've been having trouble with the intuitive part...).

@Mambouna
Copy link
Author

Whoops, also just noticed that including clock.time() happens to fix #97.

Pausing is implemented and works with both single animations and base
animations. Pausing the queue works in general but has edgecases that
cause problems.

Animation queue works but requires more work. Setting up a queue
and playing it works, complex interactions between single animations,
the queue and the base animation don't all work correctly yet.

Switched from representing not yet started animations and the queue
with -1 for the position value to representing it with None. This is
to prevent strange behaviour with unexpected checking of position
when there is no valid position. With None, the program simply errors,
exposing a location in source code to be improved.
@Mambouna
Copy link
Author

Mambouna commented Mar 29, 2025

Any comment on how an offset should be defined would be welcome.

Another thing I've come across is a possible rework of how the queue is accessed. Currently, all functionality is accessed via functions on actor.anim. This is intuitive, since everything to do with animations lives under actor.anim.. Having the same basic functionality for single animations and the queue all having slightly different names could be confusing though (e.g. currently there are actor.anim.play() and actor.anim.play_queue(), actor.anim.pause() and actor.anim.pause_queue()).

A different possibility would be to have a separate class for the queue of which the animation system holds an instance. Accessing the queue would then work thus: actor.anim.queue.play(), actor.anim.queue.pause(), actor.anim.queue.add() and so on...

The second option is clearer but requires more understanding and might be more complex to use for beginner users.

What do you think would be the most accessible and intuitive design?

Split dequeue() up into two functions for readability and maintainability,
improved comments and fixed functionality.
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.

No easy to use options for animations
1 participant