hotfix: windows build, fresh docs

This commit is contained in:
John McCardle 2025-07-10 16:34:38 -04:00
commit 96857a41c6
6 changed files with 1785 additions and 412 deletions

View file

@ -1,165 +1,208 @@
#!/usr/bin/env python3
"""Animation System Demo - Shows all animation capabilities"""
"""
Animation Demo: Grid Center & Entity Movement
=============================================
Demonstrates:
- Animated grid centering following entity
- Smooth entity movement along paths
- Perspective shifts with zoom transitions
- Field of view updates
"""
import mcrfpy
import math
import sys
# Create main scene
mcrfpy.createScene("animation_demo")
ui = mcrfpy.sceneUI("animation_demo")
mcrfpy.setScene("animation_demo")
# Setup scene
mcrfpy.createScene("anim_demo")
# Title
title = mcrfpy.Caption((400, 30), "McRogueFace Animation System Demo", mcrfpy.default_font)
title.size = 24
title.fill_color = (255, 255, 255)
# Note: centered property doesn't exist for Caption
# Create grid
grid = mcrfpy.Grid(grid_x=30, grid_y=20)
grid.fill_color = mcrfpy.Color(20, 20, 30)
# Simple map
for y in range(20):
for x in range(30):
cell = grid.at(x, y)
# Create walls around edges and some obstacles
if x == 0 or x == 29 or y == 0 or y == 19:
cell.walkable = False
cell.transparent = False
cell.color = mcrfpy.Color(40, 30, 30)
elif (x == 10 and 5 <= y <= 15) or (y == 10 and 5 <= x <= 25):
cell.walkable = False
cell.transparent = False
cell.color = mcrfpy.Color(60, 40, 40)
else:
cell.walkable = True
cell.transparent = True
cell.color = mcrfpy.Color(80, 80, 100)
# Create entities
player = mcrfpy.Entity(5, 5, grid=grid)
player.sprite_index = 64 # @
enemy = mcrfpy.Entity(25, 15, grid=grid)
enemy.sprite_index = 69 # E
# Update visibility
player.update_visibility()
enemy.update_visibility()
# UI setup
ui = mcrfpy.sceneUI("anim_demo")
ui.append(grid)
grid.position = (100, 100)
grid.size = (600, 400)
title = mcrfpy.Caption("Animation Demo - Grid Center & Entity Movement", 200, 20)
title.fill_color = mcrfpy.Color(255, 255, 255)
ui.append(title)
# 1. Position Animation Demo
pos_frame = mcrfpy.Frame(50, 100, 80, 80)
pos_frame.fill_color = (255, 100, 100)
pos_frame.outline = 2
ui.append(pos_frame)
status = mcrfpy.Caption("Press 1: Move Player | 2: Move Enemy | 3: Perspective Shift | Q: Quit", 100, 50)
status.fill_color = mcrfpy.Color(200, 200, 200)
ui.append(status)
pos_label = mcrfpy.Caption((50, 80), "Position Animation", mcrfpy.default_font)
pos_label.fill_color = (200, 200, 200)
ui.append(pos_label)
# 2. Size Animation Demo
size_frame = mcrfpy.Frame(200, 100, 50, 50)
size_frame.fill_color = (100, 255, 100)
size_frame.outline = 2
ui.append(size_frame)
size_label = mcrfpy.Caption((200, 80), "Size Animation", mcrfpy.default_font)
size_label.fill_color = (200, 200, 200)
ui.append(size_label)
# 3. Color Animation Demo
color_frame = mcrfpy.Frame(350, 100, 80, 80)
color_frame.fill_color = (255, 0, 0)
ui.append(color_frame)
color_label = mcrfpy.Caption((350, 80), "Color Animation", mcrfpy.default_font)
color_label.fill_color = (200, 200, 200)
ui.append(color_label)
# 4. Easing Functions Demo
easing_y = 250
easing_frames = []
easings = ["linear", "easeIn", "easeOut", "easeInOut", "easeInElastic", "easeOutBounce"]
for i, easing in enumerate(easings):
x = 50 + i * 120
frame = mcrfpy.Frame(x, easing_y, 20, 20)
frame.fill_color = (100, 150, 255)
ui.append(frame)
easing_frames.append((frame, easing))
label = mcrfpy.Caption((x, easing_y - 20), easing, mcrfpy.default_font)
label.size = 12
label.fill_color = (200, 200, 200)
ui.append(label)
# 5. Complex Animation Demo
complex_frame = mcrfpy.Frame(300, 350, 100, 100)
complex_frame.fill_color = (128, 128, 255)
complex_frame.outline = 3
ui.append(complex_frame)
complex_label = mcrfpy.Caption((300, 330), "Complex Multi-Property", mcrfpy.default_font)
complex_label.fill_color = (200, 200, 200)
ui.append(complex_label)
# Start animations
def start_animations(runtime):
# 1. Position animation - back and forth
x_anim = mcrfpy.Animation("x", 500.0, 3.0, "easeInOut")
x_anim.start(pos_frame)
# 2. Size animation - pulsing
w_anim = mcrfpy.Animation("w", 150.0, 2.0, "easeInOut")
h_anim = mcrfpy.Animation("h", 150.0, 2.0, "easeInOut")
w_anim.start(size_frame)
h_anim.start(size_frame)
# 3. Color animation - rainbow cycle
color_anim = mcrfpy.Animation("fill_color", (0, 255, 255, 255), 2.0, "linear")
color_anim.start(color_frame)
# 4. Easing demos - all move up with different easings
for frame, easing in easing_frames:
y_anim = mcrfpy.Animation("y", 150.0, 2.0, easing)
y_anim.start(frame)
# 5. Complex animation - multiple properties
cx_anim = mcrfpy.Animation("x", 500.0, 4.0, "easeInOut")
cy_anim = mcrfpy.Animation("y", 400.0, 4.0, "easeOut")
cw_anim = mcrfpy.Animation("w", 150.0, 4.0, "easeInElastic")
ch_anim = mcrfpy.Animation("h", 150.0, 4.0, "easeInElastic")
outline_anim = mcrfpy.Animation("outline", 10.0, 4.0, "linear")
cx_anim.start(complex_frame)
cy_anim.start(complex_frame)
cw_anim.start(complex_frame)
ch_anim.start(complex_frame)
outline_anim.start(complex_frame)
# Individual color component animations
r_anim = mcrfpy.Animation("fill_color.r", 255.0, 4.0, "easeInOut")
g_anim = mcrfpy.Animation("fill_color.g", 100.0, 4.0, "easeInOut")
b_anim = mcrfpy.Animation("fill_color.b", 50.0, 4.0, "easeInOut")
r_anim.start(complex_frame)
g_anim.start(complex_frame)
b_anim.start(complex_frame)
print("All animations started!")
# Reverse some animations
def reverse_animations(runtime):
# Position back
x_anim = mcrfpy.Animation("x", 50.0, 3.0, "easeInOut")
x_anim.start(pos_frame)
# Size back
w_anim = mcrfpy.Animation("w", 50.0, 2.0, "easeInOut")
h_anim = mcrfpy.Animation("h", 50.0, 2.0, "easeInOut")
w_anim.start(size_frame)
h_anim.start(size_frame)
# Color cycle continues
color_anim = mcrfpy.Animation("fill_color", (255, 0, 255, 255), 2.0, "linear")
color_anim.start(color_frame)
# Easing frames back down
for frame, easing in easing_frames:
y_anim = mcrfpy.Animation("y", 250.0, 2.0, easing)
y_anim.start(frame)
# Continue color cycle
def cycle_colors(runtime):
color_anim = mcrfpy.Animation("fill_color", (255, 255, 0, 255), 2.0, "linear")
color_anim.start(color_frame)
# Info text
info = mcrfpy.Caption((400, 550), "Watch as different properties animate with various easing functions!", mcrfpy.default_font)
info.fill_color = (255, 255, 200)
# Note: centered property doesn't exist for Caption
info = mcrfpy.Caption("Perspective: Player", 500, 70)
info.fill_color = mcrfpy.Color(100, 255, 100)
ui.append(info)
# Schedule animations
mcrfpy.setTimer("start", start_animations, 500)
mcrfpy.setTimer("reverse", reverse_animations, 4000)
mcrfpy.setTimer("cycle", cycle_colors, 2500)
# Movement functions
def move_player_demo():
"""Demo player movement with camera follow"""
# Calculate path to a destination
path = player.path_to(20, 10)
if not path:
status.text = "No path available!"
return
status.text = f"Moving player along {len(path)} steps..."
# Animate along path
for i, (x, y) in enumerate(path[:5]): # First 5 steps
delay = i * 500 # 500ms between steps
# Schedule movement
def move_step(dt, px=x, py=y):
# Animate entity position
anim_x = mcrfpy.Animation("x", float(px), 0.4, "easeInOut")
anim_y = mcrfpy.Animation("y", float(py), 0.4, "easeInOut")
anim_x.start(player)
anim_y.start(player)
# Update visibility
player.update_visibility()
# Animate camera to follow
center_x = px * 16 # Assuming 16x16 tiles
center_y = py * 16
cam_anim = mcrfpy.Animation("center", (center_x, center_y), 0.4, "easeOut")
cam_anim.start(grid)
mcrfpy.setTimer(f"player_move_{i}", move_step, delay)
# Exit handler
def on_key(key):
if key == "Escape":
mcrfpy.exit()
def move_enemy_demo():
"""Demo enemy movement"""
# Calculate path
path = enemy.path_to(10, 5)
if not path:
status.text = "Enemy has no path!"
return
status.text = f"Moving enemy along {len(path)} steps..."
# Animate along path
for i, (x, y) in enumerate(path[:5]): # First 5 steps
delay = i * 500
def move_step(dt, ex=x, ey=y):
anim_x = mcrfpy.Animation("x", float(ex), 0.4, "easeInOut")
anim_y = mcrfpy.Animation("y", float(ey), 0.4, "easeInOut")
anim_x.start(enemy)
anim_y.start(enemy)
enemy.update_visibility()
# If following enemy, update camera
if grid.perspective == 1:
center_x = ex * 16
center_y = ey * 16
cam_anim = mcrfpy.Animation("center", (center_x, center_y), 0.4, "easeOut")
cam_anim.start(grid)
mcrfpy.setTimer(f"enemy_move_{i}", move_step, delay)
mcrfpy.keypressScene(on_key)
def perspective_shift_demo():
"""Demo dramatic perspective shift"""
status.text = "Perspective shift in progress..."
# Phase 1: Zoom out
zoom_out = mcrfpy.Animation("zoom", 0.5, 1.5, "easeInExpo")
zoom_out.start(grid)
# Phase 2: Switch perspective at peak
def switch_perspective(dt):
if grid.perspective == 0:
grid.perspective = 1
info.text = "Perspective: Enemy"
info.fill_color = mcrfpy.Color(255, 100, 100)
target = enemy
else:
grid.perspective = 0
info.text = "Perspective: Player"
info.fill_color = mcrfpy.Color(100, 255, 100)
target = player
# Update camera to new target
center_x = target.x * 16
center_y = target.y * 16
cam_anim = mcrfpy.Animation("center", (center_x, center_y), 0.5, "linear")
cam_anim.start(grid)
mcrfpy.setTimer("switch_persp", switch_perspective, 1600)
# Phase 3: Zoom back in
def zoom_in(dt):
zoom_in_anim = mcrfpy.Animation("zoom", 1.0, 1.5, "easeOutExpo")
zoom_in_anim.start(grid)
status.text = "Perspective shift complete!"
mcrfpy.setTimer("zoom_in", zoom_in, 2100)
print("Animation demo started! Press Escape to exit.")
# Input handler
def handle_input(key, state):
if state != "start":
return
if key == "q":
print("Exiting demo...")
sys.exit(0)
elif key == "1":
move_player_demo()
elif key == "2":
move_enemy_demo()
elif key == "3":
perspective_shift_demo()
# Set scene
mcrfpy.setScene("anim_demo")
mcrfpy.keypressScene(handle_input)
# Initial setup
grid.perspective = 0
grid.zoom = 1.0
# Center on player initially
center_x = player.x * 16
center_y = player.y * 16
initial_cam = mcrfpy.Animation("center", (center_x, center_y), 0.5, "easeOut")
initial_cam.start(grid)
print("Animation Demo Started!")
print("======================")
print("Press 1: Animate player movement with camera follow")
print("Press 2: Animate enemy movement")
print("Press 3: Dramatic perspective shift with zoom")
print("Press Q: Quit")
print()
print("Watch how the grid center smoothly follows entities")
print("and how perspective shifts create cinematic effects!")