Add cookbook and tutorial showcase demos
tests/demo/: - cookbook_showcase.py: Interactive demo of cookbook recipes - tutorial_showcase.py: Visual walkthrough of tutorial content - tutorial_screenshots.py: Automated screenshot generation - new_features_showcase.py: Demo of modern API features - procgen_showcase.py: Procedural generation examples - simple_showcase.py: Minimal working examples Created during docs modernization to verify cookbook examples work. 🤖 Generated with Claude Code (https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
23afae69ad
commit
a1b692bb1f
6 changed files with 1734 additions and 0 deletions
255
tests/demo/new_features_showcase.py
Normal file
255
tests/demo/new_features_showcase.py
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
New Features Screenshot Showcase - Alignment + Dijkstra-to-HeightMap
|
||||
|
||||
Generates screenshots for the new API cookbook recipes.
|
||||
Run with: xvfb-run -a ./build/mcrogueface --headless --exec tests/demo/new_features_showcase.py
|
||||
"""
|
||||
import mcrfpy
|
||||
from mcrfpy import automation
|
||||
import sys
|
||||
import os
|
||||
|
||||
OUTPUT_DIR = "/opt/goblincorps/repos/mcrogueface.github.io/images/cookbook"
|
||||
|
||||
|
||||
def screenshot_alignment():
|
||||
"""Create an alignment system showcase."""
|
||||
scene = mcrfpy.Scene("alignment")
|
||||
|
||||
# Dark background
|
||||
bg = mcrfpy.Frame(pos=(0, 0), size=(800, 600))
|
||||
bg.fill_color = mcrfpy.Color(20, 20, 30)
|
||||
scene.children.append(bg)
|
||||
|
||||
# Title
|
||||
title = mcrfpy.Caption(text="UI Alignment System", pos=(50, 20))
|
||||
title.fill_color = mcrfpy.Color(255, 255, 255)
|
||||
title.font_size = 28
|
||||
scene.children.append(title)
|
||||
|
||||
subtitle = mcrfpy.Caption(text="Auto-positioning with reactive resize", pos=(50, 50))
|
||||
subtitle.fill_color = mcrfpy.Color(180, 180, 200)
|
||||
subtitle.font_size = 16
|
||||
scene.children.append(subtitle)
|
||||
|
||||
# Demo container
|
||||
container = mcrfpy.Frame(pos=(100, 100), size=(600, 400))
|
||||
container.fill_color = mcrfpy.Color(40, 40, 50)
|
||||
container.outline = 2
|
||||
container.outline_color = mcrfpy.Color(80, 80, 100)
|
||||
scene.children.append(container)
|
||||
|
||||
# Container label
|
||||
container_label = mcrfpy.Caption(text="Parent Container (600x400)", pos=(10, 10))
|
||||
container_label.fill_color = mcrfpy.Color(100, 100, 120)
|
||||
container_label.font_size = 12
|
||||
container.children.append(container_label)
|
||||
|
||||
# 9 alignment positions demo
|
||||
alignments = [
|
||||
(mcrfpy.Alignment.TOP_LEFT, "TL", mcrfpy.Color(200, 80, 80)),
|
||||
(mcrfpy.Alignment.TOP_CENTER, "TC", mcrfpy.Color(200, 150, 80)),
|
||||
(mcrfpy.Alignment.TOP_RIGHT, "TR", mcrfpy.Color(200, 200, 80)),
|
||||
(mcrfpy.Alignment.CENTER_LEFT, "CL", mcrfpy.Color(80, 200, 80)),
|
||||
(mcrfpy.Alignment.CENTER, "C", mcrfpy.Color(80, 200, 200)),
|
||||
(mcrfpy.Alignment.CENTER_RIGHT, "CR", mcrfpy.Color(80, 80, 200)),
|
||||
(mcrfpy.Alignment.BOTTOM_LEFT, "BL", mcrfpy.Color(150, 80, 200)),
|
||||
(mcrfpy.Alignment.BOTTOM_CENTER, "BC", mcrfpy.Color(200, 80, 200)),
|
||||
(mcrfpy.Alignment.BOTTOM_RIGHT, "BR", mcrfpy.Color(200, 80, 150)),
|
||||
]
|
||||
|
||||
for align, label, color in alignments:
|
||||
box = mcrfpy.Frame(pos=(0, 0), size=(60, 40))
|
||||
box.fill_color = color
|
||||
box.outline = 1
|
||||
box.outline_color = mcrfpy.Color(255, 255, 255)
|
||||
box.align = align
|
||||
if align != mcrfpy.Alignment.CENTER:
|
||||
box.margin = 15.0
|
||||
|
||||
# Label inside box
|
||||
text = mcrfpy.Caption(text=label, pos=(0, 0))
|
||||
text.fill_color = mcrfpy.Color(255, 255, 255)
|
||||
text.font_size = 16
|
||||
text.align = mcrfpy.Alignment.CENTER
|
||||
box.children.append(text)
|
||||
|
||||
container.children.append(box)
|
||||
|
||||
# Legend
|
||||
legend = mcrfpy.Caption(text="TL=TOP_LEFT TC=TOP_CENTER TR=TOP_RIGHT etc.", pos=(100, 520))
|
||||
legend.fill_color = mcrfpy.Color(150, 150, 170)
|
||||
legend.font_size = 14
|
||||
scene.children.append(legend)
|
||||
|
||||
legend2 = mcrfpy.Caption(text="All boxes have margin=15 except CENTER", pos=(100, 545))
|
||||
legend2.fill_color = mcrfpy.Color(150, 150, 170)
|
||||
legend2.font_size = 14
|
||||
scene.children.append(legend2)
|
||||
|
||||
scene.activate()
|
||||
output_path = os.path.join(OUTPUT_DIR, "ui_alignment.png")
|
||||
automation.screenshot(output_path)
|
||||
print(f" -> {output_path}")
|
||||
|
||||
|
||||
def screenshot_dijkstra_heightmap():
|
||||
"""Create a dijkstra-to-heightmap showcase."""
|
||||
scene = mcrfpy.Scene("dijkstra_hmap")
|
||||
|
||||
# Title
|
||||
title = mcrfpy.Caption(text="Dijkstra to HeightMap", pos=(50, 20))
|
||||
title.fill_color = mcrfpy.Color(255, 255, 255)
|
||||
title.font_size = 28
|
||||
scene.children.append(title)
|
||||
|
||||
subtitle = mcrfpy.Caption(text="Distance-based gradients for fog, difficulty, and visualization", pos=(50, 50))
|
||||
subtitle.fill_color = mcrfpy.Color(180, 180, 200)
|
||||
subtitle.font_size = 16
|
||||
scene.children.append(subtitle)
|
||||
|
||||
# Create grid for dijkstra visualization
|
||||
texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16)
|
||||
grid = mcrfpy.Grid(
|
||||
pos=(50, 90),
|
||||
size=(350, 350),
|
||||
grid_size=(16, 16),
|
||||
texture=texture,
|
||||
zoom=1.3
|
||||
)
|
||||
grid.fill_color = mcrfpy.Color(20, 20, 30)
|
||||
scene.children.append(grid)
|
||||
|
||||
# Initialize grid
|
||||
for y in range(16):
|
||||
for x in range(16):
|
||||
grid.at((x, y)).walkable = True
|
||||
grid.at((x, y)).tilesprite = 42 # floor
|
||||
|
||||
# Add some walls
|
||||
for i in range(5, 11):
|
||||
grid.at((i, 5)).walkable = False
|
||||
grid.at((i, 5)).tilesprite = 30 # wall
|
||||
grid.at((5, i)).walkable = False
|
||||
grid.at((5, i)).tilesprite = 30
|
||||
|
||||
# Player at center
|
||||
player = mcrfpy.Entity(grid_pos=(8, 8), texture=texture, sprite_index=84)
|
||||
grid.entities.append(player)
|
||||
|
||||
# Get dijkstra and create color visualization
|
||||
dijkstra = grid.get_dijkstra_map((8, 8))
|
||||
hmap = dijkstra.to_heightmap(unreachable=-1.0)
|
||||
|
||||
# Find max for normalization
|
||||
max_dist = 0
|
||||
for y in range(16):
|
||||
for x in range(16):
|
||||
d = hmap[(x, y)]
|
||||
if d > max_dist and d >= 0:
|
||||
max_dist = d
|
||||
|
||||
# Second visualization panel - color gradient
|
||||
viz_frame = mcrfpy.Frame(pos=(420, 90), size=(350, 350))
|
||||
viz_frame.fill_color = mcrfpy.Color(30, 30, 40)
|
||||
viz_frame.outline = 2
|
||||
viz_frame.outline_color = mcrfpy.Color(60, 60, 80)
|
||||
scene.children.append(viz_frame)
|
||||
|
||||
viz_label = mcrfpy.Caption(text="Distance Visualization", pos=(80, 10))
|
||||
viz_label.fill_color = mcrfpy.Color(200, 200, 220)
|
||||
viz_label.font_size = 16
|
||||
viz_frame.children.append(viz_label)
|
||||
|
||||
# Draw colored squares for each cell
|
||||
cell_size = 20
|
||||
offset_x = 15
|
||||
offset_y = 35
|
||||
|
||||
for y in range(16):
|
||||
for x in range(16):
|
||||
dist = hmap[(x, y)]
|
||||
|
||||
if dist < 0:
|
||||
# Unreachable - dark red
|
||||
color = mcrfpy.Color(60, 0, 0)
|
||||
elif dist == 0:
|
||||
# Source - bright yellow
|
||||
color = mcrfpy.Color(255, 255, 0)
|
||||
else:
|
||||
# Gradient: green (near) to blue (far)
|
||||
t = min(1.0, dist / max_dist)
|
||||
r = 0
|
||||
g = int(200 * (1 - t))
|
||||
b = int(200 * t)
|
||||
color = mcrfpy.Color(r, g, b)
|
||||
|
||||
cell = mcrfpy.Frame(
|
||||
pos=(offset_x + x * cell_size, offset_y + y * cell_size),
|
||||
size=(cell_size - 1, cell_size - 1)
|
||||
)
|
||||
cell.fill_color = color
|
||||
viz_frame.children.append(cell)
|
||||
|
||||
# Legend
|
||||
legend_frame = mcrfpy.Frame(pos=(50, 460), size=(720, 100))
|
||||
legend_frame.fill_color = mcrfpy.Color(30, 30, 40)
|
||||
legend_frame.outline = 1
|
||||
legend_frame.outline_color = mcrfpy.Color(60, 60, 80)
|
||||
scene.children.append(legend_frame)
|
||||
|
||||
leg1 = mcrfpy.Caption(text="Use Cases:", pos=(15, 10))
|
||||
leg1.fill_color = mcrfpy.Color(255, 255, 255)
|
||||
leg1.font_size = 16
|
||||
legend_frame.children.append(leg1)
|
||||
|
||||
uses = [
|
||||
"Distance-based enemy difficulty",
|
||||
"Fog intensity gradients",
|
||||
"Pathfinding visualization",
|
||||
"Influence maps for AI",
|
||||
]
|
||||
for i, use in enumerate(uses):
|
||||
txt = mcrfpy.Caption(text=f"- {use}", pos=(15 + (i // 2) * 350, 35 + (i % 2) * 25))
|
||||
txt.fill_color = mcrfpy.Color(180, 180, 200)
|
||||
txt.font_size = 14
|
||||
legend_frame.children.append(txt)
|
||||
|
||||
# Color key
|
||||
key_label = mcrfpy.Caption(text="Yellow=Source Green=Near Blue=Far Red=Blocked", pos=(420, 450))
|
||||
key_label.fill_color = mcrfpy.Color(150, 150, 170)
|
||||
key_label.font_size = 12
|
||||
scene.children.append(key_label)
|
||||
|
||||
scene.activate()
|
||||
output_path = os.path.join(OUTPUT_DIR, "grid_dijkstra_heightmap.png")
|
||||
automation.screenshot(output_path)
|
||||
print(f" -> {output_path}")
|
||||
|
||||
|
||||
def main():
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
|
||||
print("=== New Features Screenshot Showcase ===")
|
||||
print(f"Output: {OUTPUT_DIR}\n")
|
||||
|
||||
showcases = [
|
||||
('Alignment System', screenshot_alignment),
|
||||
('Dijkstra to HeightMap', screenshot_dijkstra_heightmap),
|
||||
]
|
||||
|
||||
for name, func in showcases:
|
||||
print(f"Generating {name}...")
|
||||
try:
|
||||
func()
|
||||
except Exception as e:
|
||||
print(f" ERROR: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
print("\n=== New feature screenshots generated! ===")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue