Roguelike Tutorial Planning + Prep
This commit is contained in:
		
							parent
							
								
									4e94d1d79e
								
							
						
					
					
						commit
						192d1ae1dd
					
				
							
								
								
									
										156
									
								
								ROADMAP.md
								
								
								
								
							
							
						
						
									
										156
									
								
								ROADMAP.md
								
								
								
								
							| 
						 | 
					@ -1,11 +1,121 @@
 | 
				
			||||||
# McRogueFace - Development Roadmap
 | 
					# McRogueFace - Development Roadmap
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 🚨 URGENT PRIORITIES - July 9, 2025 🚨
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### IMMEDIATE ACTION REQUIRED (Next 48 Hours)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**CRITICAL DEADLINE**: RoguelikeDev Tutorial Event starts July 15 - Need to advertise by July 11!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### 1. Tutorial Emergency Plan (2 DAYS)
 | 
				
			||||||
 | 
					- [ ] **Day 1 (July 9)**: Parts 1-2 (Setup, Moving @, Drawing Map, Entities)
 | 
				
			||||||
 | 
					- [ ] **Day 2 (July 10)**: Parts 3-4 (FOV, Combat/AI)
 | 
				
			||||||
 | 
					- [ ] **July 11**: Announce on r/roguelikedev with 4 completed parts
 | 
				
			||||||
 | 
					- [ ] **July 12-14**: Complete remaining 10 parts before event starts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### 1b. Sizzle Reel Demo (URGENT)
 | 
				
			||||||
 | 
					- [ ] **Expand animation_sizzle_reel_working.py** with Grid/Entity demos:
 | 
				
			||||||
 | 
					  - Grid scrolling and zooming animations
 | 
				
			||||||
 | 
					  - Entity movement patterns (patrol, chase, flee)
 | 
				
			||||||
 | 
					  - Particle effects using entity spawning
 | 
				
			||||||
 | 
					  - Tile animation demonstrations
 | 
				
			||||||
 | 
					  - Color cycling and transparency effects
 | 
				
			||||||
 | 
					  - Mass entity choreography (100+ entities)
 | 
				
			||||||
 | 
					  - Performance stress test with 1000+ entities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### 2. TCOD Integration Sprint
 | 
				
			||||||
 | 
					- [ ] **UIGrid TCOD Integration** (8 hours)
 | 
				
			||||||
 | 
					  - Add TCODMap* to UIGrid constructor
 | 
				
			||||||
 | 
					  - Implement mcrfpy.libtcod.compute_fov()
 | 
				
			||||||
 | 
					  - Add batch operations for NumPy-style access
 | 
				
			||||||
 | 
					  - Create CellView for ergonomic .at((x,y)) access
 | 
				
			||||||
 | 
					- [ ] **UIEntity Pathfinding** (4 hours)
 | 
				
			||||||
 | 
					  - Add path_to(target) method using A*
 | 
				
			||||||
 | 
					  - Implement Dijkstra maps for multiple targets
 | 
				
			||||||
 | 
					  - Cache paths in UIEntity for performance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### 3. Performance Critical Path
 | 
				
			||||||
 | 
					- [ ] **Implement SpatialHash** for 10,000+ entities (2 hours)
 | 
				
			||||||
 | 
					- [ ] **Add dirty flag system** to UIGrid (1 hour)
 | 
				
			||||||
 | 
					- [ ] **Batch update context managers** (2 hours)
 | 
				
			||||||
 | 
					- [ ] **Memory pool for entities** (2 hours)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### 4. Bug Fixing Pipeline
 | 
				
			||||||
 | 
					- [ ] Set up GitHub Issues automation
 | 
				
			||||||
 | 
					- [ ] Create test for each bug before fixing
 | 
				
			||||||
 | 
					- [ ] Track: Memory leaks, Segfaults, Python/C++ boundary errors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 🎯 STRATEGIC ARCHITECTURE VISION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Three-Layer Grid Architecture (From Compass Research)
 | 
				
			||||||
 | 
					Following successful roguelike patterns (Caves of Qud, Cogmind, DCSS):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. **Visual Layer** (UIGridPoint) - Sprites, colors, animations
 | 
				
			||||||
 | 
					2. **World State Layer** (TCODMap) - Walkability, transparency, physics
 | 
				
			||||||
 | 
					3. **Entity Perspective Layer** (UIGridPointState) - Per-entity FOV, knowledge
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Performance Architecture (Critical for 1000x1000 maps)
 | 
				
			||||||
 | 
					- **Spatial Hashing** for entity queries (not quadtrees!)
 | 
				
			||||||
 | 
					- **Batch Operations** with context managers (10-100x speedup)
 | 
				
			||||||
 | 
					- **Memory Pooling** for entities and components
 | 
				
			||||||
 | 
					- **Dirty Flag System** to avoid unnecessary updates
 | 
				
			||||||
 | 
					- **Zero-Copy NumPy Integration** via buffer protocol
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Key Insight from Research
 | 
				
			||||||
 | 
					"Minimizing Python/C++ boundary crossings matters more than individual function complexity"
 | 
				
			||||||
 | 
					- Batch everything possible
 | 
				
			||||||
 | 
					- Use context managers for logical operations
 | 
				
			||||||
 | 
					- Expose arrays, not individual cells
 | 
				
			||||||
 | 
					- Profile and optimize hot paths only
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Project Status: 🎉 ALPHA 0.1 RELEASE! 🎉
 | 
					## Project Status: 🎉 ALPHA 0.1 RELEASE! 🎉
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Current State**: Alpha release achieved! All critical blockers resolved!  
 | 
					**Current State**: Documentation system complete, TCOD integration urgent  
 | 
				
			||||||
