1 Animation-System
John McCardle edited this page 2025-10-25 20:57:41 +00:00

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 engine
  • src/Animation.h - Base Animation class
  • src/UIDrawable.h - Animatable properties defined here

API Reference:

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:

  1. Created via mcrfpy.animate()
  2. AnimationManager updates each frame
  3. Auto-destroyed on completion or target destruction
  4. 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:

  1. API consistency audit
  2. Bug fixes for known issues
  3. 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

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.cpp RAII overhaul (commit e9e9cd2)

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