Directory structure cleanup and organization overhaul

This commit is contained in:
John McCardle 2025-07-10 22:10:27 -04:00
commit 98fc49a978
119 changed files with 10483 additions and 4042 deletions

View file

@ -0,0 +1,129 @@
#!/usr/bin/env python3
"""Generate caption documentation screenshot with proper font"""
import mcrfpy
from mcrfpy import automation
import sys
def capture_caption(runtime):
"""Capture caption example after render loop starts"""
# Take screenshot
automation.screenshot("mcrogueface.github.io/images/ui_caption_example.png")
print("Caption screenshot saved!")
# Exit after capturing
sys.exit(0)
# Create scene
mcrfpy.createScene("captions")
# Title
title = mcrfpy.Caption(400, 30, "Caption Examples")
title.font = mcrfpy.default_font
title.font_size = 28
title.font_color = (255, 255, 255)
# Different sizes
size_label = mcrfpy.Caption(100, 100, "Different Sizes:")
size_label.font = mcrfpy.default_font
size_label.font_color = (200, 200, 200)
large = mcrfpy.Caption(300, 100, "Large Text (24pt)")
large.font = mcrfpy.default_font
large.font_size = 24
large.font_color = (255, 255, 255)
medium = mcrfpy.Caption(300, 140, "Medium Text (18pt)")
medium.font = mcrfpy.default_font
medium.font_size = 18
medium.font_color = (255, 255, 255)
small = mcrfpy.Caption(300, 170, "Small Text (14pt)")
small.font = mcrfpy.default_font
small.font_size = 14
small.font_color = (255, 255, 255)
# Different colors
color_label = mcrfpy.Caption(100, 230, "Different Colors:")
color_label.font = mcrfpy.default_font
color_label.font_color = (200, 200, 200)
white_text = mcrfpy.Caption(300, 230, "White Text")
white_text.font = mcrfpy.default_font
white_text.font_color = (255, 255, 255)
green_text = mcrfpy.Caption(300, 260, "Green Text")
green_text.font = mcrfpy.default_font
green_text.font_color = (100, 255, 100)
red_text = mcrfpy.Caption(300, 290, "Red Text")
red_text.font = mcrfpy.default_font
red_text.font_color = (255, 100, 100)
blue_text = mcrfpy.Caption(300, 320, "Blue Text")
blue_text.font = mcrfpy.default_font
blue_text.font_color = (100, 150, 255)
# Caption with background
bg_label = mcrfpy.Caption(100, 380, "With Background:")
bg_label.font = mcrfpy.default_font
bg_label.font_color = (200, 200, 200)
# Frame background
frame = mcrfpy.Frame(280, 370, 250, 50)
frame.bgcolor = (64, 64, 128)
frame.outline = 2
framed_text = mcrfpy.Caption(405, 395, "Caption on Frame")
framed_text.font = mcrfpy.default_font
framed_text.font_size = 18
framed_text.font_color = (255, 255, 255)
framed_text.centered = True
# Centered text example
center_label = mcrfpy.Caption(100, 460, "Centered Text:")
center_label.font = mcrfpy.default_font
center_label.font_color = (200, 200, 200)
centered = mcrfpy.Caption(400, 460, "This text is centered")
centered.font = mcrfpy.default_font
centered.font_size = 20
centered.font_color = (255, 255, 100)
centered.centered = True
# Multi-line example
multi_label = mcrfpy.Caption(100, 520, "Multi-line:")
multi_label.font = mcrfpy.default_font
multi_label.font_color = (200, 200, 200)
multiline = mcrfpy.Caption(300, 520, "Line 1: McRogueFace\nLine 2: Game Engine\nLine 3: Python API")
multiline.font = mcrfpy.default_font
multiline.font_size = 14
multiline.font_color = (255, 255, 255)
# Add all to scene
ui = mcrfpy.sceneUI("captions")
ui.append(title)
ui.append(size_label)
ui.append(large)
ui.append(medium)
ui.append(small)
ui.append(color_label)
ui.append(white_text)
ui.append(green_text)
ui.append(red_text)
ui.append(blue_text)
ui.append(bg_label)
ui.append(frame)
ui.append(framed_text)
ui.append(center_label)
ui.append(centered)
ui.append(multi_label)
ui.append(multiline)
# Switch to scene
mcrfpy.setScene("captions")
# Set timer to capture after rendering starts
mcrfpy.setTimer("capture", capture_caption, 100)

View file

@ -0,0 +1,217 @@
#!/usr/bin/env python3
"""Generate documentation screenshots for McRogueFace UI elements - Simple version"""
import mcrfpy
from mcrfpy import automation
import sys
import os
# Crypt of Sokoban color scheme
FRAME_COLOR = mcrfpy.Color(64, 64, 128)
SHADOW_COLOR = mcrfpy.Color(64, 64, 86)
BOX_COLOR = mcrfpy.Color(96, 96, 160)
WHITE = mcrfpy.Color(255, 255, 255)
BLACK = mcrfpy.Color(0, 0, 0)
GREEN = mcrfpy.Color(0, 255, 0)
RED = mcrfpy.Color(255, 0, 0)
# Create texture for sprites
sprite_texture = mcrfpy.Texture("assets/kenney_TD_MR_IP.png", 16, 16)
# Output directory
output_dir = "mcrogueface.github.io/images"
if not os.path.exists(output_dir):
os.makedirs(output_dir)
def create_caption(x, y, text, font_size=16, text_color=WHITE, outline_color=BLACK):
"""Helper function to create captions with common settings"""
caption = mcrfpy.Caption(mcrfpy.Vector(x, y), text=text)
caption.size = font_size
caption.fill_color = text_color
caption.outline_color = outline_color
return caption
# Screenshot counter
screenshot_count = 0
total_screenshots = 4
def screenshot_and_continue(runtime):
"""Take a screenshot and move to the next scene"""
global screenshot_count
if screenshot_count == 0:
# Caption example
print("Creating Caption example...")
mcrfpy.createScene("caption_example")
ui = mcrfpy.sceneUI("caption_example")
bg = mcrfpy.Frame(0, 0, 800, 600, fill_color=FRAME_COLOR)
ui.append(bg)
title = create_caption(200, 50, "Caption Examples", 32)
ui.append(title)
caption1 = create_caption(100, 150, "Large Caption (24pt)", 24)
ui.append(caption1)
caption2 = create_caption(100, 200, "Medium Caption (18pt)", 18, GREEN)
ui.append(caption2)
caption3 = create_caption(100, 240, "Small Caption (14pt)", 14, RED)
ui.append(caption3)
caption_bg = mcrfpy.Frame(100, 300, 300, 50, fill_color=BOX_COLOR)
ui.append(caption_bg)
caption4 = create_caption(110, 315, "Caption with Background", 16)
ui.append(caption4)
mcrfpy.setScene("caption_example")
mcrfpy.setTimer("next1", lambda r: capture_screenshot("ui_caption_example.png"), 200)
elif screenshot_count == 1:
# Sprite example
print("Creating Sprite example...")
mcrfpy.createScene("sprite_example")
ui = mcrfpy.sceneUI("sprite_example")
bg = mcrfpy.Frame(0, 0, 800, 600, fill_color=FRAME_COLOR)
ui.append(bg)
title = create_caption(250, 50, "Sprite Examples", 32)
ui.append(title)
sprite_bg = mcrfpy.Frame(100, 150, 600, 300, fill_color=BOX_COLOR)
ui.append(sprite_bg)
player_label = create_caption(150, 180, "Player", 14)
ui.append(player_label)
player_sprite = mcrfpy.Sprite(150, 200, sprite_texture, 84, 3.0)
ui.append(player_sprite)
enemy_label = create_caption(250, 180, "Enemies", 14)
ui.append(enemy_label)
enemy1 = mcrfpy.Sprite(250, 200, sprite_texture, 123, 3.0)
ui.append(enemy1)
enemy2 = mcrfpy.Sprite(300, 200, sprite_texture, 107, 3.0)
ui.append(enemy2)
boulder_label = create_caption(400, 180, "Boulder", 14)
ui.append(boulder_label)
boulder_sprite = mcrfpy.Sprite(400, 200, sprite_texture, 66, 3.0)
ui.append(boulder_sprite)
exit_label = create_caption(500, 180, "Exit States", 14)
ui.append(exit_label)
exit_locked = mcrfpy.Sprite(500, 200, sprite_texture, 45, 3.0)
ui.append(exit_locked)
exit_open = mcrfpy.Sprite(550, 200, sprite_texture, 21, 3.0)
ui.append(exit_open)
mcrfpy.setScene("sprite_example")
mcrfpy.setTimer("next2", lambda r: capture_screenshot("ui_sprite_example.png"), 200)
elif screenshot_count == 2:
# Frame example
print("Creating Frame example...")
mcrfpy.createScene("frame_example")
ui = mcrfpy.sceneUI("frame_example")
bg = mcrfpy.Frame(0, 0, 800, 600, fill_color=SHADOW_COLOR)
ui.append(bg)
title = create_caption(250, 30, "Frame Examples", 32)
ui.append(title)
frame1 = mcrfpy.Frame(50, 100, 200, 150, fill_color=FRAME_COLOR)
ui.append(frame1)
label1 = create_caption(60, 110, "Basic Frame", 16)
ui.append(label1)
frame2 = mcrfpy.Frame(300, 100, 200, 150, fill_color=BOX_COLOR,
outline_color=WHITE, outline=2.0)
ui.append(frame2)
label2 = create_caption(310, 110, "Frame with Outline", 16)
ui.append(label2)
frame3 = mcrfpy.Frame(550, 100, 200, 150, fill_color=FRAME_COLOR,
outline_color=WHITE, outline=1)
ui.append(frame3)
inner_frame = mcrfpy.Frame(570, 130, 160, 90, fill_color=BOX_COLOR)
ui.append(inner_frame)
label3 = create_caption(560, 110, "Nested Frames", 16)
ui.append(label3)
mcrfpy.setScene("frame_example")
mcrfpy.setTimer("next3", lambda r: capture_screenshot("ui_frame_example.png"), 200)
elif screenshot_count == 3:
# Grid example
print("Creating Grid example...")
mcrfpy.createScene("grid_example")
ui = mcrfpy.sceneUI("grid_example")
bg = mcrfpy.Frame(0, 0, 800, 600, fill_color=FRAME_COLOR)
ui.append(bg)
title = create_caption(250, 30, "Grid Example", 32)
ui.append(title)
grid = mcrfpy.Grid(20, 15, sprite_texture,
mcrfpy.Vector(100, 100), mcrfpy.Vector(320, 240))
# Set up dungeon tiles
for x in range(20):
for y in range(15):
if x == 0 or x == 19 or y == 0 or y == 14:
# Walls
grid.at((x, y)).tilesprite = 3
grid.at((x, y)).walkable = False
else:
# Floor
grid.at((x, y)).tilesprite = 48
grid.at((x, y)).walkable = True
# Add some internal walls
for x in range(5, 15):
grid.at((x, 7)).tilesprite = 3
grid.at((x, 7)).walkable = False
for y in range(3, 8):
grid.at((10, y)).tilesprite = 3
grid.at((10, y)).walkable = False
# Add a door
grid.at((10, 7)).tilesprite = 131
grid.at((10, 7)).walkable = True
ui.append(grid)
grid_label = create_caption(100, 480, "20x15 Grid - Simple Dungeon Layout", 16)
ui.append(grid_label)
mcrfpy.setScene("grid_example")
mcrfpy.setTimer("next4", lambda r: capture_screenshot("ui_grid_example.png"), 200)
else:
print("\nAll screenshots captured successfully!")
print(f"Screenshots saved to: {output_dir}/")
mcrfpy.exit()
return
def capture_screenshot(filename):
"""Capture a screenshot"""
global screenshot_count
full_path = f"{output_dir}/{filename}"
result = automation.screenshot(full_path)
print(f"Screenshot {screenshot_count + 1}/{total_screenshots}: {filename} - {'Success' if result else 'Failed'}")
screenshot_count += 1
# Schedule next scene
mcrfpy.setTimer("continue", screenshot_and_continue, 300)
# Start the process
print("Starting screenshot generation...")
mcrfpy.setTimer("start", screenshot_and_continue, 500)
# Safety timeout
mcrfpy.setTimer("safety", lambda r: mcrfpy.exit(), 30000)
print("Setup complete. Game loop starting...")