**Latest Update**: Moved RenderTexture (#6) to Beta - Alpha is READY! (2025-07-05)  
 | 
					**Latest Update**: Completed Phase 7 documentation infrastructure (2025-07-08)  
 | 
				
			||||||
**Branch**: interpreter_mode (ready for alpha release merge)  
 | 
					**Branch**: alpha_streamline_2  
 | 
				
			||||||
**Open Issues**: ~46 remaining (non-blocking quality-of-life improvements)
 | 
					**Open Issues**: ~46 remaining + URGENT TCOD/Tutorial work
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 📋 TCOD Integration Implementation Details
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Phase 1: Core UIGrid Integration (Day 1 Morning)
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					// UIGrid.h additions
 | 
				
			||||||
 | 
					class UIGrid : public UIDrawable {
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    TCODMap* world_state;  // Add TCOD map
 | 
				
			||||||
 | 
					    std::unordered_map<int, UIGridPointState*> entity_perspectives;
 | 
				
			||||||
 | 
					    bool batch_mode = false;
 | 
				
			||||||
 | 
					    std::vector<CellUpdate> pending_updates;
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Phase 2: Python Bindings (Day 1 Afternoon)
 | 
				
			||||||
 | 
					```python
 | 
				
			||||||
 | 
					# New API surface
 | 
				
			||||||
 | 
					grid = mcrfpy.Grid(100, 100)
 | 
				
			||||||
 | 
					grid.compute_fov(player.x, player.y, radius=10)  # Returns visible cells
 | 
				
			||||||
 | 
					grid.at((x, y)).walkable = False  # Ergonomic access
 | 
				
			||||||
 | 
					with grid.batch_update():  # Context manager for performance
 | 
				
			||||||
 | 
					    # All updates batched
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Phase 3: Entity Integration (Day 2 Morning)
 | 
				
			||||||
 | 
					```python
 | 
				
			||||||
 | 
					# UIEntity additions
 | 
				
			||||||
 | 
					entity.path_to(target_x, target_y)  # A* pathfinding
 | 
				
			||||||
 | 
					entity.flee_from(threat)  # Dijkstra map
 | 
				
			||||||
 | 
					entity.can_see(other_entity)  # FOV check
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Critical Success Factors:
 | 
				
			||||||
 | 
					1. **Batch everything** - Never update single cells in loops
 | 
				
			||||||
 | 
					2. **Lazy evaluation** - Only compute FOV for entities that need it
 | 
				
			||||||
 | 
					3. **Sparse storage** - Don't store full grids per entity
 | 
				
			||||||
 | 
					4. **Profile early** - Find the 20% of code taking 80% of time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -613,4 +723,40 @@ This architecture would make McRogueFace a first-class Python citizen, following
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*Last Updated: 2025-07-08*  
 | 
					## 🚀 IMMEDIATE NEXT STEPS (Priority Order)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Today (July 9) - EXECUTE NOW:
 | 
				
			||||||
 | 
					1. **Start Tutorial Part 1** - Basic setup and @ movement (2 hours)
 | 
				
			||||||
 | 
					2. **Implement UIGrid.at((x,y))** - CellView pattern (1 hour)
 | 
				
			||||||
 | 
					3. **Create Grid demo** for sizzle reel (1 hour)
 | 
				
			||||||
 | 
					4. **Fix any blocking bugs** discovered during tutorial writing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Tomorrow (July 10) - CRITICAL PATH:
 | 
				
			||||||
 | 
					1. **Tutorial Parts 2-4** - Map drawing, entities, FOV, combat
 | 
				
			||||||
 | 
					2. **Implement compute_fov()** in UIGrid
 | 
				
			||||||
 | 
					3. **Add batch_update context manager**
 | 
				
			||||||
 | 
					4. **Expand sizzle reel** with entity choreography
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### July 11 - ANNOUNCEMENT DAY:
 | 
				
			||||||
 | 
					1. **Polish 4 tutorial parts**
 | 
				
			||||||
 | 
					2. **Create announcement post** for r/roguelikedev
 | 
				
			||||||
 | 
					3. **Record sizzle reel video**
 | 
				
			||||||
 | 
					4. **Submit announcement** by end of day
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Architecture Decision Log:
 | 
				
			||||||
 | 
					- **DECIDED**: Use three-layer architecture (visual/world/perspective)
 | 
				
			||||||
 | 
					- **DECIDED**: Spatial hashing over quadtrees for entities
 | 
				
			||||||
 | 
					- **DECIDED**: Batch operations are mandatory, not optional
 | 
				
			||||||
 | 
					- **DECIDED**: TCOD integration as mcrfpy.libtcod submodule
 | 
				
			||||||
 | 
					- **DECIDED**: Tutorial must showcase McRogueFace strengths, not mimic TCOD
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Risk Mitigation:
 | 
				
			||||||
 | 
					- **If TCOD integration delays**: Use pure Python FOV for tutorial
 | 
				
			||||||
 | 
					- **If performance issues**: Focus on <100x100 maps for demos
 | 
				
			||||||
 | 
					- **If tutorial incomplete**: Ship with 4 solid parts + roadmap
 | 
				
			||||||
 | 
					- **If bugs block progress**: Document as "known issues" and continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*Last Updated: 2025-07-09 (URGENT SPRINT MODE)*
 | 
				
			||||||
 | 
					*Next Review: July 11 after announcement*  
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,146 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					McRogueFace Animation Demo - Safe Version
 | 
				
			||||||
 | 
					=========================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A safer, simpler version that demonstrates animations without crashes.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import mcrfpy
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Configuration
 | 
				
			||||||
 | 
					DEMO_DURATION = 4.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Track state
 | 
				
			||||||
 | 
					current_demo = 0
 | 
				
			||||||
 | 
					subtitle = None
 | 
				
			||||||
 | 
					demo_items = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def create_scene():
 | 
				
			||||||
 | 
					    """Create the demo scene"""
 | 
				
			||||||
 | 
					    mcrfpy.createScene("demo")
 | 
				
			||||||
 | 
					    mcrfpy.setScene("demo")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("demo")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Title
 | 
				
			||||||
 | 
					    title = mcrfpy.Caption("Animation Demo", 500, 20)
 | 
				
			||||||
 | 
					    title.fill_color = mcrfpy.Color(255, 255, 0)
 | 
				
			||||||
 | 
					    title.outline = 2
 | 
				
			||||||
 | 
					    ui.append(title)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Subtitle
 | 
				
			||||||
 | 
					    global subtitle
 | 
				
			||||||
 | 
					    subtitle = mcrfpy.Caption("Starting...", 450, 60)
 | 
				
			||||||
 | 
					    subtitle.fill_color = mcrfpy.Color(200, 200, 200)
 | 
				
			||||||
 | 
					    ui.append(subtitle)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def clear_demo_items():
 | 
				
			||||||
 | 
					    """Clear demo items from scene"""
 | 
				
			||||||
 | 
					    global demo_items
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("demo")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Remove demo items by tracking what we added
 | 
				
			||||||
 | 
					    for item in demo_items:
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            # Find index of item
 | 
				
			||||||
 | 
					            for i in range(len(ui)):
 | 
				
			||||||
 | 
					                if i >= 2:  # Skip title and subtitle
 | 
				
			||||||
 | 
					                    ui.remove(i)
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    demo_items = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo1_basic():
 | 
				
			||||||
 | 
					    """Basic frame animations"""
 | 
				
			||||||
 | 
					    global demo_items
 | 
				
			||||||
 | 
					    clear_demo_items()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("demo")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 1: Basic Frame Animations"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create frame
 | 
				
			||||||
 | 
					    f = mcrfpy.Frame(100, 150, 200, 100)
 | 
				
			||||||
 | 
					    f.fill_color = mcrfpy.Color(50, 50, 150)
 | 
				
			||||||
 | 
					    f.outline = 3
 | 
				
			||||||
 | 
					    ui.append(f)
 | 
				
			||||||
 | 
					    demo_items.append(f)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Simple animations
 | 
				
			||||||
 | 
					    mcrfpy.Animation("x", 600.0, 2.0, "easeInOut").start(f)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("w", 300.0, 2.0, "easeInOut").start(f)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("fill_color", (255, 100, 50, 200), 3.0, "linear").start(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo2_caption():
 | 
				
			||||||
 | 
					    """Caption animations"""
 | 
				
			||||||
 | 
					    global demo_items
 | 
				
			||||||
 | 
					    clear_demo_items()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("demo")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 2: Caption Animations"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Moving caption
 | 
				
			||||||
 | 
					    c1 = mcrfpy.Caption("Moving Text!", 100, 200)
 | 
				
			||||||
 | 
					    c1.fill_color = mcrfpy.Color(255, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(c1)
 | 
				
			||||||
 | 
					    demo_items.append(c1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    mcrfpy.Animation("x", 700.0, 3.0, "easeOutBounce").start(c1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Typewriter
 | 
				
			||||||
 | 
					    c2 = mcrfpy.Caption("", 100, 300)
 | 
				
			||||||
 | 
					    c2.fill_color = mcrfpy.Color(0, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(c2)
 | 
				
			||||||
 | 
					    demo_items.append(c2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    mcrfpy.Animation("text", "Typewriter effect...", 3.0, "linear").start(c2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo3_multiple():
 | 
				
			||||||
 | 
					    """Multiple animations"""
 | 
				
			||||||
 | 
					    global demo_items
 | 
				
			||||||
 | 
					    clear_demo_items()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("demo")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 3: Multiple Animations"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create several frames
 | 
				
			||||||
 | 
					    for i in range(5):
 | 
				
			||||||
 | 
					        f = mcrfpy.Frame(100 + i * 120, 200, 80, 80)
 | 
				
			||||||
 | 
					        f.fill_color = mcrfpy.Color(50 + i * 40, 100, 200 - i * 30)
 | 
				
			||||||
 | 
					        ui.append(f)
 | 
				
			||||||
 | 
					        demo_items.append(f)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Animate each differently
 | 
				
			||||||
 | 
					        target_y = 350 + i * 20
 | 
				
			||||||
 | 
					        mcrfpy.Animation("y", float(target_y), 2.0, "easeInOut").start(f)
 | 
				
			||||||
 | 
					        mcrfpy.Animation("opacity", 0.5, 3.0, "easeInOut").start(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def run_next_demo(runtime):
 | 
				
			||||||
 | 
					    """Run the next demo"""
 | 
				
			||||||
 | 
					    global current_demo
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    demos = [demo1_basic, demo2_caption, demo3_multiple]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if current_demo < len(demos):
 | 
				
			||||||
 | 
					        demos[current_demo]()
 | 
				
			||||||
 | 
					        current_demo += 1
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if current_demo < len(demos):
 | 
				
			||||||
 | 
					            mcrfpy.setTimer("next", run_next_demo, int(DEMO_DURATION * 1000))
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            subtitle.text = "Demo Complete!"
 | 
				
			||||||
 | 
					            # Exit after a delay
 | 
				
			||||||
 | 
					            def exit_program(rt):
 | 
				
			||||||
 | 
					                print("Demo finished successfully!")
 | 
				
			||||||
 | 
					                sys.exit(0)
 | 
				
			||||||
 | 
					            mcrfpy.setTimer("exit", exit_program, 2000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Initialize
 | 
				
			||||||
 | 
					print("Starting Safe Animation Demo...")
 | 
				
			||||||
 | 
					create_scene()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Start demos
 | 
				
			||||||
 | 
					mcrfpy.setTimer("start", run_next_demo, 500)
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,615 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					McRogueFace Animation Sizzle Reel
 | 
				
			||||||
 | 
					=================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This script demonstrates EVERY animation type on EVERY UI object type.
 | 
				
			||||||
 | 
					It showcases all 30 easing functions, all animatable properties, and 
 | 
				
			||||||
 | 
					special animation modes (delta, sprite sequences, text effects).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The script creates a comprehensive visual demonstration of the animation
 | 
				
			||||||
 | 
					system's capabilities, cycling through different objects and effects.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author: Claude
 | 
				
			||||||
 | 
					Purpose: Complete animation system demonstration
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import mcrfpy
 | 
				
			||||||
 | 
					from mcrfpy import Color, Frame, Caption, Sprite, Grid, Entity, Texture, Animation
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import math
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Configuration
 | 
				
			||||||
 | 
					SCENE_WIDTH = 1280
 | 
				
			||||||
 | 
					SCENE_HEIGHT = 720
 | 
				
			||||||
 | 
					DEMO_DURATION = 5.0  # Duration for each demo section
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# All available easing functions
 | 
				
			||||||
 | 
					EASING_FUNCTIONS = [
 | 
				
			||||||
 | 
					    "linear", "easeIn", "easeOut", "easeInOut",
 | 
				
			||||||
 | 
					    "easeInQuad", "easeOutQuad", "easeInOutQuad",
 | 
				
			||||||
 | 
					    "easeInCubic", "easeOutCubic", "easeInOutCubic",
 | 
				
			||||||
 | 
					    "easeInQuart", "easeOutQuart", "easeInOutQuart",
 | 
				
			||||||
 | 
					    "easeInSine", "easeOutSine", "easeInOutSine",
 | 
				
			||||||
 | 
					    "easeInExpo", "easeOutExpo", "easeInOutExpo",
 | 
				
			||||||
 | 
					    "easeInCirc", "easeOutCirc", "easeInOutCirc",
 | 
				
			||||||
 | 
					    "easeInElastic", "easeOutElastic", "easeInOutElastic",
 | 
				
			||||||
 | 
					    "easeInBack", "easeOutBack", "easeInOutBack",
 | 
				
			||||||
 | 
					    "easeInBounce", "easeOutBounce", "easeInOutBounce"
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Track current demo state
 | 
				
			||||||
 | 
					current_demo = 0
 | 
				
			||||||
 | 
					demo_start_time = 0
 | 
				
			||||||
 | 
					demos = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Handle ESC key to exit
 | 
				
			||||||
 | 
					def handle_keypress(scene_name, keycode):
 | 
				
			||||||
 | 
					    if keycode == 256:  # ESC key
 | 
				
			||||||
 | 
					        print("Exiting animation sizzle reel...")
 | 
				
			||||||
 | 
					        sys.exit(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def create_demo_scene():
 | 
				
			||||||
 | 
					    """Create the main demo scene with title"""
 | 
				
			||||||
 | 
					    mcrfpy.createScene("sizzle_reel")
 | 
				
			||||||
 | 
					    mcrfpy.setScene("sizzle_reel")
 | 
				
			||||||
 | 
					    mcrfpy.keypressScene(handle_keypress)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Title caption
 | 
				
			||||||
 | 
					    title = Caption("McRogueFace Animation Sizzle Reel", 
 | 
				
			||||||
 | 
					                   SCENE_WIDTH/2 - 200, 20)
 | 
				
			||||||
 | 
					    title.fill_color = Color(255, 255, 0)
 | 
				
			||||||
 | 
					    title.outline = 2
 | 
				
			||||||
 | 
					    title.outline_color = Color(0, 0, 0)
 | 
				
			||||||
 | 
					    ui.append(title)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Subtitle showing current demo
 | 
				
			||||||
 | 
					    global subtitle
 | 
				
			||||||
 | 
					    subtitle = Caption("Initializing...", 
 | 
				
			||||||
 | 
					                      SCENE_WIDTH/2 - 150, 60)
 | 
				
			||||||
 | 
					    subtitle.fill_color = Color(200, 200, 200)
 | 
				
			||||||
 | 
					    ui.append(subtitle)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return ui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_frame_basic_animations(ui):
 | 
				
			||||||
 | 
					    """Demo 1: Basic frame animations - position, size, colors"""
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 1: Frame Basic Animations (Position, Size, Colors)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create test frame
 | 
				
			||||||
 | 
					    frame = Frame(100, 150, 200, 100)
 | 
				
			||||||
 | 
					    frame.fill_color = Color(50, 50, 150)
 | 
				
			||||||
 | 
					    frame.outline = 3
 | 
				
			||||||
 | 
					    frame.outline_color = Color(255, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Position animations with different easings
 | 
				
			||||||
 | 
					    x_anim = Animation("x", 800.0, 2.0, "easeInOutBack")
 | 
				
			||||||
 | 
					    y_anim = Animation("y", 400.0, 2.0, "easeInOutElastic")
 | 
				
			||||||
 | 
					    x_anim.start(frame)
 | 
				
			||||||
 | 
					    y_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Size animations
 | 
				
			||||||
 | 
					    w_anim = Animation("w", 400.0, 3.0, "easeInOutCubic")
 | 
				
			||||||
 | 
					    h_anim = Animation("h", 200.0, 3.0, "easeInOutCubic")
 | 
				
			||||||
 | 
					    w_anim.start(frame)
 | 
				
			||||||
 | 
					    h_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Color animations - use tuples instead of Color objects
 | 
				
			||||||
 | 
					    fill_anim = Animation("fill_color", (255, 100, 50, 200), 4.0, "easeInOutSine")
 | 
				
			||||||
 | 
					    outline_anim = Animation("outline_color", (0, 255, 255, 255), 4.0, "easeOutBounce")
 | 
				
			||||||
 | 
					    fill_anim.start(frame)
 | 
				
			||||||
 | 
					    outline_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Outline thickness animation
 | 
				
			||||||
 | 
					    thickness_anim = Animation("outline", 10.0, 4.5, "easeInOutQuad")
 | 
				
			||||||
 | 
					    thickness_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return frame
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_frame_opacity_zindex(ui):
 | 
				
			||||||
 | 
					    """Demo 2: Frame opacity and z-index animations"""
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 2: Frame Opacity & Z-Index Animations"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    frames = []
 | 
				
			||||||
 | 
					    colors = [
 | 
				
			||||||
 | 
					        Color(255, 0, 0, 200),
 | 
				
			||||||
 | 
					        Color(0, 255, 0, 200),
 | 
				
			||||||
 | 
					        Color(0, 0, 255, 200),
 | 
				
			||||||
 | 
					        Color(255, 255, 0, 200)
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create overlapping frames
 | 
				
			||||||
 | 
					    for i in range(4):
 | 
				
			||||||
 | 
					        frame = Frame(200 + i*80, 200 + i*40, 200, 150)
 | 
				
			||||||
 | 
					        frame.fill_color = colors[i]
 | 
				
			||||||
 | 
					        frame.outline = 2
 | 
				
			||||||
 | 
					        frame.z_index = i
 | 
				
			||||||
 | 
					        ui.append(frame)
 | 
				
			||||||
 | 
					        frames.append(frame)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Animate opacity in waves
 | 
				
			||||||
 | 
					        opacity_anim = Animation("opacity", 0.3, 2.0, "easeInOutSine")
 | 
				
			||||||
 | 
					        opacity_anim.start(frame)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Reverse opacity animation
 | 
				
			||||||
 | 
					        opacity_back = Animation("opacity", 1.0, 2.0, "easeInOutSine", delta=False)
 | 
				
			||||||
 | 
					        mcrfpy.setTimer(f"opacity_back_{i}", lambda t, f=frame, a=opacity_back: a.start(f), 2000)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Z-index shuffle animation
 | 
				
			||||||
 | 
					        z_anim = Animation("z_index", (i + 2) % 4, 3.0, "linear")
 | 
				
			||||||
 | 
					        z_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return frames
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_caption_animations(ui):
 | 
				
			||||||
 | 
					    """Demo 3: Caption text animations and effects"""
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 3: Caption Animations (Text, Color, Position)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Basic caption with position animation
 | 
				
			||||||
 | 
					    caption1 = Caption("Moving Text!", 100, 200)
 | 
				
			||||||
 | 
					    caption1.fill_color = Color(255, 255, 255)
 | 
				
			||||||
 | 
					    caption1.outline = 1
 | 
				
			||||||
 | 
					    ui.append(caption1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Animate across screen with bounce
 | 
				
			||||||
 | 
					    x_anim = Animation("x", 900.0, 3.0, "easeOutBounce")
 | 
				
			||||||
 | 
					    x_anim.start(caption1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Color cycling caption
 | 
				
			||||||
 | 
					    caption2 = Caption("Rainbow Colors", 400, 300)
 | 
				
			||||||
 | 
					    caption2.outline = 2
 | 
				
			||||||
 | 
					    ui.append(caption2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Cycle through colors - use tuples
 | 
				
			||||||
 | 
					    color_anim1 = Animation("fill_color", (255, 0, 0, 255), 1.0, "linear")
 | 
				
			||||||
 | 
					    color_anim2 = Animation("fill_color", (0, 255, 0, 255), 1.0, "linear")
 | 
				
			||||||
 | 
					    color_anim3 = Animation("fill_color", (0, 0, 255, 255), 1.0, "linear")
 | 
				
			||||||
 | 
					    color_anim4 = Animation("fill_color", (255, 255, 255, 255), 1.0, "linear")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    color_anim1.start(caption2)
 | 
				
			||||||
 | 
					    mcrfpy.setTimer("color2", lambda t: color_anim2.start(caption2), 1000)
 | 
				
			||||||
 | 
					    mcrfpy.setTimer("color3", lambda t: color_anim3.start(caption2), 2000)
 | 
				
			||||||
 | 
					    mcrfpy.setTimer("color4", lambda t: color_anim4.start(caption2), 3000)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Typewriter effect caption
 | 
				
			||||||
 | 
					    caption3 = Caption("", 100, 400)
 | 
				
			||||||
 | 
					    caption3.fill_color = Color(0, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(caption3)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    typewriter = Animation("text", "This text appears one character at a time...", 3.0, "linear")
 | 
				
			||||||
 | 
					    typewriter.start(caption3)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Size animation caption
 | 
				
			||||||
 | 
					    caption4 = Caption("Growing Text", 400, 500)
 | 
				
			||||||
 | 
					    caption4.fill_color = Color(255, 200, 0)
 | 
				
			||||||
 | 
					    ui.append(caption4)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Note: size animation would require font size property support
 | 
				
			||||||
 | 
					    # For now, animate position to simulate growth
 | 
				
			||||||
 | 
					    scale_sim = Animation("y", 480.0, 2.0, "easeInOutElastic")
 | 
				
			||||||
 | 
					    scale_sim.start(caption4)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return [caption1, caption2, caption3, caption4]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_sprite_animations(ui):
 | 
				
			||||||
 | 
					    """Demo 4: Sprite animations including sprite sequences"""
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 4: Sprite Animations (Position, Scale, Sprite Sequences)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Load a test texture (you'll need to adjust path)
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        texture = Texture("assets/sprites/player.png", grid_size=(32, 32))
 | 
				
			||||||
 | 
					    except:
 | 
				
			||||||
 | 
					        # Fallback if texture not found
 | 
				
			||||||
 | 
					        texture = None
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if texture:
 | 
				
			||||||
 | 
					        # Basic sprite with position animation
 | 
				
			||||||
 | 
					        sprite1 = Sprite(100, 200, texture, sprite_index=0)
 | 
				
			||||||
 | 
					        sprite1.scale = 2.0
 | 
				
			||||||
 | 
					        ui.append(sprite1)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Circular motion using sin/cos animations
 | 
				
			||||||
 | 
					        # We'll use delta mode to create circular motion
 | 
				
			||||||
 | 
					        x_circle = Animation("x", 300.0, 4.0, "easeInOutSine")
 | 
				
			||||||
 | 
					        y_circle = Animation("y", 300.0, 4.0, "easeInOutCubic")
 | 
				
			||||||
 | 
					        x_circle.start(sprite1)
 | 
				
			||||||
 | 
					        y_circle.start(sprite1)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Sprite sequence animation (walking cycle)
 | 
				
			||||||
 | 
					        sprite2 = Sprite(500, 300, texture, sprite_index=0)
 | 
				
			||||||
 | 
					        sprite2.scale = 3.0
 | 
				
			||||||
 | 
					        ui.append(sprite2)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Animate through sprite indices for animation
 | 
				
			||||||
 | 
					        walk_cycle = Animation("sprite_index", [0, 1, 2, 3, 2, 1], 2.0, "linear")
 | 
				
			||||||
 | 
					        walk_cycle.start(sprite2)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Scale pulsing sprite
 | 
				
			||||||
 | 
					        sprite3 = Sprite(800, 400, texture, sprite_index=4)
 | 
				
			||||||
 | 
					        ui.append(sprite3)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Note: scale animation would need to be supported
 | 
				
			||||||
 | 
					        # For now use position to simulate
 | 
				
			||||||
 | 
					        pulse_y = Animation("y", 380.0, 0.5, "easeInOutSine")
 | 
				
			||||||
 | 
					        pulse_y.start(sprite3)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Z-index animation for layering
 | 
				
			||||||
 | 
					        sprite3_z = Animation("z_index", 10, 2.0, "linear")
 | 
				
			||||||
 | 
					        sprite3_z.start(sprite3)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return [sprite1, sprite2, sprite3]
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        # Create placeholder caption if no texture
 | 
				
			||||||
 | 
					        no_texture = Caption("(Sprite demo requires texture file)", 400, 350)
 | 
				
			||||||
 | 
					        no_texture.fill_color = Color(255, 100, 100)
 | 
				
			||||||
 | 
					        ui.append(no_texture)
 | 
				
			||||||
 | 
					        return [no_texture]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_grid_animations(ui):
 | 
				
			||||||
 | 
					    """Demo 5: Grid animations (position, camera, zoom)"""
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 5: Grid Animations (Position, Camera Effects)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create a grid
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        texture = Texture("assets/sprites/tiles.png", grid_size=(16, 16))
 | 
				
			||||||
 | 
					    except:
 | 
				
			||||||
 | 
					        texture = None
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    grid = Grid(100, 150, grid_size=(20, 15), texture=texture, 
 | 
				
			||||||
 | 
					                tile_width=24, tile_height=24)
 | 
				
			||||||
 | 
					    grid.fill_color = Color(20, 20, 40)
 | 
				
			||||||
 | 
					    ui.append(grid)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Fill with some test pattern
 | 
				
			||||||
 | 
					    for y in range(15):
 | 
				
			||||||
 | 
					        for x in range(20):
 | 
				
			||||||
 | 
					            point = grid.at(x, y)
 | 
				
			||||||
 | 
					            point.tilesprite = (x + y) % 4
 | 
				
			||||||
 | 
					            point.walkable = ((x + y) % 3) != 0
 | 
				
			||||||
 | 
					            if not point.walkable:
 | 
				
			||||||
 | 
					                point.color = Color(100, 50, 50, 128)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Animate grid position
 | 
				
			||||||
 | 
					    grid_x = Animation("x", 400.0, 3.0, "easeInOutBack")
 | 
				
			||||||
 | 
					    grid_x.start(grid)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Camera pan animation (if supported)
 | 
				
			||||||
 | 
					    # center_x = Animation("center", (10.0, 7.5), 4.0, "easeInOutCubic")
 | 
				
			||||||
 | 
					    # center_x.start(grid)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create entities in the grid
 | 
				
			||||||
 | 
					    if texture:
 | 
				
			||||||
 | 
					        entity1 = Entity(5.0, 5.0, texture, sprite_index=8)
 | 
				
			||||||
 | 
					        entity1.scale = 1.5
 | 
				
			||||||
 | 
					        grid.entities.append(entity1)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Animate entity movement
 | 
				
			||||||
 | 
					        entity_pos = Animation("position", (15.0, 10.0), 3.0, "easeInOutQuad")
 | 
				
			||||||
 | 
					        entity_pos.start(entity1)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Create patrolling entity
 | 
				
			||||||
 | 
					        entity2 = Entity(10.0, 2.0, texture, sprite_index=12)
 | 
				
			||||||
 | 
					        grid.entities.append(entity2)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Animate sprite changes
 | 
				
			||||||
 | 
					        entity2_sprite = Animation("sprite_index", [12, 13, 14, 15, 14, 13], 2.0, "linear")
 | 
				
			||||||
 | 
					        entity2_sprite.start(entity2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_complex_combinations(ui):
 | 
				
			||||||
 | 
					    """Demo 6: Complex multi-property animations"""
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 6: Complex Multi-Property Animations"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create a complex UI composition
 | 
				
			||||||
 | 
					    main_frame = Frame(200, 200, 400, 300)
 | 
				
			||||||
 | 
					    main_frame.fill_color = Color(30, 30, 60, 200)
 | 
				
			||||||
 | 
					    main_frame.outline = 2
 | 
				
			||||||
 | 
					    ui.append(main_frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Child elements
 | 
				
			||||||
 | 
					    title = Caption("Multi-Animation Demo", 20, 20)
 | 
				
			||||||
 | 
					    title.fill_color = Color(255, 255, 255)
 | 
				
			||||||
 | 
					    main_frame.children.append(title)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Animate everything at once
 | 
				
			||||||
 | 
					    # Frame animations
 | 
				
			||||||
 | 
					    frame_x = Animation("x", 600.0, 3.0, "easeInOutElastic")
 | 
				
			||||||
 | 
					    frame_w = Animation("w", 300.0, 2.5, "easeOutBack")
 | 
				
			||||||
 | 
					    frame_fill = Animation("fill_color", (60, 30, 90, 220), 4.0, "easeInOutSine")
 | 
				
			||||||
 | 
					    frame_outline = Animation("outline", 8.0, 3.0, "easeInOutQuad")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    frame_x.start(main_frame)
 | 
				
			||||||
 | 
					    frame_w.start(main_frame)
 | 
				
			||||||
 | 
					    frame_fill.start(main_frame)
 | 
				
			||||||
 | 
					    frame_outline.start(main_frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Title animations  
 | 
				
			||||||
 | 
					    title_color = Animation("fill_color", (255, 200, 0, 255), 2.0, "easeOutBounce")
 | 
				
			||||||
 | 
					    title_color.start(title)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Add animated sub-frames
 | 
				
			||||||
 | 
					    for i in range(3):
 | 
				
			||||||
 | 
					        sub_frame = Frame(50 + i * 100, 100, 80, 80)
 | 
				
			||||||
 | 
					        sub_frame.fill_color = Color(100 + i*50, 50, 200 - i*50, 180)
 | 
				
			||||||
 | 
					        main_frame.children.append(sub_frame)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Rotate positions using delta animations
 | 
				
			||||||
 | 
					        sub_y = Animation("y", 50.0, 2.0, "easeInOutSine", delta=True)
 | 
				
			||||||
 | 
					        sub_y.start(sub_frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return main_frame
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_easing_showcase(ui):
 | 
				
			||||||
 | 
					    """Demo 7: Showcase all 30 easing functions"""
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 7: All 30 Easing Functions Showcase"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create small frames for each easing function
 | 
				
			||||||
 | 
					    frames_per_row = 6
 | 
				
			||||||
 | 
					    frame_size = 180
 | 
				
			||||||
 | 
					    spacing = 10
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for i, easing in enumerate(EASING_FUNCTIONS[:12]):  # First 12 easings
 | 
				
			||||||
 | 
					        row = i // frames_per_row
 | 
				
			||||||
 | 
					        col = i % frames_per_row
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        x = 50 + col * (frame_size + spacing)
 | 
				
			||||||
 | 
					        y = 150 + row * (60 + spacing)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Create indicator frame
 | 
				
			||||||
 | 
					        frame = Frame(x, y, 20, 20)
 | 
				
			||||||
 | 
					        frame.fill_color = Color(100, 200, 255)
 | 
				
			||||||
 | 
					        frame.outline = 1
 | 
				
			||||||
 | 
					        ui.append(frame)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Label
 | 
				
			||||||
 | 
					        label = Caption(easing, x, y - 20)
 | 
				
			||||||
 | 
					        label.fill_color = Color(200, 200, 200)
 | 
				
			||||||
 | 
					        ui.append(label)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Animate using this easing
 | 
				
			||||||
 | 
					        move_anim = Animation("x", x + frame_size - 20, 3.0, easing)
 | 
				
			||||||
 | 
					        move_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Continue with remaining easings after a delay
 | 
				
			||||||
 | 
					    def show_more_easings(runtime):
 | 
				
			||||||
 | 
					        for j, easing in enumerate(EASING_FUNCTIONS[12:24]):  # Next 12
 | 
				
			||||||
 | 
					            row = j // frames_per_row + 2
 | 
				
			||||||
 | 
					            col = j % frames_per_row
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            x = 50 + col * (frame_size + spacing)
 | 
				
			||||||
 | 
					            y = 150 + row * (60 + spacing)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            frame2 = Frame(x, y, 20, 20)
 | 
				
			||||||
 | 
					            frame2.fill_color = Color(255, 150, 100)
 | 
				
			||||||
 | 
					            frame2.outline = 1
 | 
				
			||||||
 | 
					            ui.append(frame2)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            label2 = Caption(easing, x, y - 20)
 | 
				
			||||||
 | 
					            label2.fill_color = Color(200, 200, 200)
 | 
				
			||||||
 | 
					            ui.append(label2)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            move_anim2 = Animation("x", x + frame_size - 20, 3.0, easing)
 | 
				
			||||||
 | 
					            move_anim2.start(frame2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    mcrfpy.setTimer("more_easings", show_more_easings, 1000)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Show final easings
 | 
				
			||||||
 | 
					    def show_final_easings(runtime):
 | 
				
			||||||
 | 
					        for k, easing in enumerate(EASING_FUNCTIONS[24:]):  # Last 6
 | 
				
			||||||
 | 
					            row = k // frames_per_row + 4
 | 
				
			||||||
 | 
					            col = k % frames_per_row
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            x = 50 + col * (frame_size + spacing)
 | 
				
			||||||
 | 
					            y = 150 + row * (60 + spacing)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            frame3 = Frame(x, y, 20, 20)
 | 
				
			||||||
 | 
					            frame3.fill_color = Color(150, 255, 150)
 | 
				
			||||||
 | 
					            frame3.outline = 1
 | 
				
			||||||
 | 
					            ui.append(frame3)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            label3 = Caption(easing, x, y - 20)
 | 
				
			||||||
 | 
					            label3.fill_color = Color(200, 200, 200)
 | 
				
			||||||
 | 
					            ui.append(label3)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            move_anim3 = Animation("x", x + frame_size - 20, 3.0, easing)
 | 
				
			||||||
 | 
					            move_anim3.start(frame3)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    mcrfpy.setTimer("final_easings", show_final_easings, 2000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_delta_animations(ui):
 | 
				
			||||||
 | 
					    """Demo 8: Delta mode animations (relative movements)"""
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 8: Delta Mode Animations (Relative Movements)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create objects that will move relative to their position
 | 
				
			||||||
 | 
					    frames = []
 | 
				
			||||||
 | 
					    start_positions = [(100, 200), (300, 200), (500, 200), (700, 200)]
 | 
				
			||||||
 | 
					    colors = [Color(255, 100, 100), Color(100, 255, 100), 
 | 
				
			||||||
 | 
					              Color(100, 100, 255), Color(255, 255, 100)]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for i, (x, y) in enumerate(start_positions):
 | 
				
			||||||
 | 
					        frame = Frame(x, y, 80, 80)
 | 
				
			||||||
 | 
					        frame.fill_color = colors[i]
 | 
				
			||||||
 | 
					        frame.outline = 2
 | 
				
			||||||
 | 
					        ui.append(frame)
 | 
				
			||||||
 | 
					        frames.append(frame)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Delta animations - move relative to current position
 | 
				
			||||||
 | 
					        # Each frame moves by different amounts
 | 
				
			||||||
 | 
					        dx = (i + 1) * 50
 | 
				
			||||||
 | 
					        dy = math.sin(i) * 100
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        x_delta = Animation("x", dx, 2.0, "easeInOutBack", delta=True)
 | 
				
			||||||
 | 
					        y_delta = Animation("y", dy, 2.0, "easeInOutElastic", delta=True)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        x_delta.start(frame)
 | 
				
			||||||
 | 
					        y_delta.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create caption showing delta mode
 | 
				
			||||||
 | 
					    delta_label = Caption("Delta mode: Relative animations from current position", 200, 400)
 | 
				
			||||||
 | 
					    delta_label.fill_color = Color(255, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(delta_label)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Animate the label with delta mode text append
 | 
				
			||||||
 | 
					    text_delta = Animation("text", " - ANIMATED!", 2.0, "linear", delta=True)
 | 
				
			||||||
 | 
					    text_delta.start(delta_label)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return frames
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_color_component_animations(ui):
 | 
				
			||||||
 | 
					    """Demo 9: Individual color channel animations"""
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 9: Color Component Animations (R, G, B, A channels)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create frames to demonstrate individual color channel animations
 | 
				
			||||||
 | 
					    base_frame = Frame(300, 200, 600, 300)
 | 
				
			||||||
 | 
					    base_frame.fill_color = Color(128, 128, 128, 255)
 | 
				
			||||||
 | 
					    base_frame.outline = 3
 | 
				
			||||||
 | 
					    ui.append(base_frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Labels for each channel
 | 
				
			||||||
 | 
					    labels = ["Red", "Green", "Blue", "Alpha"]
 | 
				
			||||||
 | 
					    positions = [(50, 50), (200, 50), (350, 50), (500, 50)]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for i, (label_text, (x, y)) in enumerate(zip(labels, positions)):
 | 
				
			||||||
 | 
					        # Create label
 | 
				
			||||||
 | 
					        label = Caption(label_text, x, y - 30)
 | 
				
			||||||
 | 
					        label.fill_color = Color(255, 255, 255)
 | 
				
			||||||
 | 
					        base_frame.children.append(label)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Create demo frame for this channel
 | 
				
			||||||
 | 
					        demo_frame = Frame(x, y, 100, 100)
 | 
				
			||||||
 | 
					        demo_frame.fill_color = Color(100, 100, 100, 200)
 | 
				
			||||||
 | 
					        demo_frame.outline = 2
 | 
				
			||||||
 | 
					        base_frame.children.append(demo_frame)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Animate individual color channel
 | 
				
			||||||
 | 
					        if i == 0:  # Red
 | 
				
			||||||
 | 
					            r_anim = Animation("fill_color.r", 255, 3.0, "easeInOutSine")
 | 
				
			||||||
 | 
					            r_anim.start(demo_frame)
 | 
				
			||||||
 | 
					        elif i == 1:  # Green  
 | 
				
			||||||
 | 
					            g_anim = Animation("fill_color.g", 255, 3.0, "easeInOutSine")
 | 
				
			||||||
 | 
					            g_anim.start(demo_frame)
 | 
				
			||||||
 | 
					        elif i == 2:  # Blue
 | 
				
			||||||
 | 
					            b_anim = Animation("fill_color.b", 255, 3.0, "easeInOutSine")
 | 
				
			||||||
 | 
					            b_anim.start(demo_frame)
 | 
				
			||||||
 | 
					        else:  # Alpha
 | 
				
			||||||
 | 
					            a_anim = Animation("fill_color.a", 50, 3.0, "easeInOutSine")
 | 
				
			||||||
 | 
					            a_anim.start(demo_frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Animate main frame outline color components in sequence
 | 
				
			||||||
 | 
					    outline_r = Animation("outline_color.r", 255, 1.0, "linear")
 | 
				
			||||||
 | 
					    outline_g = Animation("outline_color.g", 255, 1.0, "linear")
 | 
				
			||||||
 | 
					    outline_b = Animation("outline_color.b", 0, 1.0, "linear")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    outline_r.start(base_frame)
 | 
				
			||||||
 | 
					    mcrfpy.setTimer("outline_g", lambda t: outline_g.start(base_frame), 1000)
 | 
				
			||||||
 | 
					    mcrfpy.setTimer("outline_b", lambda t: outline_b.start(base_frame), 2000)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return base_frame
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_performance_stress_test(ui):
 | 
				
			||||||
 | 
					    """Demo 10: Performance test with many simultaneous animations"""
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 10: Performance Stress Test (100+ Simultaneous Animations)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create many small objects with different animations
 | 
				
			||||||
 | 
					    num_objects = 100
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for i in range(num_objects):
 | 
				
			||||||
 | 
					        # Random starting position
 | 
				
			||||||
 | 
					        x = 100 + (i % 20) * 50
 | 
				
			||||||
 | 
					        y = 150 + (i // 20) * 50
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Create small frame
 | 
				
			||||||
 | 
					        size = 20 + (i % 3) * 10
 | 
				
			||||||
 | 
					        frame = Frame(x, y, size, size)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Random color
 | 
				
			||||||
 | 
					        r = (i * 37) % 256
 | 
				
			||||||
 | 
					        g = (i * 73) % 256  
 | 
				
			||||||
 | 
					        b = (i * 113) % 256
 | 
				
			||||||
 | 
					        frame.fill_color = Color(r, g, b, 200)
 | 
				
			||||||
 | 
					        frame.outline = 1
 | 
				
			||||||
 | 
					        ui.append(frame)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Random animation properties
 | 
				
			||||||
 | 
					        target_x = 100 + (i % 15) * 70
 | 
				
			||||||
 | 
					        target_y = 150 + (i // 15) * 70
 | 
				
			||||||
 | 
					        duration = 2.0 + (i % 30) * 0.1
 | 
				
			||||||
 | 
					        easing = EASING_FUNCTIONS[i % len(EASING_FUNCTIONS)]
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Start multiple animations per object
 | 
				
			||||||
 | 
					        x_anim = Animation("x", target_x, duration, easing)
 | 
				
			||||||
 | 
					        y_anim = Animation("y", target_y, duration, easing)
 | 
				
			||||||
 | 
					        opacity_anim = Animation("opacity", 0.3 + (i % 7) * 0.1, duration, "easeInOutSine")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        x_anim.start(frame)
 | 
				
			||||||
 | 
					        y_anim.start(frame)
 | 
				
			||||||
 | 
					        opacity_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Performance counter
 | 
				
			||||||
 | 
					    perf_caption = Caption(f"Animating {num_objects * 3} properties simultaneously", 400, 600)
 | 
				
			||||||
 | 
					    perf_caption.fill_color = Color(255, 255, 0)
 | 
				
			||||||
 | 
					    ui.append(perf_caption)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def next_demo(runtime):
 | 
				
			||||||
 | 
					    """Cycle to the next demo"""
 | 
				
			||||||
 | 
					    global current_demo, demo_start_time
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Clear the UI except title and subtitle
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Keep only the first two elements (title and subtitle)
 | 
				
			||||||
 | 
					    while len(ui) > 2:
 | 
				
			||||||
 | 
					        # Remove from the end to avoid index issues
 | 
				
			||||||
 | 
					        ui.remove(len(ui) - 1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Run the next demo
 | 
				
			||||||
 | 
					    if current_demo < len(demos):
 | 
				
			||||||
 | 
					        demos[current_demo](ui)
 | 
				
			||||||
 | 
					        current_demo += 1
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Schedule next demo
 | 
				
			||||||
 | 
					        if current_demo < len(demos):
 | 
				
			||||||
 | 
					            mcrfpy.setTimer("next_demo", next_demo, int(DEMO_DURATION * 1000))
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        # All demos complete
 | 
				
			||||||
 | 
					        subtitle.text = "Animation Showcase Complete! Press ESC to exit."
 | 
				
			||||||
 | 
					        complete = Caption("All animation types demonstrated!", 400, 350)
 | 
				
			||||||
 | 
					        complete.fill_color = Color(0, 255, 0)
 | 
				
			||||||
 | 
					        complete.outline = 2
 | 
				
			||||||
 | 
					        ui.append(complete)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def run_sizzle_reel(runtime):
 | 
				
			||||||
 | 
					    """Main entry point - start the demo sequence"""
 | 
				
			||||||
 | 
					    global demos
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # List of all demo functions
 | 
				
			||||||
 | 
					    demos = [
 | 
				
			||||||
 | 
					        demo_frame_basic_animations,
 | 
				
			||||||
 | 
					        demo_frame_opacity_zindex,
 | 
				
			||||||
 | 
					        demo_caption_animations,
 | 
				
			||||||
 | 
					        demo_sprite_animations,
 | 
				
			||||||
 | 
					        demo_grid_animations,
 | 
				
			||||||
 | 
					        demo_complex_combinations,
 | 
				
			||||||
 | 
					        demo_easing_showcase,
 | 
				
			||||||
 | 
					        demo_delta_animations,
 | 
				
			||||||
 | 
					        demo_color_component_animations,
 | 
				
			||||||
 | 
					        demo_performance_stress_test
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Start the first demo
 | 
				
			||||||
 | 
					    next_demo(runtime)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Initialize scene
 | 
				
			||||||
 | 
					ui = create_demo_scene()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Start the sizzle reel after a short delay
 | 
				
			||||||
 | 
					mcrfpy.setTimer("start_sizzle", run_sizzle_reel, 500)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					print("Starting McRogueFace Animation Sizzle Reel...")
 | 
				
			||||||
 | 
					print("This will demonstrate ALL animation types on ALL objects.")
 | 
				
			||||||
 | 
					print("Press ESC at any time to exit.")
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,227 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					McRogueFace Animation Sizzle Reel (Fixed)
 | 
				
			||||||
 | 
					=========================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This script demonstrates EVERY animation type on EVERY UI object type.
 | 
				
			||||||
 | 
					Fixed version that works properly with the game loop.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import mcrfpy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Configuration
 | 
				
			||||||
 | 
					SCENE_WIDTH = 1280
 | 
				
			||||||
 | 
					SCENE_HEIGHT = 720
 | 
				
			||||||
 | 
					DEMO_DURATION = 5.0  # Duration for each demo section
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# All available easing functions
 | 
				
			||||||
 | 
					EASING_FUNCTIONS = [
 | 
				
			||||||
 | 
					    "linear", "easeIn", "easeOut", "easeInOut",
 | 
				
			||||||
 | 
					    "easeInQuad", "easeOutQuad", "easeInOutQuad",
 | 
				
			||||||
 | 
					    "easeInCubic", "easeOutCubic", "easeInOutCubic",
 | 
				
			||||||
 | 
					    "easeInQuart", "easeOutQuart", "easeInOutQuart",
 | 
				
			||||||
 | 
					    "easeInSine", "easeOutSine", "easeInOutSine",
 | 
				
			||||||
 | 
					    "easeInExpo", "easeOutExpo", "easeInOutExpo",
 | 
				
			||||||
 | 
					    "easeInCirc", "easeOutCirc", "easeInOutCirc",
 | 
				
			||||||
 | 
					    "easeInElastic", "easeOutElastic", "easeInOutElastic",
 | 
				
			||||||
 | 
					    "easeInBack", "easeOutBack", "easeInOutBack",
 | 
				
			||||||
 | 
					    "easeInBounce", "easeOutBounce", "easeInOutBounce"
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Track current demo state
 | 
				
			||||||
 | 
					current_demo = 0
 | 
				
			||||||
 | 
					subtitle = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def create_demo_scene():
 | 
				
			||||||
 | 
					    """Create the main demo scene with title"""
 | 
				
			||||||
 | 
					    mcrfpy.createScene("sizzle_reel")
 | 
				
			||||||
 | 
					    mcrfpy.setScene("sizzle_reel")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Title caption
 | 
				
			||||||
 | 
					    title = mcrfpy.Caption("McRogueFace Animation Sizzle Reel", 
 | 
				
			||||||
 | 
					                   SCENE_WIDTH/2 - 200, 20)
 | 
				
			||||||
 | 
					    title.fill_color = mcrfpy.Color(255, 255, 0)
 | 
				
			||||||
 | 
					    title.outline = 2
 | 
				
			||||||
 | 
					    title.outline_color = mcrfpy.Color(0, 0, 0)
 | 
				
			||||||
 | 
					    ui.append(title)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Subtitle showing current demo
 | 
				
			||||||
 | 
					    global subtitle
 | 
				
			||||||
 | 
					    subtitle = mcrfpy.Caption("Initializing...", 
 | 
				
			||||||
 | 
					                      SCENE_WIDTH/2 - 150, 60)
 | 
				
			||||||
 | 
					    subtitle.fill_color = mcrfpy.Color(200, 200, 200)
 | 
				
			||||||
 | 
					    ui.append(subtitle)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return ui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_frame_basic_animations():
 | 
				
			||||||
 | 
					    """Demo 1: Basic frame animations - position, size, colors"""
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 1: Frame Basic Animations (Position, Size, Colors)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create test frame
 | 
				
			||||||
 | 
					    frame = mcrfpy.Frame(100, 150, 200, 100)
 | 
				
			||||||
 | 
					    frame.fill_color = mcrfpy.Color(50, 50, 150)
 | 
				
			||||||
 | 
					    frame.outline = 3
 | 
				
			||||||
 | 
					    frame.outline_color = mcrfpy.Color(255, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Position animations with different easings
 | 
				
			||||||
 | 
					    x_anim = mcrfpy.Animation("x", 800.0, 2.0, "easeInOutBack")
 | 
				
			||||||
 | 
					    y_anim = mcrfpy.Animation("y", 400.0, 2.0, "easeInOutElastic")
 | 
				
			||||||
 | 
					    x_anim.start(frame)
 | 
				
			||||||
 | 
					    y_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Size animations
 | 
				
			||||||
 | 
					    w_anim = mcrfpy.Animation("w", 400.0, 3.0, "easeInOutCubic")
 | 
				
			||||||
 | 
					    h_anim = mcrfpy.Animation("h", 200.0, 3.0, "easeInOutCubic")
 | 
				
			||||||
 | 
					    w_anim.start(frame)
 | 
				
			||||||
 | 
					    h_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Color animations
 | 
				
			||||||
 | 
					    fill_anim = mcrfpy.Animation("fill_color", mcrfpy.Color(255, 100, 50, 200), 4.0, "easeInOutSine")
 | 
				
			||||||
 | 
					    outline_anim = mcrfpy.Animation("outline_color", mcrfpy.Color(0, 255, 255), 4.0, "easeOutBounce")
 | 
				
			||||||
 | 
					    fill_anim.start(frame)
 | 
				
			||||||
 | 
					    outline_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Outline thickness animation
 | 
				
			||||||
 | 
					    thickness_anim = mcrfpy.Animation("outline", 10.0, 4.5, "easeInOutQuad")
 | 
				
			||||||
 | 
					    thickness_anim.start(frame)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_caption_animations():
 | 
				
			||||||
 | 
					    """Demo 2: Caption text animations and effects"""
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 2: Caption Animations (Text, Color, Position)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Basic caption with position animation
 | 
				
			||||||
 | 
					    caption1 = mcrfpy.Caption("Moving Text!", 100, 200)
 | 
				
			||||||
 | 
					    caption1.fill_color = mcrfpy.Color(255, 255, 255)
 | 
				
			||||||
 | 
					    caption1.outline = 1
 | 
				
			||||||
 | 
					    ui.append(caption1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Animate across screen with bounce
 | 
				
			||||||
 | 
					    x_anim = mcrfpy.Animation("x", 900.0, 3.0, "easeOutBounce")
 | 
				
			||||||
 | 
					    x_anim.start(caption1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Color cycling caption
 | 
				
			||||||
 | 
					    caption2 = mcrfpy.Caption("Rainbow Colors", 400, 300)
 | 
				
			||||||
 | 
					    caption2.outline = 2
 | 
				
			||||||
 | 
					    ui.append(caption2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Cycle through colors
 | 
				
			||||||
 | 
					    color_anim1 = mcrfpy.Animation("fill_color", mcrfpy.Color(255, 0, 0), 1.0, "linear")
 | 
				
			||||||
 | 
					    color_anim1.start(caption2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Typewriter effect caption
 | 
				
			||||||
 | 
					    caption3 = mcrfpy.Caption("", 100, 400)
 | 
				
			||||||
 | 
					    caption3.fill_color = mcrfpy.Color(0, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(caption3)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    typewriter = mcrfpy.Animation("text", "This text appears one character at a time...", 3.0, "linear")
 | 
				
			||||||
 | 
					    typewriter.start(caption3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_sprite_animations():
 | 
				
			||||||
 | 
					    """Demo 3: Sprite animations (if texture available)"""
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 3: Sprite Animations"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create placeholder caption since texture might not exist
 | 
				
			||||||
 | 
					    no_texture = mcrfpy.Caption("(Sprite demo - textures may not be loaded)", 400, 350)
 | 
				
			||||||
 | 
					    no_texture.fill_color = mcrfpy.Color(255, 100, 100)
 | 
				
			||||||
 | 
					    ui.append(no_texture)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_performance_stress_test():
 | 
				
			||||||
 | 
					    """Demo 4: Performance test with many simultaneous animations"""
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 4: Performance Test (50+ Simultaneous Animations)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create many small objects with different animations
 | 
				
			||||||
 | 
					    num_objects = 50
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for i in range(num_objects):
 | 
				
			||||||
 | 
					        # Random starting position
 | 
				
			||||||
 | 
					        x = 100 + (i % 10) * 100
 | 
				
			||||||
 | 
					        y = 150 + (i // 10) * 80
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Create small frame
 | 
				
			||||||
 | 
					        size = 20 + (i % 3) * 10
 | 
				
			||||||
 | 
					        frame = mcrfpy.Frame(x, y, size, size)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Random color
 | 
				
			||||||
 | 
					        r = (i * 37) % 256
 | 
				
			||||||
 | 
					        g = (i * 73) % 256  
 | 
				
			||||||
 | 
					        b = (i * 113) % 256
 | 
				
			||||||
 | 
					        frame.fill_color = mcrfpy.Color(r, g, b, 200)
 | 
				
			||||||
 | 
					        frame.outline = 1
 | 
				
			||||||
 | 
					        ui.append(frame)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Random animation properties
 | 
				
			||||||
 | 
					        target_x = 100 + (i % 8) * 120
 | 
				
			||||||
 | 
					        target_y = 150 + (i // 8) * 100
 | 
				
			||||||
 | 
					        duration = 2.0 + (i % 30) * 0.1
 | 
				
			||||||
 | 
					        easing = EASING_FUNCTIONS[i % len(EASING_FUNCTIONS)]
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Start multiple animations per object
 | 
				
			||||||
 | 
					        x_anim = mcrfpy.Animation("x", float(target_x), duration, easing)
 | 
				
			||||||
 | 
					        y_anim = mcrfpy.Animation("y", float(target_y), duration, easing)
 | 
				
			||||||
 | 
					        opacity_anim = mcrfpy.Animation("opacity", 0.3 + (i % 7) * 0.1, duration, "easeInOutSine")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        x_anim.start(frame)
 | 
				
			||||||
 | 
					        y_anim.start(frame)
 | 
				
			||||||
 | 
					        opacity_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Performance counter
 | 
				
			||||||
 | 
					    perf_caption = mcrfpy.Caption(f"Animating {num_objects * 3} properties simultaneously", 400, 600)
 | 
				
			||||||
 | 
					    perf_caption.fill_color = mcrfpy.Color(255, 255, 0)
 | 
				
			||||||
 | 
					    ui.append(perf_caption)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def clear_scene():
 | 
				
			||||||
 | 
					    """Clear the scene except title and subtitle"""
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Keep only the first two elements (title and subtitle)
 | 
				
			||||||
 | 
					    while len(ui) > 2:
 | 
				
			||||||
 | 
					        ui.remove(ui[2])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def run_demo_sequence(runtime):
 | 
				
			||||||
 | 
					    """Run through all demos"""
 | 
				
			||||||
 | 
					    global current_demo
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Clear previous demo
 | 
				
			||||||
 | 
					    clear_scene()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Demo list
 | 
				
			||||||
 | 
					    demos = [
 | 
				
			||||||
 | 
					        demo_frame_basic_animations,
 | 
				
			||||||
 | 
					        demo_caption_animations,
 | 
				
			||||||
 | 
					        demo_sprite_animations,
 | 
				
			||||||
 | 
					        demo_performance_stress_test
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if current_demo < len(demos):
 | 
				
			||||||
 | 
					        # Run current demo
 | 
				
			||||||
 | 
					        demos[current_demo]()
 | 
				
			||||||
 | 
					        current_demo += 1
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Schedule next demo
 | 
				
			||||||
 | 
					        if current_demo < len(demos):
 | 
				
			||||||
 | 
					            mcrfpy.setTimer("next_demo", run_demo_sequence, int(DEMO_DURATION * 1000))
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        # All demos complete
 | 
				
			||||||
 | 
					        subtitle.text = "Animation Showcase Complete!"
 | 
				
			||||||
 | 
					        complete = mcrfpy.Caption("All animation types demonstrated!", 400, 350)
 | 
				
			||||||
 | 
					        complete.fill_color = mcrfpy.Color(0, 255, 0)
 | 
				
			||||||
 | 
					        complete.outline = 2
 | 
				
			||||||
 | 
					        ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					        ui.append(complete)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Initialize scene
 | 
				
			||||||
 | 
					print("Starting McRogueFace Animation Sizzle Reel...")
 | 
				
			||||||
 | 
					print("This will demonstrate animation types on various objects.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ui = create_demo_scene()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Start the demo sequence after a short delay
 | 
				
			||||||
 | 
					mcrfpy.setTimer("start_demos", run_demo_sequence, 500)
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,307 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					McRogueFace Animation Sizzle Reel v2
 | 
				
			||||||
 | 
					====================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixed version with proper API usage for animations and collections.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import mcrfpy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Configuration
 | 
				
			||||||
 | 
					SCENE_WIDTH = 1280
 | 
				
			||||||
 | 
					SCENE_HEIGHT = 720
 | 
				
			||||||
 | 
					DEMO_DURATION = 5.0  # Duration for each demo section
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# All available easing functions
 | 
				
			||||||
 | 
					EASING_FUNCTIONS = [
 | 
				
			||||||
 | 
					    "linear", "easeIn", "easeOut", "easeInOut",
 | 
				
			||||||
 | 
					    "easeInQuad", "easeOutQuad", "easeInOutQuad",
 | 
				
			||||||
 | 
					    "easeInCubic", "easeOutCubic", "easeInOutCubic",
 | 
				
			||||||
 | 
					    "easeInQuart", "easeOutQuart", "easeInOutQuart",
 | 
				
			||||||
 | 
					    "easeInSine", "easeOutSine", "easeInOutSine",
 | 
				
			||||||
 | 
					    "easeInExpo", "easeOutExpo", "easeInOutExpo",
 | 
				
			||||||
 | 
					    "easeInCirc", "easeOutCirc", "easeInOutCirc",
 | 
				
			||||||
 | 
					    "easeInElastic", "easeOutElastic", "easeInOutElastic",
 | 
				
			||||||
 | 
					    "easeInBack", "easeOutBack", "easeInOutBack",
 | 
				
			||||||
 | 
					    "easeInBounce", "easeOutBounce", "easeInOutBounce"
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Track current demo state
 | 
				
			||||||
 | 
					current_demo = 0
 | 
				
			||||||
 | 
					subtitle = None
 | 
				
			||||||
 | 
					demo_objects = []  # Track objects from current demo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def create_demo_scene():
 | 
				
			||||||
 | 
					    """Create the main demo scene with title"""
 | 
				
			||||||
 | 
					    mcrfpy.createScene("sizzle_reel")
 | 
				
			||||||
 | 
					    mcrfpy.setScene("sizzle_reel")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Title caption
 | 
				
			||||||
 | 
					    title = mcrfpy.Caption("McRogueFace Animation Sizzle Reel", 
 | 
				
			||||||
 | 
					                   SCENE_WIDTH/2 - 200, 20)
 | 
				
			||||||
 | 
					    title.fill_color = mcrfpy.Color(255, 255, 0)
 | 
				
			||||||
 | 
					    title.outline = 2
 | 
				
			||||||
 | 
					    title.outline_color = mcrfpy.Color(0, 0, 0)
 | 
				
			||||||
 | 
					    ui.append(title)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Subtitle showing current demo
 | 
				
			||||||
 | 
					    global subtitle
 | 
				
			||||||
 | 
					    subtitle = mcrfpy.Caption("Initializing...", 
 | 
				
			||||||
 | 
					                      SCENE_WIDTH/2 - 150, 60)
 | 
				
			||||||
 | 
					    subtitle.fill_color = mcrfpy.Color(200, 200, 200)
 | 
				
			||||||
 | 
					    ui.append(subtitle)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return ui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_frame_basic_animations():
 | 
				
			||||||
 | 
					    """Demo 1: Basic frame animations - position, size, colors"""
 | 
				
			||||||
 | 
					    global demo_objects
 | 
				
			||||||
 | 
					    demo_objects = []
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 1: Frame Basic Animations (Position, Size, Colors)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create test frame
 | 
				
			||||||
 | 
					    frame = mcrfpy.Frame(100, 150, 200, 100)
 | 
				
			||||||
 | 
					    frame.fill_color = mcrfpy.Color(50, 50, 150)
 | 
				
			||||||
 | 
					    frame.outline = 3
 | 
				
			||||||
 | 
					    frame.outline_color = mcrfpy.Color(255, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(frame)
 | 
				
			||||||
 | 
					    demo_objects.append(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Position animations with different easings
 | 
				
			||||||
 | 
					    x_anim = mcrfpy.Animation("x", 800.0, 2.0, "easeInOutBack")
 | 
				
			||||||
 | 
					    y_anim = mcrfpy.Animation("y", 400.0, 2.0, "easeInOutElastic")
 | 
				
			||||||
 | 
					    x_anim.start(frame)
 | 
				
			||||||
 | 
					    y_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Size animations
 | 
				
			||||||
 | 
					    w_anim = mcrfpy.Animation("w", 400.0, 3.0, "easeInOutCubic")
 | 
				
			||||||
 | 
					    h_anim = mcrfpy.Animation("h", 200.0, 3.0, "easeInOutCubic")
 | 
				
			||||||
 | 
					    w_anim.start(frame)
 | 
				
			||||||
 | 
					    h_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Color animations - use tuples instead of Color objects
 | 
				
			||||||
 | 
					    fill_anim = mcrfpy.Animation("fill_color", (255, 100, 50, 200), 4.0, "easeInOutSine")
 | 
				
			||||||
 | 
					    outline_anim = mcrfpy.Animation("outline_color", (0, 255, 255, 255), 4.0, "easeOutBounce")
 | 
				
			||||||
 | 
					    fill_anim.start(frame)
 | 
				
			||||||
 | 
					    outline_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Outline thickness animation
 | 
				
			||||||
 | 
					    thickness_anim = mcrfpy.Animation("outline", 10.0, 4.5, "easeInOutQuad")
 | 
				
			||||||
 | 
					    thickness_anim.start(frame)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_caption_animations():
 | 
				
			||||||
 | 
					    """Demo 2: Caption text animations and effects"""
 | 
				
			||||||
 | 
					    global demo_objects
 | 
				
			||||||
 | 
					    demo_objects = []
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 2: Caption Animations (Text, Color, Position)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Basic caption with position animation
 | 
				
			||||||
 | 
					    caption1 = mcrfpy.Caption("Moving Text!", 100, 200)
 | 
				
			||||||
 | 
					    caption1.fill_color = mcrfpy.Color(255, 255, 255)
 | 
				
			||||||
 | 
					    caption1.outline = 1
 | 
				
			||||||
 | 
					    ui.append(caption1)
 | 
				
			||||||
 | 
					    demo_objects.append(caption1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Animate across screen with bounce
 | 
				
			||||||
 | 
					    x_anim = mcrfpy.Animation("x", 900.0, 3.0, "easeOutBounce")
 | 
				
			||||||
 | 
					    x_anim.start(caption1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Color cycling caption
 | 
				
			||||||
 | 
					    caption2 = mcrfpy.Caption("Rainbow Colors", 400, 300)
 | 
				
			||||||
 | 
					    caption2.outline = 2
 | 
				
			||||||
 | 
					    ui.append(caption2)
 | 
				
			||||||
 | 
					    demo_objects.append(caption2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Cycle through colors using tuples
 | 
				
			||||||
 | 
					    color_anim1 = mcrfpy.Animation("fill_color", (255, 0, 0, 255), 1.0, "linear")
 | 
				
			||||||
 | 
					    color_anim1.start(caption2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Schedule color changes
 | 
				
			||||||
 | 
					    def change_to_green(rt):
 | 
				
			||||||
 | 
					        color_anim2 = mcrfpy.Animation("fill_color", (0, 255, 0, 255), 1.0, "linear")
 | 
				
			||||||
 | 
					        color_anim2.start(caption2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def change_to_blue(rt):
 | 
				
			||||||
 | 
					        color_anim3 = mcrfpy.Animation("fill_color", (0, 0, 255, 255), 1.0, "linear")
 | 
				
			||||||
 | 
					        color_anim3.start(caption2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def change_to_white(rt):
 | 
				
			||||||
 | 
					        color_anim4 = mcrfpy.Animation("fill_color", (255, 255, 255, 255), 1.0, "linear")
 | 
				
			||||||
 | 
					        color_anim4.start(caption2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    mcrfpy.setTimer("color2", change_to_green, 1000)
 | 
				
			||||||
 | 
					    mcrfpy.setTimer("color3", change_to_blue, 2000)
 | 
				
			||||||
 | 
					    mcrfpy.setTimer("color4", change_to_white, 3000)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Typewriter effect caption
 | 
				
			||||||
 | 
					    caption3 = mcrfpy.Caption("", 100, 400)
 | 
				
			||||||
 | 
					    caption3.fill_color = mcrfpy.Color(0, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(caption3)
 | 
				
			||||||
 | 
					    demo_objects.append(caption3)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    typewriter = mcrfpy.Animation("text", "This text appears one character at a time...", 3.0, "linear")
 | 
				
			||||||
 | 
					    typewriter.start(caption3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_easing_showcase():
 | 
				
			||||||
 | 
					    """Demo 3: Showcase different easing functions"""
 | 
				
			||||||
 | 
					    global demo_objects
 | 
				
			||||||
 | 
					    demo_objects = []
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 3: Easing Functions Showcase"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create small frames for each easing function
 | 
				
			||||||
 | 
					    frames_per_row = 6
 | 
				
			||||||
 | 
					    frame_width = 180
 | 
				
			||||||
 | 
					    spacing = 10
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Show first 12 easings
 | 
				
			||||||
 | 
					    for i, easing in enumerate(EASING_FUNCTIONS[:12]):
 | 
				
			||||||
 | 
					        row = i // frames_per_row
 | 
				
			||||||
 | 
					        col = i % frames_per_row
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        x = 50 + col * (frame_width + spacing)
 | 
				
			||||||
 | 
					        y = 150 + row * (80 + spacing)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Create indicator frame
 | 
				
			||||||
 | 
					        frame = mcrfpy.Frame(x, y, 20, 20)
 | 
				
			||||||
 | 
					        frame.fill_color = mcrfpy.Color(100, 200, 255)
 | 
				
			||||||
 | 
					        frame.outline = 1
 | 
				
			||||||
 | 
					        ui.append(frame)
 | 
				
			||||||
 | 
					        demo_objects.append(frame)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Label
 | 
				
			||||||
 | 
					        label = mcrfpy.Caption(easing[:8], x, y - 20)  # Truncate long names
 | 
				
			||||||
 | 
					        label.fill_color = mcrfpy.Color(200, 200, 200)
 | 
				
			||||||
 | 
					        ui.append(label)
 | 
				
			||||||
 | 
					        demo_objects.append(label)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Animate using this easing
 | 
				
			||||||
 | 
					        move_anim = mcrfpy.Animation("x", float(x + frame_width - 20), 3.0, easing)
 | 
				
			||||||
 | 
					        move_anim.start(frame)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo_performance_stress_test():
 | 
				
			||||||
 | 
					    """Demo 4: Performance test with many simultaneous animations"""
 | 
				
			||||||
 | 
					    global demo_objects
 | 
				
			||||||
 | 
					    demo_objects = []
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 4: Performance Test (50+ Simultaneous Animations)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create many small objects with different animations
 | 
				
			||||||
 | 
					    num_objects = 50
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for i in range(num_objects):
 | 
				
			||||||
 | 
					        # Starting position
 | 
				
			||||||
 | 
					        x = 100 + (i % 10) * 100
 | 
				
			||||||
 | 
					        y = 150 + (i // 10) * 80
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Create small frame
 | 
				
			||||||
 | 
					        size = 20 + (i % 3) * 10
 | 
				
			||||||
 | 
					        frame = mcrfpy.Frame(x, y, size, size)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Random color
 | 
				
			||||||
 | 
					        r = (i * 37) % 256
 | 
				
			||||||
 | 
					        g = (i * 73) % 256  
 | 
				
			||||||
 | 
					        b = (i * 113) % 256
 | 
				
			||||||
 | 
					        frame.fill_color = mcrfpy.Color(r, g, b, 200)
 | 
				
			||||||
 | 
					        frame.outline = 1
 | 
				
			||||||
 | 
					        ui.append(frame)
 | 
				
			||||||
 | 
					        demo_objects.append(frame)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Random animation properties
 | 
				
			||||||
 | 
					        target_x = 100 + (i % 8) * 120
 | 
				
			||||||
 | 
					        target_y = 150 + (i // 8) * 100
 | 
				
			||||||
 | 
					        duration = 2.0 + (i % 30) * 0.1
 | 
				
			||||||
 | 
					        easing = EASING_FUNCTIONS[i % len(EASING_FUNCTIONS)]
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Start multiple animations per object
 | 
				
			||||||
 | 
					        x_anim = mcrfpy.Animation("x", float(target_x), duration, easing)
 | 
				
			||||||
 | 
					        y_anim = mcrfpy.Animation("y", float(target_y), duration, easing)
 | 
				
			||||||
 | 
					        opacity_anim = mcrfpy.Animation("opacity", 0.3 + (i % 7) * 0.1, duration, "easeInOutSine")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        x_anim.start(frame)
 | 
				
			||||||
 | 
					        y_anim.start(frame)
 | 
				
			||||||
 | 
					        opacity_anim.start(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Performance counter
 | 
				
			||||||
 | 
					    perf_caption = mcrfpy.Caption(f"Animating {num_objects * 3} properties simultaneously", 350, 600)
 | 
				
			||||||
 | 
					    perf_caption.fill_color = mcrfpy.Color(255, 255, 0)
 | 
				
			||||||
 | 
					    ui.append(perf_caption)
 | 
				
			||||||
 | 
					    demo_objects.append(perf_caption)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def clear_scene():
 | 
				
			||||||
 | 
					    """Clear the scene except title and subtitle"""
 | 
				
			||||||
 | 
					    global demo_objects
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Remove all demo objects
 | 
				
			||||||
 | 
					    for obj in demo_objects:
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            # Find index of object
 | 
				
			||||||
 | 
					            for i in range(len(ui)):
 | 
				
			||||||
 | 
					                if ui[i] is obj:
 | 
				
			||||||
 | 
					                    ui.remove(ui[i])
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            pass  # Object might already be removed
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    demo_objects = []
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Clean up any timers
 | 
				
			||||||
 | 
					    for timer_name in ["color2", "color3", "color4"]:
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            mcrfpy.delTimer(timer_name)
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def run_demo_sequence(runtime):
 | 
				
			||||||
 | 
					    """Run through all demos"""
 | 
				
			||||||
 | 
					    global current_demo
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Clear previous demo
 | 
				
			||||||
 | 
					    clear_scene()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Demo list
 | 
				
			||||||
 | 
					    demos = [
 | 
				
			||||||
 | 
					        demo_frame_basic_animations,
 | 
				
			||||||
 | 
					        demo_caption_animations,
 | 
				
			||||||
 | 
					        demo_easing_showcase,
 | 
				
			||||||
 | 
					        demo_performance_stress_test
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if current_demo < len(demos):
 | 
				
			||||||
 | 
					        # Run current demo
 | 
				
			||||||
 | 
					        demos[current_demo]()
 | 
				
			||||||
 | 
					        current_demo += 1
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Schedule next demo
 | 
				
			||||||
 | 
					        if current_demo < len(demos):
 | 
				
			||||||
 | 
					            mcrfpy.setTimer("next_demo", run_demo_sequence, int(DEMO_DURATION * 1000))
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            # Final demo completed
 | 
				
			||||||
 | 
					            def show_complete(rt):
 | 
				
			||||||
 | 
					                subtitle.text = "Animation Showcase Complete!"
 | 
				
			||||||
 | 
					                complete = mcrfpy.Caption("All animation types demonstrated!", 400, 350)
 | 
				
			||||||
 | 
					                complete.fill_color = mcrfpy.Color(0, 255, 0)
 | 
				
			||||||
 | 
					                complete.outline = 2
 | 
				
			||||||
 | 
					                ui = mcrfpy.sceneUI("sizzle_reel")
 | 
				
			||||||
 | 
					                ui.append(complete)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            mcrfpy.setTimer("complete", show_complete, 3000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Initialize scene
 | 
				
			||||||
 | 
					print("Starting McRogueFace Animation Sizzle Reel v2...")
 | 
				
			||||||
 | 
					print("This will demonstrate animation types on various objects.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ui = create_demo_scene()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Start the demo sequence after a short delay
 | 
				
			||||||
 | 
					mcrfpy.setTimer("start_demos", run_demo_sequence, 500)
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,318 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					McRogueFace Animation Sizzle Reel - Working Version
 | 
				
			||||||
 | 
					===================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Complete demonstration of all animation capabilities.
 | 
				
			||||||
 | 
					Fixed to work properly with the API.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import mcrfpy
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import math
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Configuration
 | 
				
			||||||
 | 
					DEMO_DURATION = 7.0  # Duration for each demo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# All available easing functions
 | 
				
			||||||
 | 
					EASING_FUNCTIONS = [
 | 
				
			||||||
 | 
					    "linear", "easeIn", "easeOut", "easeInOut",
 | 
				
			||||||
 | 
					    "easeInQuad", "easeOutQuad", "easeInOutQuad",
 | 
				
			||||||
 | 
					    "easeInCubic", "easeOutCubic", "easeInOutCubic",
 | 
				
			||||||
 | 
					    "easeInQuart", "easeOutQuart", "easeInOutQuart",
 | 
				
			||||||
 | 
					    "easeInSine", "easeOutSine", "easeInOutSine",
 | 
				
			||||||
 | 
					    "easeInExpo", "easeOutExpo", "easeInOutExpo",
 | 
				
			||||||
 | 
					    "easeInCirc", "easeOutCirc", "easeInOutCirc",
 | 
				
			||||||
 | 
					    "easeInElastic", "easeOutElastic", "easeInOutElastic",
 | 
				
			||||||
 | 
					    "easeInBack", "easeOutBack", "easeInOutBack",
 | 
				
			||||||
 | 
					    "easeInBounce", "easeOutBounce", "easeInOutBounce"
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Track state
 | 
				
			||||||
 | 
					current_demo = 0
 | 
				
			||||||
 | 
					subtitle = None
 | 
				
			||||||
 | 
					demo_objects = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def create_scene():
 | 
				
			||||||
 | 
					    """Create the demo scene with title"""
 | 
				
			||||||
 | 
					    mcrfpy.createScene("sizzle")
 | 
				
			||||||
 | 
					    mcrfpy.setScene("sizzle")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Title
 | 
				
			||||||
 | 
					    title = mcrfpy.Caption("McRogueFace Animation Sizzle Reel", 340, 20)
 | 
				
			||||||
 | 
					    title.fill_color = mcrfpy.Color(255, 255, 0)
 | 
				
			||||||
 | 
					    title.outline = 2
 | 
				
			||||||
 | 
					    title.outline_color = mcrfpy.Color(0, 0, 0)
 | 
				
			||||||
 | 
					    ui.append(title)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Subtitle
 | 
				
			||||||
 | 
					    global subtitle
 | 
				
			||||||
 | 
					    subtitle = mcrfpy.Caption("Initializing...", 400, 60)
 | 
				
			||||||
 | 
					    subtitle.fill_color = mcrfpy.Color(200, 200, 200)
 | 
				
			||||||
 | 
					    ui.append(subtitle)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def clear_demo():
 | 
				
			||||||
 | 
					    """Clear demo objects"""
 | 
				
			||||||
 | 
					    global demo_objects
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Remove items starting from the end
 | 
				
			||||||
 | 
					    # Skip first 2 (title and subtitle)
 | 
				
			||||||
 | 
					    while len(ui) > 2:
 | 
				
			||||||
 | 
					        ui.remove(len(ui) - 1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    demo_objects = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo1_frame_basics():
 | 
				
			||||||
 | 
					    """Demo 1: Basic frame animations"""
 | 
				
			||||||
 | 
					    clear_demo()
 | 
				
			||||||
 | 
					    print("demo1")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 1: Frame Animations (Position, Size, Color)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create frame
 | 
				
			||||||
 | 
					    frame = mcrfpy.Frame(100, 150, 200, 100)
 | 
				
			||||||
 | 
					    frame.fill_color = mcrfpy.Color(50, 50, 150)
 | 
				
			||||||
 | 
					    frame.outline = 3
 | 
				
			||||||
 | 
					    frame.outline_color = mcrfpy.Color(255, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Animate properties
 | 
				
			||||||
 | 
					    mcrfpy.Animation("x", 700.0, 2.5, "easeInOutBack").start(frame)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("y", 350.0, 2.5, "easeInOutElastic").start(frame)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("w", 350.0, 3.0, "easeInOutCubic").start(frame)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("h", 180.0, 3.0, "easeInOutCubic").start(frame)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("fill_color", (255, 100, 50, 200), 4.0, "easeInOutSine").start(frame)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("outline_color", (0, 255, 255, 255), 4.0, "easeOutBounce").start(frame)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("outline", 8.0, 4.0, "easeInOutQuad").start(frame)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo2_opacity_zindex():
 | 
				
			||||||
 | 
					    """Demo 2: Opacity and z-index animations"""
 | 
				
			||||||
 | 
					    clear_demo()
 | 
				
			||||||
 | 
					    print("demo2")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 2: Opacity & Z-Index Animations"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create overlapping frames
 | 
				
			||||||
 | 
					    colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0)]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for i in range(4):
 | 
				
			||||||
 | 
					        frame = mcrfpy.Frame(200 + i*80, 200 + i*40, 200, 150)
 | 
				
			||||||
 | 
					        frame.fill_color = mcrfpy.Color(colors[i][0], colors[i][1], colors[i][2], 200)
 | 
				
			||||||
 | 
					        frame.outline = 2
 | 
				
			||||||
 | 
					        frame.z_index = i
 | 
				
			||||||
 | 
					        ui.append(frame)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Animate opacity
 | 
				
			||||||
 | 
					        mcrfpy.Animation("opacity", 0.3, 2.0, "easeInOutSine").start(frame)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    # Schedule opacity return
 | 
				
			||||||
 | 
					    def return_opacity(rt):
 | 
				
			||||||
 | 
					        for i in range(4):
 | 
				
			||||||
 | 
					            mcrfpy.Animation("opacity", 1.0, 2.0, "easeInOutSine").start(ui[i])
 | 
				
			||||||
 | 
					    mcrfpy.setTimer(f"opacity_{i}", return_opacity, 2100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo3_captions():
 | 
				
			||||||
 | 
					    """Demo 3: Caption animations"""
 | 
				
			||||||
 | 
					    clear_demo()
 | 
				
			||||||
 | 
					    print("demo3")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 3: Caption Animations"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Moving caption
 | 
				
			||||||
 | 
					    c1 = mcrfpy.Caption("Bouncing Text!", 100, 200)
 | 
				
			||||||
 | 
					    c1.fill_color = mcrfpy.Color(255, 255, 255)
 | 
				
			||||||
 | 
					    c1.outline = 1
 | 
				
			||||||
 | 
					    ui.append(c1)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("x", 800.0, 3.0, "easeOutBounce").start(c1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Color cycling caption
 | 
				
			||||||
 | 
					    c2 = mcrfpy.Caption("Color Cycle", 400, 300)
 | 
				
			||||||
 | 
					    c2.outline = 2
 | 
				
			||||||
 | 
					    ui.append(c2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Animate through colors
 | 
				
			||||||
 | 
					    def cycle_colors():
 | 
				
			||||||
 | 
					        anim = mcrfpy.Animation("fill_color", (255, 0, 0, 255), 0.5, "linear")
 | 
				
			||||||
 | 
					        anim.start(c2)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        def to_green(rt):
 | 
				
			||||||
 | 
					            mcrfpy.Animation("fill_color", (0, 255, 0, 255), 0.5, "linear").start(c2)
 | 
				
			||||||
 | 
					        def to_blue(rt):
 | 
				
			||||||
 | 
					            mcrfpy.Animation("fill_color", (0, 0, 255, 255), 0.5, "linear").start(c2)
 | 
				
			||||||
 | 
					        def to_white(rt):
 | 
				
			||||||
 | 
					            mcrfpy.Animation("fill_color", (255, 255, 255, 255), 0.5, "linear").start(c2)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        mcrfpy.setTimer("c_green", to_green, 600)
 | 
				
			||||||
 | 
					        mcrfpy.setTimer("c_blue", to_blue, 1200)
 | 
				
			||||||
 | 
					        mcrfpy.setTimer("c_white", to_white, 1800)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    cycle_colors()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Typewriter effect
 | 
				
			||||||
 | 
					    c3 = mcrfpy.Caption("", 100, 400)
 | 
				
			||||||
 | 
					    c3.fill_color = mcrfpy.Color(0, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(c3)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("text", "This text appears one character at a time...", 3.0, "linear").start(c3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo4_easing_showcase():
 | 
				
			||||||
 | 
					    """Demo 4: Showcase easing functions"""
 | 
				
			||||||
 | 
					    clear_demo()
 | 
				
			||||||
 | 
					    print("demo4")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 4: 30 Easing Functions"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Show first 15 easings
 | 
				
			||||||
 | 
					    for i in range(15):
 | 
				
			||||||
 | 
					        row = i // 5
 | 
				
			||||||
 | 
					        col = i % 5
 | 
				
			||||||
 | 
					        x = 80 + col * 180
 | 
				
			||||||
 | 
					        y = 150 + row * 120
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Create frame
 | 
				
			||||||
 | 
					        f = mcrfpy.Frame(x, y, 20, 20)
 | 
				
			||||||
 | 
					        f.fill_color = mcrfpy.Color(100, 150, 255)
 | 
				
			||||||
 | 
					        f.outline = 1
 | 
				
			||||||
 | 
					        ui.append(f)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Label
 | 
				
			||||||
 | 
					        label = mcrfpy.Caption(EASING_FUNCTIONS[i][:10], x, y - 20)
 | 
				
			||||||
 | 
					        label.fill_color = mcrfpy.Color(200, 200, 200)
 | 
				
			||||||
 | 
					        ui.append(label)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Animate with this easing
 | 
				
			||||||
 | 
					        mcrfpy.Animation("x", float(x + 140), 3.0, EASING_FUNCTIONS[i]).start(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo5_performance():
 | 
				
			||||||
 | 
					    """Demo 5: Many simultaneous animations"""
 | 
				
			||||||
 | 
					    clear_demo()
 | 
				
			||||||
 | 
					    print("demo5")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 5: 50+ Simultaneous Animations"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create many animated objects
 | 
				
			||||||
 | 
					    for i in range(50):
 | 
				
			||||||
 | 
					        print(f"{i}...",end='',flush=True)
 | 
				
			||||||
 | 
					        x = 100 + (i % 10) * 90
 | 
				
			||||||
 | 
					        y = 120 + (i // 10) * 80
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        f = mcrfpy.Frame(x, y, 25, 25)
 | 
				
			||||||
 | 
					        r = (i * 37) % 256
 | 
				
			||||||
 | 
					        g = (i * 73) % 256
 | 
				
			||||||
 | 
					        b = (i * 113) % 256
 | 
				
			||||||
 | 
					        f.fill_color = (r, g, b, 200) #mcrfpy.Color(r, g, b, 200)
 | 
				
			||||||
 | 
					        f.outline = 1
 | 
				
			||||||
 | 
					        ui.append(f)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Random animations
 | 
				
			||||||
 | 
					        target_x = 150 + (i % 8) * 100
 | 
				
			||||||
 | 
					        target_y = 150 + (i // 8) * 85
 | 
				
			||||||
 | 
					        duration = 2.0 + (i % 30) * 0.1
 | 
				
			||||||
 | 
					        easing = EASING_FUNCTIONS[i % len(EASING_FUNCTIONS)]
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        mcrfpy.Animation("x", float(target_x), duration, easing).start(f)
 | 
				
			||||||
 | 
					        mcrfpy.Animation("y", float(target_y), duration, easing).start(f)
 | 
				
			||||||
 | 
					        mcrfpy.Animation("opacity", 0.3 + (i % 7) * 0.1, 2.5, "easeInOutSine").start(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo6_delta_mode():
 | 
				
			||||||
 | 
					    """Demo 6: Delta mode animations"""
 | 
				
			||||||
 | 
					    clear_demo()
 | 
				
			||||||
 | 
					    print("demo6")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 6: Delta Mode (Relative Movement)"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("sizzle")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create frames that move relative to position
 | 
				
			||||||
 | 
					    positions = [(100, 300), (300, 300), (500, 300), (700, 300)]
 | 
				
			||||||
 | 
					    colors = [(255, 100, 100), (100, 255, 100), (100, 100, 255), (255, 255, 100)]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for i, ((x, y), color) in enumerate(zip(positions, colors)):
 | 
				
			||||||
 | 
					        f = mcrfpy.Frame(x, y, 60, 60)
 | 
				
			||||||
 | 
					        f.fill_color = mcrfpy.Color(color[0], color[1], color[2])
 | 
				
			||||||
 | 
					        f.outline = 2
 | 
				
			||||||
 | 
					        ui.append(f)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Delta animations - move by amount, not to position
 | 
				
			||||||
 | 
					        dx = (i + 1) * 30
 | 
				
			||||||
 | 
					        dy = math.sin(i * 0.5) * 50
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        mcrfpy.Animation("x", float(dx), 2.0, "easeInOutBack", delta=True).start(f)
 | 
				
			||||||
 | 
					        mcrfpy.Animation("y", float(dy), 2.0, "easeInOutElastic", delta=True).start(f)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Caption explaining delta mode
 | 
				
			||||||
 | 
					    info = mcrfpy.Caption("Delta mode: animations move BY amount, not TO position", 200, 450)
 | 
				
			||||||
 | 
					    info.fill_color = mcrfpy.Color(255, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def run_next_demo(runtime):
 | 
				
			||||||
 | 
					    """Run the next demo in sequence"""
 | 
				
			||||||
 | 
					    global current_demo
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    demos = [
 | 
				
			||||||
 | 
					        demo1_frame_basics,
 | 
				
			||||||
 | 
					        demo2_opacity_zindex,
 | 
				
			||||||
 | 
					        demo3_captions,
 | 
				
			||||||
 | 
					        demo4_easing_showcase,
 | 
				
			||||||
 | 
					        demo5_performance,
 | 
				
			||||||
 | 
					        demo6_delta_mode
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if current_demo < len(demos):
 | 
				
			||||||
 | 
					        # Clean up timers from previous demo
 | 
				
			||||||
 | 
					        for timer in ["opacity_0", "opacity_1", "opacity_2", "opacity_3", 
 | 
				
			||||||
 | 
					                      "c_green", "c_blue", "c_white"]:
 | 
				
			||||||
 | 
					            if not mcrfpy.getTimer(timer):
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                mcrfpy.delTimer(timer)
 | 
				
			||||||
 | 
					            except:
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Run next demo
 | 
				
			||||||
 | 
					        print(f"Run next: {current_demo}")
 | 
				
			||||||
 | 
					        demos[current_demo]()
 | 
				
			||||||
 | 
					        current_demo += 1
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Schedule next demo
 | 
				
			||||||
 | 
					        if current_demo < len(demos):
 | 
				
			||||||
 | 
					            #mcrfpy.setTimer("next_demo", run_next_demo, int(DEMO_DURATION * 1000))
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            current_demo = 0
 | 
				
			||||||
 | 
					            # All done
 | 
				
			||||||
 | 
					            #subtitle.text = "Animation Showcase Complete!"
 | 
				
			||||||
 | 
					            #complete = mcrfpy.Caption("All animations demonstrated successfully!", 350, 350)
 | 
				
			||||||
 | 
					            #complete.fill_color = mcrfpy.Color(0, 255, 0)
 | 
				
			||||||
 | 
					            #complete.outline = 2
 | 
				
			||||||
 | 
					            #ui = mcrfpy.sceneUI("sizzle")
 | 
				
			||||||
 | 
					            #ui.append(complete)
 | 
				
			||||||
 | 
					            #
 | 
				
			||||||
 | 
					            ## Exit after delay
 | 
				
			||||||
 | 
					            #def exit_program(rt):
 | 
				
			||||||
 | 
					            #    print("\nSizzle reel completed successfully!")
 | 
				
			||||||
 | 
					            #    sys.exit(0)
 | 
				
			||||||
 | 
					            #mcrfpy.setTimer("exit", exit_program, 3000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Handle ESC key
 | 
				
			||||||
 | 
					def handle_keypress(scene_name, keycode):
 | 
				
			||||||
 | 
					    if keycode == 256:  # ESC
 | 
				
			||||||
 | 
					        print("\nExiting...")
 | 
				
			||||||
 | 
					        sys.exit(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Initialize
 | 
				
			||||||
 | 
					print("Starting McRogueFace Animation Sizzle Reel...")
 | 
				
			||||||
 | 
					print("This demonstrates all animation capabilities.")
 | 
				
			||||||
 | 
					print("Press ESC to exit at any time.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					create_scene()
 | 
				
			||||||
 | 
					mcrfpy.keypressScene(handle_keypress)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Start the show
 | 
				
			||||||
 | 
					mcrfpy.setTimer("start", run_next_demo, int(DEMO_DURATION * 1000))
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,207 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					McRogueFace API Demo - Final Version
 | 
				
			||||||
 | 
					====================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Complete API demonstration with proper error handling.
 | 
				
			||||||
 | 
					Tests all constructors and methods systematically.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import mcrfpy
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def print_section(title):
 | 
				
			||||||
 | 
					    """Print a section header"""
 | 
				
			||||||
 | 
					    print("\n" + "="*60)
 | 
				
			||||||
 | 
					    print(f"  {title}")
 | 
				
			||||||
 | 
					    print("="*60)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def print_test(name, success=True):
 | 
				
			||||||
 | 
					    """Print test result"""
 | 
				
			||||||
 | 
					    status = "✓" if success else "✗"
 | 
				
			||||||
 | 
					    print(f"  {status} {name}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_colors():
 | 
				
			||||||
 | 
					    """Test Color API"""
 | 
				
			||||||
 | 
					    print_section("COLOR TESTS")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        # Basic constructors
 | 
				
			||||||
 | 
					        c1 = mcrfpy.Color(255, 0, 0)  # RGB
 | 
				
			||||||
 | 
					        print_test(f"Color(255,0,0) = ({c1.r},{c1.g},{c1.b},{c1.a})")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        c2 = mcrfpy.Color(100, 150, 200, 128)  # RGBA
 | 
				
			||||||
 | 
					        print_test(f"Color(100,150,200,128) = ({c2.r},{c2.g},{c2.b},{c2.a})")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Property modification
 | 
				
			||||||
 | 
					        c1.r = 128
 | 
				
			||||||
 | 
					        c1.g = 128
 | 
				
			||||||
 | 
					        c1.b = 128
 | 
				
			||||||
 | 
					        c1.a = 200
 | 
				
			||||||
 | 
					        print_test(f"Modified color = ({c1.r},{c1.g},{c1.b},{c1.a})")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        print_test(f"Color test failed: {e}", False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_frames():
 | 
				
			||||||
 | 
					    """Test Frame API"""
 | 
				
			||||||
 | 
					    print_section("FRAME TESTS")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create scene
 | 
				
			||||||
 | 
					    mcrfpy.createScene("test")
 | 
				
			||||||
 | 
					    mcrfpy.setScene("test")
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("test")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        # Constructors
 | 
				
			||||||
 | 
					        f1 = mcrfpy.Frame()
 | 
				
			||||||
 | 
					        print_test(f"Frame() at ({f1.x},{f1.y}) size ({f1.w},{f1.h})")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        f2 = mcrfpy.Frame(100, 50)
 | 
				
			||||||
 | 
					        print_test(f"Frame(100,50) at ({f2.x},{f2.y})")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        f3 = mcrfpy.Frame(200, 100, 150, 75)
 | 
				
			||||||
 | 
					        print_test(f"Frame(200,100,150,75) size ({f3.w},{f3.h})")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Properties
 | 
				
			||||||
 | 
					        f3.fill_color = mcrfpy.Color(100, 100, 200)
 | 
				
			||||||
 | 
					        f3.outline = 3
 | 
				
			||||||
 | 
					        f3.outline_color = mcrfpy.Color(255, 255, 0)
 | 
				
			||||||
 | 
					        f3.opacity = 0.8
 | 
				
			||||||
 | 
					        f3.visible = True
 | 
				
			||||||
 | 
					        f3.z_index = 5
 | 
				
			||||||
 | 
					        print_test(f"Frame properties set")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Add to scene
 | 
				
			||||||
 | 
					        ui.append(f3)
 | 
				
			||||||
 | 
					        print_test(f"Frame added to scene")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Children
 | 
				
			||||||
 | 
					        child = mcrfpy.Frame(10, 10, 50, 50)
 | 
				
			||||||
 | 
					        f3.children.append(child)
 | 
				
			||||||
 | 
					        print_test(f"Child added, count = {len(f3.children)}")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        print_test(f"Frame test failed: {e}", False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_captions():
 | 
				
			||||||
 | 
					    """Test Caption API"""
 | 
				
			||||||
 | 
					    print_section("CAPTION TESTS")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("test")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        # Constructors
 | 
				
			||||||
 | 
					        c1 = mcrfpy.Caption()
 | 
				
			||||||
 | 
					        print_test(f"Caption() text='{c1.text}'")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        c2 = mcrfpy.Caption("Hello World")
 | 
				
			||||||
 | 
					        print_test(f"Caption('Hello World') at ({c2.x},{c2.y})")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        c3 = mcrfpy.Caption("Test", 300, 200)
 | 
				
			||||||
 | 
					        print_test(f"Caption with position at ({c3.x},{c3.y})")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Properties
 | 
				
			||||||
 | 
					        c3.text = "Modified"
 | 
				
			||||||
 | 
					        c3.fill_color = mcrfpy.Color(255, 255, 0)
 | 
				
			||||||
 | 
					        c3.outline = 2
 | 
				
			||||||
 | 
					        c3.outline_color = mcrfpy.Color(0, 0, 0)
 | 
				
			||||||
 | 
					        print_test(f"Caption text='{c3.text}'")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        ui.append(c3)
 | 
				
			||||||
 | 
					        print_test("Caption added to scene")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        print_test(f"Caption test failed: {e}", False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_animations():
 | 
				
			||||||
 | 
					    """Test Animation API"""
 | 
				
			||||||
 | 
					    print_section("ANIMATION TESTS")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("test")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        # Create target
 | 
				
			||||||
 | 
					        frame = mcrfpy.Frame(50, 50, 100, 100)
 | 
				
			||||||
 | 
					        frame.fill_color = mcrfpy.Color(100, 100, 100)
 | 
				
			||||||
 | 
					        ui.append(frame)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Basic animations
 | 
				
			||||||
 | 
					        a1 = mcrfpy.Animation("x", 300.0, 2.0)
 | 
				
			||||||
 | 
					        print_test("Animation created (position)")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        a2 = mcrfpy.Animation("opacity", 0.5, 1.5, "easeInOut")
 | 
				
			||||||
 | 
					        print_test("Animation with easing")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        a3 = mcrfpy.Animation("fill_color", (255, 0, 0, 255), 2.0)
 | 
				
			||||||
 | 
					        print_test("Color animation (tuple)")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Start animations
 | 
				
			||||||
 | 
					        a1.start(frame)
 | 
				
			||||||
 | 
					        a2.start(frame)
 | 
				
			||||||
 | 
					        a3.start(frame)
 | 
				
			||||||
 | 
					        print_test("Animations started")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Check properties
 | 
				
			||||||
 | 
					        print_test(f"Duration = {a1.duration}")
 | 
				
			||||||
 | 
					        print_test(f"Elapsed = {a1.elapsed}")
 | 
				
			||||||
 | 
					        print_test(f"Complete = {a1.is_complete}")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        print_test(f"Animation test failed: {e}", False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_collections():
 | 
				
			||||||
 | 
					    """Test collection operations"""
 | 
				
			||||||
 | 
					    print_section("COLLECTION TESTS")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("test")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        # Clear scene
 | 
				
			||||||
 | 
					        while len(ui) > 0:
 | 
				
			||||||
 | 
					            ui.remove(ui[len(ui)-1])
 | 
				
			||||||
 | 
					        print_test(f"Scene cleared, length = {len(ui)}")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Add items
 | 
				
			||||||
 | 
					        for i in range(5):
 | 
				
			||||||
 | 
					            f = mcrfpy.Frame(i*100, 50, 80, 80)
 | 
				
			||||||
 | 
					            ui.append(f)
 | 
				
			||||||
 | 
					        print_test(f"Added 5 frames, length = {len(ui)}")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Access
 | 
				
			||||||
 | 
					        first = ui[0]
 | 
				
			||||||
 | 
					        print_test(f"Accessed ui[0] at ({first.x},{first.y})")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Iteration
 | 
				
			||||||
 | 
					        count = sum(1 for _ in ui)
 | 
				
			||||||
 | 
					        print_test(f"Iteration count = {count}")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        print_test(f"Collection test failed: {e}", False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def run_tests():
 | 
				
			||||||
 | 
					    """Run all tests"""
 | 
				
			||||||
 | 
					    print("\n" + "="*60)
 | 
				
			||||||
 | 
					    print("  McRogueFace API Test Suite")
 | 
				
			||||||
 | 
					    print("="*60)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    test_colors()
 | 
				
			||||||
 | 
					    test_frames()
 | 
				
			||||||
 | 
					    test_captions()
 | 
				
			||||||
 | 
					    test_animations()
 | 
				
			||||||
 | 
					    test_collections()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    print("\n" + "="*60)
 | 
				
			||||||
 | 
					    print("  Tests Complete")
 | 
				
			||||||
 | 
					    print("="*60)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Exit after delay
 | 
				
			||||||
 | 
					    def exit_program(runtime):
 | 
				
			||||||
 | 
					        print("\nExiting...")
 | 
				
			||||||
 | 
					        sys.exit(0)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    mcrfpy.setTimer("exit", exit_program, 3000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run tests
 | 
				
			||||||
 | 
					print("Starting API tests...")
 | 
				
			||||||
 | 
					run_tests()
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
					@ -0,0 +1,306 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					McRogueFace Exhaustive API Demo (Fixed)
 | 
				
			||||||
 | 
					=======================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixed version that properly exits after tests complete.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import mcrfpy
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Test configuration
 | 
				
			||||||
 | 
					VERBOSE = True  # Print detailed information about each test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def print_section(title):
 | 
				
			||||||
 | 
					    """Print a section header"""
 | 
				
			||||||
 | 
					    print("\n" + "="*60)
 | 
				
			||||||
 | 
					    print(f"  {title}")
 | 
				
			||||||
 | 
					    print("="*60)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def print_test(test_name, success=True):
 | 
				
			||||||
 | 
					    """Print test result"""
 | 
				
			||||||
 | 
					    status = "✓ PASS" if success else "✗ FAIL"
 | 
				
			||||||
 | 
					    print(f"  {status} - {test_name}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_color_api():
 | 
				
			||||||
 | 
					    """Test all Color constructors and methods"""
 | 
				
			||||||
 | 
					    print_section("COLOR API TESTS")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Constructor variants
 | 
				
			||||||
 | 
					    print("\n  Constructors:")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Empty constructor (defaults to white)
 | 
				
			||||||
 | 
					    c1 = mcrfpy.Color()
 | 
				
			||||||
 | 
					    print_test(f"Color() = ({c1.r}, {c1.g}, {c1.b}, {c1.a})")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Single value (grayscale)
 | 
				
			||||||
 | 
					    c2 = mcrfpy.Color(128)
 | 
				
			||||||
 | 
					    print_test(f"Color(128) = ({c2.r}, {c2.g}, {c2.b}, {c2.a})")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # RGB only (alpha defaults to 255)
 | 
				
			||||||
 | 
					    c3 = mcrfpy.Color(255, 128, 0)
 | 
				
			||||||
 | 
					    print_test(f"Color(255, 128, 0) = ({c3.r}, {c3.g}, {c3.b}, {c3.a})")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Full RGBA
 | 
				
			||||||
 | 
					    c4 = mcrfpy.Color(100, 150, 200, 128)
 | 
				
			||||||
 | 
					    print_test(f"Color(100, 150, 200, 128) = ({c4.r}, {c4.g}, {c4.b}, {c4.a})")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Property access
 | 
				
			||||||
 | 
					    print("\n  Properties:")
 | 
				
			||||||
 | 
					    c = mcrfpy.Color(10, 20, 30, 40)
 | 
				
			||||||
 | 
					    print_test(f"Initial: r={c.r}, g={c.g}, b={c.b}, a={c.a}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    c.r = 200
 | 
				
			||||||
 | 
					    c.g = 150
 | 
				
			||||||
 | 
					    c.b = 100
 | 
				
			||||||
 | 
					    c.a = 255
 | 
				
			||||||
 | 
					    print_test(f"After modification: r={c.r}, g={c.g}, b={c.b}, a={c.a}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_frame_api():
 | 
				
			||||||
 | 
					    """Test all Frame constructors and methods"""
 | 
				
			||||||
 | 
					    print_section("FRAME API TESTS")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create a test scene
 | 
				
			||||||
 | 
					    mcrfpy.createScene("api_test")
 | 
				
			||||||
 | 
					    mcrfpy.setScene("api_test")
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("api_test")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Constructor variants
 | 
				
			||||||
 | 
					    print("\n  Constructors:")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Empty constructor
 | 
				
			||||||
 | 
					    f1 = mcrfpy.Frame()
 | 
				
			||||||
 | 
					    print_test(f"Frame() - pos=({f1.x}, {f1.y}), size=({f1.w}, {f1.h})")
 | 
				
			||||||
 | 
					    ui.append(f1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Position only
 | 
				
			||||||
 | 
					    f2 = mcrfpy.Frame(100, 50)
 | 
				
			||||||
 | 
					    print_test(f"Frame(100, 50) - pos=({f2.x}, {f2.y}), size=({f2.w}, {f2.h})")
 | 
				
			||||||
 | 
					    ui.append(f2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Position and size
 | 
				
			||||||
 | 
					    f3 = mcrfpy.Frame(200, 100, 150, 75)
 | 
				
			||||||
 | 
					    print_test(f"Frame(200, 100, 150, 75) - pos=({f3.x}, {f3.y}), size=({f3.w}, {f3.h})")
 | 
				
			||||||
 | 
					    ui.append(f3)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Full constructor
 | 
				
			||||||
 | 
					    f4 = mcrfpy.Frame(300, 200, 200, 100, 
 | 
				
			||||||
 | 
					                      fill_color=mcrfpy.Color(100, 100, 200),
 | 
				
			||||||
 | 
					                      outline_color=mcrfpy.Color(255, 255, 0),
 | 
				
			||||||
 | 
					                      outline=3)
 | 
				
			||||||
 | 
					    print_test("Frame with all parameters")
 | 
				
			||||||
 | 
					    ui.append(f4)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Properties
 | 
				
			||||||
 | 
					    print("\n  Properties:")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Position and size
 | 
				
			||||||
 | 
					    f = mcrfpy.Frame(10, 20, 30, 40)
 | 
				
			||||||
 | 
					    print_test(f"Initial: x={f.x}, y={f.y}, w={f.w}, h={f.h}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    f.x = 50
 | 
				
			||||||
 | 
					    f.y = 60
 | 
				
			||||||
 | 
					    f.w = 70
 | 
				
			||||||
 | 
					    f.h = 80
 | 
				
			||||||
 | 
					    print_test(f"Modified: x={f.x}, y={f.y}, w={f.w}, h={f.h}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Colors
 | 
				
			||||||
 | 
					    f.fill_color = mcrfpy.Color(255, 0, 0, 128)
 | 
				
			||||||
 | 
					    f.outline_color = mcrfpy.Color(0, 255, 0)
 | 
				
			||||||
 | 
					    f.outline = 5.0
 | 
				
			||||||
 | 
					    print_test(f"Colors set, outline={f.outline}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Visibility and opacity
 | 
				
			||||||
 | 
					    f.visible = False
 | 
				
			||||||
 | 
					    f.opacity = 0.5
 | 
				
			||||||
 | 
					    print_test(f"visible={f.visible}, opacity={f.opacity}")
 | 
				
			||||||
 | 
					    f.visible = True  # Reset
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Z-index
 | 
				
			||||||
 | 
					    f.z_index = 10
 | 
				
			||||||
 | 
					    print_test(f"z_index={f.z_index}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Children collection
 | 
				
			||||||
 | 
					    child1 = mcrfpy.Frame(5, 5, 20, 20)
 | 
				
			||||||
 | 
					    child2 = mcrfpy.Frame(30, 5, 20, 20)
 | 
				
			||||||
 | 
					    f.children.append(child1)
 | 
				
			||||||
 | 
					    f.children.append(child2)
 | 
				
			||||||
 | 
					    print_test(f"children.count = {len(f.children)}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_caption_api():
 | 
				
			||||||
 | 
					    """Test all Caption constructors and methods"""
 | 
				
			||||||
 | 
					    print_section("CAPTION API TESTS")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("api_test")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Constructor variants
 | 
				
			||||||
 | 
					    print("\n  Constructors:")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Empty constructor
 | 
				
			||||||
 | 
					    c1 = mcrfpy.Caption()
 | 
				
			||||||
 | 
					    print_test(f"Caption() - text='{c1.text}', pos=({c1.x}, {c1.y})")
 | 
				
			||||||
 | 
					    ui.append(c1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Text only
 | 
				
			||||||
 | 
					    c2 = mcrfpy.Caption("Hello World")
 | 
				
			||||||
 | 
					    print_test(f"Caption('Hello World') - pos=({c2.x}, {c2.y})")
 | 
				
			||||||
 | 
					    ui.append(c2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Text and position
 | 
				
			||||||
 | 
					    c3 = mcrfpy.Caption("Positioned Text", 100, 50)
 | 
				
			||||||
 | 
					    print_test(f"Caption('Positioned Text', 100, 50)")
 | 
				
			||||||
 | 
					    ui.append(c3)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Full constructor
 | 
				
			||||||
 | 
					    c5 = mcrfpy.Caption("Styled Text", 300, 150,
 | 
				
			||||||
 | 
					                        fill_color=mcrfpy.Color(255, 255, 0),
 | 
				
			||||||
 | 
					                        outline_color=mcrfpy.Color(255, 0, 0),
 | 
				
			||||||
 | 
					                        outline=2)
 | 
				
			||||||
 | 
					    print_test("Caption with all style parameters")
 | 
				
			||||||
 | 
					    ui.append(c5)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Properties
 | 
				
			||||||
 | 
					    print("\n  Properties:")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    c = mcrfpy.Caption("Test Caption", 10, 20)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Text
 | 
				
			||||||
 | 
					    c.text = "Modified Text"
 | 
				
			||||||
 | 
					    print_test(f"text = '{c.text}'")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Position
 | 
				
			||||||
 | 
					    c.x = 50
 | 
				
			||||||
 | 
					    c.y = 60
 | 
				
			||||||
 | 
					    print_test(f"position = ({c.x}, {c.y})")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Colors and style
 | 
				
			||||||
 | 
					    c.fill_color = mcrfpy.Color(0, 255, 255)
 | 
				
			||||||
 | 
					    c.outline_color = mcrfpy.Color(255, 0, 255)
 | 
				
			||||||
 | 
					    c.outline = 3.0
 | 
				
			||||||
 | 
					    print_test("Colors and outline set")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Size (read-only, computed from text)
 | 
				
			||||||
 | 
					    print_test(f"size (computed) = ({c.w}, {c.h})")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_animation_api():
 | 
				
			||||||
 | 
					    """Test Animation class API"""
 | 
				
			||||||
 | 
					    print_section("ANIMATION API TESTS")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("api_test")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    print("\n  Animation Constructors:")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Basic animation
 | 
				
			||||||
 | 
					    anim1 = mcrfpy.Animation("x", 100.0, 2.0)
 | 
				
			||||||
 | 
					    print_test("Animation('x', 100.0, 2.0)")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # With easing
 | 
				
			||||||
 | 
					    anim2 = mcrfpy.Animation("y", 200.0, 3.0, "easeInOut")
 | 
				
			||||||
 | 
					    print_test("Animation with easing='easeInOut'")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Delta mode
 | 
				
			||||||
 | 
					    anim3 = mcrfpy.Animation("w", 50.0, 1.5, "linear", delta=True)
 | 
				
			||||||
 | 
					    print_test("Animation with delta=True")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Color animation (as tuple)
 | 
				
			||||||
 | 
					    anim4 = mcrfpy.Animation("fill_color", (255, 0, 0, 255), 2.0)
 | 
				
			||||||
 | 
					    print_test("Animation with Color tuple target")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Vector animation
 | 
				
			||||||
 | 
					    anim5 = mcrfpy.Animation("position", (10.0, 20.0), 2.5, "easeOutBounce")
 | 
				
			||||||
 | 
					    print_test("Animation with position tuple")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Sprite sequence
 | 
				
			||||||
 | 
					    anim6 = mcrfpy.Animation("sprite_index", [0, 1, 2, 3, 2, 1], 2.0)
 | 
				
			||||||
 | 
					    print_test("Animation with sprite sequence")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Properties
 | 
				
			||||||
 | 
					    print("\n  Animation Properties:")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Check properties
 | 
				
			||||||
 | 
					    print_test(f"property = '{anim1.property}'")
 | 
				
			||||||
 | 
					    print_test(f"duration = {anim1.duration}")
 | 
				
			||||||
 | 
					    print_test(f"elapsed = {anim1.elapsed}")
 | 
				
			||||||
 | 
					    print_test(f"is_complete = {anim1.is_complete}")
 | 
				
			||||||
 | 
					    print_test(f"is_delta = {anim3.is_delta}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Methods
 | 
				
			||||||
 | 
					    print("\n  Animation Methods:")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create test frame
 | 
				
			||||||
 | 
					    frame = mcrfpy.Frame(50, 50, 100, 100)
 | 
				
			||||||
 | 
					    frame.fill_color = mcrfpy.Color(100, 100, 100)
 | 
				
			||||||
 | 
					    ui.append(frame)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Start animation
 | 
				
			||||||
 | 
					    anim1.start(frame)
 | 
				
			||||||
 | 
					    print_test("start() called on frame")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Test some easing functions
 | 
				
			||||||
 | 
					    print("\n  Sample Easing Functions:")
 | 
				
			||||||
 | 
					    easings = ["linear", "easeIn", "easeOut", "easeInOut", "easeInBounce", "easeOutElastic"]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for easing in easings:
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            test_anim = mcrfpy.Animation("x", 100.0, 1.0, easing)
 | 
				
			||||||
 | 
					            print_test(f"Easing '{easing}' ✓")
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            print_test(f"Easing '{easing}' failed", False)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def run_all_tests():
 | 
				
			||||||
 | 
					    """Run all API tests"""
 | 
				
			||||||
 | 
					    print("\n" + "="*60)
 | 
				
			||||||
 | 
					    print("  McRogueFace Exhaustive API Test Suite (Fixed)")
 | 
				
			||||||
 | 
					    print("  Testing constructors and methods...")
 | 
				
			||||||
 | 
					    print("="*60)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Run each test category
 | 
				
			||||||
 | 
					    test_functions = [
 | 
				
			||||||
 | 
					        test_color_api,
 | 
				
			||||||
 | 
					        test_frame_api,
 | 
				
			||||||
 | 
					        test_caption_api,
 | 
				
			||||||
 | 
					        test_animation_api
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    passed = 0
 | 
				
			||||||
 | 
					    failed = 0
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for test_func in test_functions:
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            if test_func():
 | 
				
			||||||
 | 
					                passed += 1
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                failed += 1
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            print(f"\n  ERROR in {test_func.__name__}: {e}")
 | 
				
			||||||
 | 
					            failed += 1
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Summary
 | 
				
			||||||
 | 
					    print("\n" + "="*60)
 | 
				
			||||||
 | 
					    print(f"  TEST SUMMARY: {passed} passed, {failed} failed")
 | 
				
			||||||
 | 
					    print("="*60)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    print("\n  Visual elements are displayed in the 'api_test' scene.")
 | 
				
			||||||
 | 
					    print("  The test is complete.")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Exit after a short delay to allow output to be seen
 | 
				
			||||||
 | 
					    def exit_test(runtime):
 | 
				
			||||||
 | 
					        print("\nExiting API test suite...")
 | 
				
			||||||
 | 
					        sys.exit(0)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    mcrfpy.setTimer("exit", exit_test, 2000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run the tests immediately
 | 
				
			||||||
 | 
					print("Starting McRogueFace Exhaustive API Demo (Fixed)...")
 | 
				
			||||||
 | 
					print("This will test constructors and methods.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					run_all_tests()
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,177 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					McRogueFace Animation Sizzle Reel - Final Version
 | 
				
			||||||
 | 
					=================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Complete demonstration of all animation capabilities.
 | 
				
			||||||
 | 
					This version works properly with the game loop and avoids API issues.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import mcrfpy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Configuration
 | 
				
			||||||
 | 
					DEMO_DURATION = 4.0  # Duration for each demo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# All available easing functions
 | 
				
			||||||
 | 
					EASING_FUNCTIONS = [
 | 
				
			||||||
 | 
					    "linear", "easeIn", "easeOut", "easeInOut",
 | 
				
			||||||
 | 
					    "easeInQuad", "easeOutQuad", "easeInOutQuad",
 | 
				
			||||||
 | 
					    "easeInCubic", "easeOutCubic", "easeInOutCubic",
 | 
				
			||||||
 | 
					    "easeInQuart", "easeOutQuart", "easeInOutQuart",
 | 
				
			||||||
 | 
					    "easeInSine", "easeOutSine", "easeInOutSine",
 | 
				
			||||||
 | 
					    "easeInExpo", "easeOutExpo", "easeInOutExpo",
 | 
				
			||||||
 | 
					    "easeInCirc", "easeOutCirc", "easeInOutCirc",
 | 
				
			||||||
 | 
					    "easeInElastic", "easeOutElastic", "easeInOutElastic",
 | 
				
			||||||
 | 
					    "easeInBack", "easeOutBack", "easeInOutBack",
 | 
				
			||||||
 | 
					    "easeInBounce", "easeOutBounce", "easeInOutBounce"
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Track demo state
 | 
				
			||||||
 | 
					current_demo = 0
 | 
				
			||||||
 | 
					subtitle = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def create_scene():
 | 
				
			||||||
 | 
					    """Create the demo scene"""
 | 
				
			||||||
 | 
					    mcrfpy.createScene("demo")
 | 
				
			||||||
 | 
					    mcrfpy.setScene("demo")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("demo")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Title
 | 
				
			||||||
 | 
					    title = mcrfpy.Caption("Animation Sizzle Reel", 500, 20)
 | 
				
			||||||
 | 
					    title.fill_color = mcrfpy.Color(255, 255, 0)
 | 
				
			||||||
 | 
					    title.outline = 2
 | 
				
			||||||
 | 
					    ui.append(title)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Subtitle
 | 
				
			||||||
 | 
					    global subtitle
 | 
				
			||||||
 | 
					    subtitle = mcrfpy.Caption("Starting...", 450, 60)
 | 
				
			||||||
 | 
					    subtitle.fill_color = mcrfpy.Color(200, 200, 200)
 | 
				
			||||||
 | 
					    ui.append(subtitle)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return ui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo1_frame_animations():
 | 
				
			||||||
 | 
					    """Frame position, size, and color animations"""
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("demo")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 1: Frame Animations"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create frame
 | 
				
			||||||
 | 
					    f = mcrfpy.Frame(100, 150, 200, 100)
 | 
				
			||||||
 | 
					    f.fill_color = mcrfpy.Color(50, 50, 150)
 | 
				
			||||||
 | 
					    f.outline = 3
 | 
				
			||||||
 | 
					    f.outline_color = mcrfpy.Color(255, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(f)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Animate properties
 | 
				
			||||||
 | 
					    mcrfpy.Animation("x", 600.0, 2.0, "easeInOutBack").start(f)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("y", 300.0, 2.0, "easeInOutElastic").start(f)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("w", 300.0, 2.5, "easeInOutCubic").start(f)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("h", 150.0, 2.5, "easeInOutCubic").start(f)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("fill_color", (255, 100, 50, 200), 3.0, "easeInOutSine").start(f)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("outline", 8.0, 3.0, "easeInOutQuad").start(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo2_caption_animations():
 | 
				
			||||||
 | 
					    """Caption movement and text effects"""
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("demo")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 2: Caption Animations"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Moving caption
 | 
				
			||||||
 | 
					    c1 = mcrfpy.Caption("Bouncing Text!", 100, 200)
 | 
				
			||||||
 | 
					    c1.fill_color = mcrfpy.Color(255, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(c1)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("x", 800.0, 3.0, "easeOutBounce").start(c1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Color cycling
 | 
				
			||||||
 | 
					    c2 = mcrfpy.Caption("Color Cycle", 400, 300)
 | 
				
			||||||
 | 
					    c2.outline = 2
 | 
				
			||||||
 | 
					    ui.append(c2)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("fill_color", (255, 0, 0, 255), 1.0, "linear").start(c2)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Typewriter effect
 | 
				
			||||||
 | 
					    c3 = mcrfpy.Caption("", 100, 400)
 | 
				
			||||||
 | 
					    c3.fill_color = mcrfpy.Color(0, 255, 255)
 | 
				
			||||||
 | 
					    ui.append(c3)
 | 
				
			||||||
 | 
					    mcrfpy.Animation("text", "Typewriter effect animation...", 3.0, "linear").start(c3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo3_easing_showcase():
 | 
				
			||||||
 | 
					    """Show all 30 easing functions"""
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("demo")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 3: All 30 Easing Functions"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create a small frame for each easing
 | 
				
			||||||
 | 
					    for i, easing in enumerate(EASING_FUNCTIONS[:15]):  # First 15
 | 
				
			||||||
 | 
					        row = i // 5
 | 
				
			||||||
 | 
					        col = i % 5
 | 
				
			||||||
 | 
					        x = 100 + col * 200
 | 
				
			||||||
 | 
					        y = 150 + row * 100
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Frame
 | 
				
			||||||
 | 
					        f = mcrfpy.Frame(x, y, 20, 20)
 | 
				
			||||||
 | 
					        f.fill_color = mcrfpy.Color(100, 150, 255)
 | 
				
			||||||
 | 
					        ui.append(f)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Label
 | 
				
			||||||
 | 
					        label = mcrfpy.Caption(easing[:10], x, y - 20)
 | 
				
			||||||
 | 
					        label.fill_color = mcrfpy.Color(200, 200, 200)
 | 
				
			||||||
 | 
					        ui.append(label)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Animate with this easing
 | 
				
			||||||
 | 
					        mcrfpy.Animation("x", float(x + 150), 3.0, easing).start(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def demo4_performance():
 | 
				
			||||||
 | 
					    """Many simultaneous animations"""
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("demo")
 | 
				
			||||||
 | 
					    subtitle.text = "Demo 4: 50+ Simultaneous Animations"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for i in range(50):
 | 
				
			||||||
 | 
					        x = 100 + (i % 10) * 100
 | 
				
			||||||
 | 
					        y = 150 + (i // 10) * 100
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        f = mcrfpy.Frame(x, y, 30, 30)
 | 
				
			||||||
 | 
					        f.fill_color = mcrfpy.Color((i*37)%256, (i*73)%256, (i*113)%256)
 | 
				
			||||||
 | 
					        ui.append(f)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Animate to random position
 | 
				
			||||||
 | 
					        target_x = 150 + (i % 8) * 110
 | 
				
			||||||
 | 
					        target_y = 200 + (i // 8) * 90
 | 
				
			||||||
 | 
					        easing = EASING_FUNCTIONS[i % len(EASING_FUNCTIONS)]
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        mcrfpy.Animation("x", float(target_x), 2.5, easing).start(f)
 | 
				
			||||||
 | 
					        mcrfpy.Animation("y", float(target_y), 2.5, easing).start(f)
 | 
				
			||||||
 | 
					        mcrfpy.Animation("opacity", 0.3 + (i%7)*0.1, 2.0, "easeInOutSine").start(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def clear_demo_objects():
 | 
				
			||||||
 | 
					    """Clear scene except title and subtitle"""
 | 
				
			||||||
 | 
					    ui = mcrfpy.sceneUI("demo")
 | 
				
			||||||
 | 
					    # Keep removing items after the first 2 (title and subtitle)
 | 
				
			||||||
 | 
					    while len(ui) > 2:
 | 
				
			||||||
 | 
					        # Remove the last item
 | 
				
			||||||
 | 
					        ui.remove(ui[len(ui)-1])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def next_demo(runtime):
 | 
				
			||||||
 | 
					    """Run the next demo"""
 | 
				
			||||||
 | 
					    global current_demo
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    clear_demo_objects()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    demos = [
 | 
				
			||||||
 | 
					        demo1_frame_animations,
 | 
				
			||||||
 | 
					        demo2_caption_animations,
 | 
				
			||||||
 | 
					        demo3_easing_showcase,
 | 
				
			||||||
 | 
					        demo4_performance
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if current_demo < len(demos):
 | 
				
			||||||
 | 
					        demos[current_demo]()
 | 
				
			||||||
 | 
					        current_demo += 1
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if current_demo < len(demos):
 | 
				
			||||||
 | 
					            mcrfpy.setTimer("next", next_demo, int(DEMO_DURATION * 1000))
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            subtitle.text = "Demo Complete!"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Initialize
 | 
				
			||||||
 | 
					print("Starting Animation Sizzle Reel...")
 | 
				
			||||||
 | 
					create_scene()
 | 
				
			||||||
 | 
					mcrfpy.setTimer("start", next_demo, 500)
 | 
				
			||||||
		Loading…
	
		Reference in New Issue