Animation System
The Animation System provides property-based animations with 24+ easing functions for smooth transitions on all UI elements.
Quick Reference
Related Issues:
- #120 - Animation Property Locking (Tier 1 - Active)
- #119 - Animation Completion Callbacks (Closed - Implemented)
- #100 - Add Rotation Support
Key Files:
src/AnimationManager.h/src/AnimationManager.cpp- Animation execution enginesrc/Animation.h- Base Animation classsrc/UIDrawable.h- Animatable properties defined here
API Reference:
- See mcrfpy.animate() in generated API docs
Architecture Overview
Property-Based Animation
Animations modify any numeric property on UI objects over time:
import mcrfpy
sprite = mcrfpy.Sprite("player.png", 100, 100)
# Animate position with easing
mcrfpy.animate(sprite, "x", 300, 1000, "ease_in_out_cubic")
# Animate multiple properties
mcrfpy.animate(sprite, "opacity", 0.5, 500, "ease_out_quad")
mcrfpy.animate(sprite, "scale_x", 2.0, 800, "bounce_out")
Supported Properties:
- Position:
x,y,pos - Size:
w,h,size,scale_x,scale_y - Colors:
r,g,b,a,fill_color,outline_color - Grid-specific:
zoom,left_edge,top_edge - Caption-specific:
font_size
Implementation: See src/AnimationManager.cpp::createAnimation()
Easing Functions
24+ easing functions available:
Families:
- Linear
- Quad, Cubic, Quart, Quint
- Sine, Expo, Circ
- Elastic, Back, Bounce
Variants: ease_in_*, ease_out_*, ease_in_out_*
Implementation: All easing functions in src/Animation.cpp
Execution Model
Pure C++ Execution:
- Animations run in C++ update loop - no Python callbacks per frame
- High performance: thousands of concurrent animations possible
- Frame-independent: adjusts for variable frame times
Lifecycle:
- Created via
mcrfpy.animate() - AnimationManager updates each frame
- Auto-destroyed on completion or target destruction
- Weak pointer tracking prevents use-after-free
See: src/AnimationManager.cpp::update() for frame update logic
Current Issues & Limitations
Known Issues:
- API inconsistency: position vs frame animation differs (see FINAL_RECOMMENDATIONS.md)
- Property locking: Multiple animations can conflict on same property (#120)
- Rotation not yet supported (#100)
Recommendations from Strategic Review: Per FINAL_RECOMMENDATIONS.md, animation bugs contributed to tutorial burnout. Current system is feature-complete but needs:
- API consistency audit
- Bug fixes for known issues
- Comprehensive testing
Common Tasks
Basic Animation
# Linear movement
mcrfpy.animate(entity, "x", 500, 2000, "linear")
# Smooth bounce
mcrfpy.animate(frame, "y", 300, 1000, "ease_out_bounce")
Color Fades
# Fade to red
mcrfpy.animate(caption, "r", 255, 500, "ease_in_quad")
# Fade out
mcrfpy.animate(sprite, "a", 0, 1000, "ease_out_cubic")
Delta Animations
# Move relative to current position
current_x = entity.x
mcrfpy.animate(entity, "x", current_x + 100, 500, "ease_in_out_quad")
Completion Callbacks
def on_complete(runtime_ms):
print(f"Animation completed after {runtime_ms}ms")
# Trigger next action
mcrfpy.animate(sprite, "x", 400, 1000, "linear", callback=on_complete)
Implementation: #119 - Callbacks fire when animation completes
Related Systems
- UI-Component-Hierarchy - All UIDrawable objects are animatable
- Grid-System - Grid viewport animations (zoom, pan)
- Performance-and-Profiling - Animation time tracked separately
Design Decisions
Why Property-Based?
- Flexible: Any numeric property animatable
- Type-safe: Properties validated at C++ level
- Performant: No Python overhead during animation
Why Weak Pointers?
- Prevents crashes when animated objects destroyed
- Automatic cleanup on target death
- See:
src/AnimationManager.cppRAII overhaul (commite9e9cd2)
Tradeoffs:
- More complex than tween libraries
- Requires property exposure in Python bindings
- API surface larger than simple position tweening
Historical Notes:
- ANIMATION_FIX_IMPLEMENTATION.md documents segfault fix (race conditions resolved)
- Major refactor July 2025: Weak pointer tracking eliminated use-after-free bugs