View file

@ -0,0 +1,144 @@
#!/usr/bin/env python3
"""Generate entity documentation screenshot with proper font loading"""
import mcrfpy
from mcrfpy import automation
import sys
def capture_entity(runtime):
"""Capture entity example after render loop starts"""
# Take screenshot
automation.screenshot("mcrogueface.github.io/images/ui_entity_example.png")
print("Entity screenshot saved!")
# Exit after capturing
sys.exit(0)
# Create scene
mcrfpy.createScene("entities")
# Use the default font which is already loaded
# Instead of: font = mcrfpy.Font("assets/JetbrainsMono.ttf")
# We use: mcrfpy.default_font (which is already loaded by the engine)
# Title
title = mcrfpy.Caption((400, 30), "Entity Example - Roguelike Characters", font=mcrfpy.default_font)
#title.font = mcrfpy.default_font
#title.font_size = 24
title.size=24
#title.font_color = (255, 255, 255)
#title.text_color = (255,255,255)
# Create a grid background
texture = mcrfpy.Texture("assets/kenney_TD_MR_IP.png", 16, 16)
# Create grid with entities - using 2x scale (32x32 pixel tiles)
#grid = mcrfpy.Grid((100, 100), (20, 15), texture, 16, 16) # I can never get the args right for this thing
t = mcrfpy.Texture("assets/kenney_TD_MR_IP.png", 16, 16)
grid = mcrfpy.Grid(20, 15, t, (10, 10), (1014, 758))
grid.zoom = 2.0
#grid.texture = texture
# Define tile types
FLOOR = 58 # Stone floor
WALL = 11 # Stone wall
# Fill with floor
for x in range(20):
for y in range(15):
grid.at((x, y)).tilesprite = WALL
# Add walls around edges
for x in range(20):
grid.at((x, 0)).tilesprite = WALL
grid.at((x, 14)).tilesprite = WALL
for y in range(15):
grid.at((0, y)).tilesprite = WALL
grid.at((19, y)).tilesprite = WALL
# Create entities
# Player at center
player = mcrfpy.Entity((10, 7), t, 84)
#player.texture = texture
#player.sprite_index = 84 # Player sprite
# Enemies
rat1 = mcrfpy.Entity((5, 5), t, 123)
#rat1.texture = texture
#rat1.sprite_index = 123 # Rat
rat2 = mcrfpy.Entity((15, 5), t, 123)
#rat2.texture = texture
#rat2.sprite_index = 123 # Rat
big_rat = mcrfpy.Entity((7, 10), t, 130)
#big_rat.texture = texture
#big_rat.sprite_index = 130 # Big rat
cyclops = mcrfpy.Entity((13, 10), t, 109)
#cyclops.texture = texture
#cyclops.sprite_index = 109 # Cyclops
# Items
chest = mcrfpy.Entity((3, 3), t, 89)
#chest.texture = texture
#chest.sprite_index = 89 # Chest
boulder = mcrfpy.Entity((10, 5), t, 66)
#boulder.texture = texture
#boulder.sprite_index = 66 # Boulder
key = mcrfpy.Entity((17, 12), t, 384)
#key.texture = texture
#key.sprite_index = 384 # Key
# Add all entities to grid
grid.entities.append(player)
grid.entities.append(rat1)
grid.entities.append(rat2)
grid.entities.append(big_rat)
grid.entities.append(cyclops)
grid.entities.append(chest)
grid.entities.append(boulder)
grid.entities.append(key)
# Labels
entity_label = mcrfpy.Caption((100, 580), "Entities move independently on the grid. Grid scale: 2x (32x32 pixels)")
#entity_label.font = mcrfpy.default_font
#entity_label.font_color = (255, 255, 255)
info = mcrfpy.Caption((100, 600), "Player (center), Enemies (rats, cyclops), Items (chest, boulder, key)")
#info.font = mcrfpy.default_font
#info.font_size = 14
#info.font_color = (200, 200, 200)
# Legend frame
legend_frame = mcrfpy.Frame(50, 50, 200, 150)
#legend_frame.bgcolor = (64, 64, 128)
#legend_frame.outline = 2
legend_title = mcrfpy.Caption((150, 60), "Entity Types")
#legend_title.font = mcrfpy.default_font
#legend_title.font_color = (255, 255, 255)
#legend_title.centered = True
#legend_text = mcrfpy.Caption((60, 90), "Player: @\nRat: r\nBig Rat: R\nCyclops: C\nChest: $\nBoulder: O\nKey: k")
#legend_text.font = mcrfpy.default_font
#legend_text.font_size = 12
#legend_text.font_color = (255, 255, 255)
# Add all to scene
ui = mcrfpy.sceneUI("entities")
ui.append(grid)
ui.append(title)
ui.append(entity_label)
ui.append(info)
ui.append(legend_frame)
ui.append(legend_title)
#ui.append(legend_text)
# Switch to scene
mcrfpy.setScene("entities")
# Set timer to capture after rendering starts
mcrfpy.setTimer("capture", capture_entity, 100)

View file

@ -0,0 +1,375 @@
#!/usr/bin/env python3
"""
Path & Vision Sizzle Reel (Fixed)
=================================
Fixed version with proper animation chaining to prevent glitches.
"""
import mcrfpy
import sys
class PathAnimator:
"""Handles step-by-step animation with proper completion tracking"""
def __init__(self, entity, name="animator"):
self.entity = entity
self.name = name
self.path = []
self.current_index = 0
self.step_duration = 0.4
self.animating = False
self.on_step = None
self.on_complete = None
def set_path(self, path):
"""Set the path to animate along"""
self.path = path
self.current_index = 0
def start(self):
"""Start animating"""
if not self.path:
return
self.animating = True
self.current_index = 0
self._move_to_next()
def stop(self):
"""Stop animating"""
self.animating = False
mcrfpy.delTimer(f"{self.name}_check")
def _move_to_next(self):
"""Move to next position in path"""
if not self.animating or self.current_index >= len(self.path):
self.animating = False
if self.on_complete:
self.on_complete()
return
# Get next position
x, y = self.path[self.current_index]
# Create animations
anim_x = mcrfpy.Animation("x", float(x), self.step_duration, "easeInOut")
anim_y = mcrfpy.Animation("y", float(y), self.step_duration, "easeInOut")
anim_x.start(self.entity)
anim_y.start(self.entity)
# Update visibility
self.entity.update_visibility()
# Callback for each step
if self.on_step:
self.on_step(self.current_index, x, y)
# Schedule next move
delay = int(self.step_duration * 1000) + 50 # Add small buffer
mcrfpy.setTimer(f"{self.name}_next", self._handle_next, delay)
def _handle_next(self, dt):
"""Timer callback to move to next position"""
self.current_index += 1
mcrfpy.delTimer(f"{self.name}_next")
self._move_to_next()
# Global state
grid = None
player = None
enemy = None
player_animator = None
enemy_animator = None
demo_phase = 0
def create_scene():
"""Create the demo environment"""
global grid, player, enemy
mcrfpy.createScene("fixed_demo")
# Create grid
grid = mcrfpy.Grid(grid_x=30, grid_y=20)
grid.fill_color = mcrfpy.Color(20, 20, 30)
# Simple dungeon layout
map_layout = [
"##############################",
"#......#########.....#########",
"#......#########.....#########",
"#......#.........#...#########",
"#......#.........#...#########",
"####.###.........#.###########",
"####.............#.###########",
"####.............#.###########",
"####.###.........#.###########",
"#......#.........#...#########",
"#......#.........#...#########",
"#......#########.#...........#",
"#......#########.#...........#",
"#......#########.#...........#",
"#......#########.#############",
"####.###########.............#",
"####.........................#",
"####.###########.............#",
"#......#########.............#",
"##############################",
]
# Build map
for y, row in enumerate(map_layout):
for x, char in enumerate(row):
cell = grid.at(x, y)
if char == '#':
cell.walkable = False
cell.transparent = False
cell.color = mcrfpy.Color(40, 30, 30)
else:
cell.walkable = True
cell.transparent = True
cell.color = mcrfpy.Color(80, 80, 100)
# Create entities
player = mcrfpy.Entity(3, 3, grid=grid)
player.sprite_index = 64 # @
enemy = mcrfpy.Entity(26, 16, grid=grid)
enemy.sprite_index = 69 # E
# Initial visibility
player.update_visibility()
enemy.update_visibility()
# Set initial perspective
grid.perspective = 0
def setup_ui():
"""Create UI elements"""
ui = mcrfpy.sceneUI("fixed_demo")
ui.append(grid)
grid.position = (50, 80)
grid.size = (700, 500)
title = mcrfpy.Caption("Path & Vision Demo (Fixed)", 300, 20)
title.fill_color = mcrfpy.Color(255, 255, 255)
ui.append(title)
global status_text, perspective_text
status_text = mcrfpy.Caption("Initializing...", 50, 50)
status_text.fill_color = mcrfpy.Color(200, 200, 200)
ui.append(status_text)
perspective_text = mcrfpy.Caption("Perspective: Player", 550, 50)
perspective_text.fill_color = mcrfpy.Color(100, 255, 100)
ui.append(perspective_text)
controls = mcrfpy.Caption("Space: Start/Pause | R: Restart | Q: Quit", 250, 600)
controls.fill_color = mcrfpy.Color(150, 150, 150)
ui.append(controls)
def update_camera_smooth(target, duration=0.3):
"""Smoothly move camera to entity"""
center_x = target.x * 23 # Approximate pixel size
center_y = target.y * 23
cam_anim = mcrfpy.Animation("center", (center_x, center_y), duration, "easeOut")
cam_anim.start(grid)
def start_demo():
"""Start the demo sequence"""
global demo_phase, player_animator, enemy_animator
demo_phase = 1
status_text.text = "Phase 1: Player movement with camera follow"
# Player path
player_path = [
(3, 3), (3, 6), (4, 6), (7, 6), (7, 8),
(10, 8), (13, 8), (16, 8), (16, 10),
(16, 13), (16, 16), (20, 16), (24, 16)
]
# Setup player animator
player_animator = PathAnimator(player, "player")
player_animator.set_path(player_path)
player_animator.step_duration = 0.5
def on_player_step(index, x, y):
"""Called for each player step"""
status_text.text = f"Player step {index+1}/{len(player_path)}"
if grid.perspective == 0:
update_camera_smooth(player, 0.4)
def on_player_complete():
"""Called when player path is complete"""
start_phase_2()
player_animator.on_step = on_player_step
player_animator.on_complete = on_player_complete
player_animator.start()
def start_phase_2():
"""Start enemy movement phase"""
global demo_phase
demo_phase = 2
status_text.text = "Phase 2: Enemy movement (may enter player's view)"
# Enemy path
enemy_path = [
(26, 16), (22, 16), (18, 16), (16, 16),
(16, 13), (16, 10), (16, 8), (13, 8),
(10, 8), (7, 8), (7, 6), (4, 6)
]
# Setup enemy animator
enemy_animator.set_path(enemy_path)
enemy_animator.step_duration = 0.4
def on_enemy_step(index, x, y):
"""Check if enemy is visible to player"""
if grid.perspective == 0:
# Check if enemy is in player's view
enemy_idx = int(y) * grid.grid_x + int(x)
if enemy_idx < len(player.gridstate) and player.gridstate[enemy_idx].visible:
status_text.text = "Enemy spotted in player's view!"
def on_enemy_complete():
"""Start perspective transition"""
start_phase_3()
enemy_animator.on_step = on_enemy_step
enemy_animator.on_complete = on_enemy_complete
enemy_animator.start()
def start_phase_3():
"""Dramatic perspective shift"""
global demo_phase
demo_phase = 3
status_text.text = "Phase 3: Perspective shift..."
# Stop any ongoing animations
player_animator.stop()
enemy_animator.stop()
# Zoom out
zoom_out = mcrfpy.Animation("zoom", 0.6, 2.0, "easeInExpo")
zoom_out.start(grid)
# Schedule perspective switch
mcrfpy.setTimer("switch_persp", switch_perspective, 2100)
def switch_perspective(dt):
"""Switch to enemy perspective"""
grid.perspective = 1
perspective_text.text = "Perspective: Enemy"
perspective_text.fill_color = mcrfpy.Color(255, 100, 100)
# Update camera
update_camera_smooth(enemy, 0.5)
# Zoom back in
zoom_in = mcrfpy.Animation("zoom", 1.0, 2.0, "easeOutExpo")
zoom_in.start(grid)
status_text.text = "Now following enemy perspective"
# Clean up timer
mcrfpy.delTimer("switch_persp")
# Continue enemy movement after transition
mcrfpy.setTimer("continue_enemy", continue_enemy_movement, 2500)
def continue_enemy_movement(dt):
"""Continue enemy movement after perspective shift"""
mcrfpy.delTimer("continue_enemy")
# Continue path
enemy_path_2 = [
(4, 6), (3, 6), (3, 3), (3, 2), (3, 1)
]
enemy_animator.set_path(enemy_path_2)
def on_step(index, x, y):
update_camera_smooth(enemy, 0.4)
status_text.text = f"Following enemy: step {index+1}"
def on_complete():
status_text.text = "Demo complete! Press R to restart"
enemy_animator.on_step = on_step
enemy_animator.on_complete = on_complete
enemy_animator.start()
# Control state
running = False
def handle_keys(key, state):
"""Handle keyboard input"""
global running
if state != "start":
return
key = key.lower()
if key == "q":
sys.exit(0)
elif key == "space":
if not running:
running = True
start_demo()
else:
running = False
player_animator.stop()
enemy_animator.stop()
status_text.text = "Paused"
elif key == "r":
# Reset everything
player.x, player.y = 3, 3
enemy.x, enemy.y = 26, 16
grid.perspective = 0
perspective_text.text = "Perspective: Player"
perspective_text.fill_color = mcrfpy.Color(100, 255, 100)
grid.zoom = 1.0
update_camera_smooth(player, 0.5)
if running:
player_animator.stop()
enemy_animator.stop()
running = False
status_text.text = "Reset - Press SPACE to start"
# Initialize
create_scene()
setup_ui()
# Setup animators
player_animator = PathAnimator(player, "player")
enemy_animator = PathAnimator(enemy, "enemy")
# Set scene
mcrfpy.setScene("fixed_demo")
mcrfpy.keypressScene(handle_keys)
# Initial camera
grid.zoom = 1.0
update_camera_smooth(player, 0.5)
print("Path & Vision Demo (Fixed)")
print("==========================")
print("This version properly chains animations to prevent glitches.")
print()
print("The demo will:")
print("1. Move player with camera following")
print("2. Move enemy (may enter player's view)")
print("3. Dramatic perspective shift to enemy")
print("4. Continue following enemy")
print()
print("Press SPACE to start, Q to quit")

View file

@ -0,0 +1,58 @@
#!/usr/bin/env python3
"""Simple test for mcrfpy.Grid"""
import mcrfpy
print("Starting Grid test...")
# Create test scene
print("[DEBUG] Creating scene...")
mcrfpy.createScene("grid_test")
print("[DEBUG] Setting scene...")
mcrfpy.setScene("grid_test")
print("[DEBUG] Getting UI...")
ui = mcrfpy.sceneUI("grid_test")
print("[DEBUG] UI retrieved")
# Test grid creation
try:
# Texture constructor: filename, sprite_width, sprite_height
# kenney_ice.png is 192x176, so 16x16 would give us 12x11 sprites
texture = mcrfpy.Texture("assets/kenney_ice.png", 16, 16)
print("[INFO] Texture created successfully")
except Exception as e:
print(f"[FAIL] Texture creation failed: {e}")
exit(1)
grid = None
try:
# Try with just 2 args
grid = mcrfpy.Grid(20, 15) # Just grid dimensions
print("[INFO] Grid created with 2 args")
except Exception as e:
print(f"[FAIL] 2 args failed: {e}")
if not grid:
try:
# Try with 3 args
grid = mcrfpy.Grid(20, 15, texture)
print("[INFO] Grid created with 3 args")
except Exception as e:
print(f"[FAIL] 3 args failed: {e}")
# If we got here, add to UI
try:
ui.append(grid)
print("[PASS] Grid created and added to UI successfully")
except Exception as e:
print(f"[FAIL] Failed to add Grid to UI: {e}")
exit(1)
# Test grid properties
try:
print(f"Grid size: {grid.grid_size}")
print(f"Position: {grid.position}")
print(f"Size: {grid.size}")
except Exception as e:
print(f"[FAIL] Property access failed: {e}")
print("Test complete!")