Page:
Rendering and Visuals
Pages
AI and Pathfinding
Adding Python Bindings
Animation System
Design Proposals
Development Workflow
Entity Management
Grid Interaction Patterns
Grid Rendering Pipeline
Grid System
Grid TCOD Integration
Headless Mode
Home
Input and Events
Issue Roadmap
Performance Optimization Workflow
Performance and Profiling
Procedural Generation
Proposal: Next Gen Grid Entity System
Python Binding Layer
Rendering and Visuals
Strategic Direction
UI Component Hierarchy
UI Widget Patterns
Writing Tests
1
Rendering and Visuals
John McCardle edited this page 2025-12-02 03:16:49 +00:00
Rendering and Visuals
How to create and display visual elements in McRogueFace.
Quick Reference
Systems: UI-Component-Hierarchy, Grid-System, Animation-System
Key Types:
Frame- Rectangles and containersCaption- Text renderingSprite- Images and sprite sheetsGrid- TilemapsEntity- Grid-based sprites
Basic Rendering
Creating UI Elements
import mcrfpy
# Create scene
mcrfpy.createScene("game")
# Rectangle/Frame
frame = mcrfpy.Frame(100, 100, 200, 150)
frame.fill_color = mcrfpy.Color(50, 50, 50)
frame.outline_color = mcrfpy.Color(255, 255, 255)
frame.outline_thickness = 2
# Text
label = mcrfpy.Caption((10, 10), "Hello World!")
label.font_size = 24
label.fill_color = mcrfpy.Color(255, 255, 255)
# Sprite
sprite = mcrfpy.Sprite("player.png", 50, 50)
sprite.scale_x = 2.0
sprite.scale_y = 2.0
# Add to scene
scene_ui = mcrfpy.sceneUI("game")
scene_ui.append(frame)
scene_ui.append(label)
scene_ui.append(sprite)
Textures and Sprite Sheets
Loading Textures
# Load single image
texture = mcrfpy.createTexture("sprites/player.png")
# Use with sprite
sprite = mcrfpy.Sprite("dummy.png", 0, 0) # Path doesn't matter
sprite.texture = texture
Sprite Sheets
# Load sprite sheet (multiple sprites in one image)
sheet = mcrfpy.createTexture("spritesh eet.png")
# Use specific sprite from sheet
sprite = mcrfpy.Sprite("dummy.png", 100, 100)
sprite.texture = sheet
sprite.sprite_index = 5 # Use 6th sprite (0-indexed)
# Grid with tileset
grid = mcrfpy.Grid(50, 50, 16, 16) # Each tile is 16x16
grid.texture = mcrfpy.createTexture("tileset.png")
# Set tiles
for x in range(50):
for y in range(50):
grid.at((x, y)).tilesprite = 0 # Floor tile
Z-Order Layering
Control render order with z_index (higher = front):
# Background layer (z=0)
background = mcrfpy.Sprite("bg.png", 0, 0)
background.z_index = 0
# Game layer (z=10)
grid = mcrfpy.Grid(50, 50, 16, 16)
grid.z_index = 10
# UI layer (z=100)
hud = mcrfpy.Frame(0, 0, 800, 50)
hud.z_index = 100
# Add to scene (order doesn't matter, z_index controls rendering)
ui = mcrfpy.sceneUI("game")
ui.append(hud)
ui.append(background)
ui.append(grid)
# Renders: background → grid → hud
Implementation: Automatic sorting by z_index in src/Scene.cpp::render()
Colors
Color Creation
# RGB
red = mcrfpy.Color(255, 0, 0)
# RGBA (with alpha/transparency)
semi_transparent = mcrfpy.Color(255, 255, 255, 128)
# Access components
color = mcrfpy.Color(100, 150, 200, 255)
print(f"R: {color.r}, G: {color.g}, B: {color.b}, A: {color.a}")
Color Application
# Frame colors
frame.fill_color = mcrfpy.Color(50, 50, 50)
frame.outline_color = mcrfpy.Color(255, 255, 255)
# Text color
caption.fill_color = mcrfpy.Color(255, 255, 0) # Yellow text
# Grid point colors
grid.at((x, y)).color = mcrfpy.Color(255, 0, 0) # Red tint
# Opacity
sprite.opacity = 0.5 # 50% transparent
Visual Effects
Animations
See Animation-System for complete animation documentation.
# Fade in
mcrfpy.animate(sprite, "opacity", 1.0, 1000, "ease_in_quad")
# Color transition
mcrfpy.animate(frame, "fill_color", mcrfpy.Color(255, 0, 0), 500, "linear")
# Movement
mcrfpy.animate(entity, "x", target_x, 300, "ease_out_cubic")
mcrfpy.animate(entity, "y", target_y, 300, "ease_out_cubic")
# Scaling
mcrfpy.animate(sprite, "scale_x", 2.0, 200, "bounce_out")
Visibility
# Show/hide elements
sprite.visible = False # Hidden
sprite.visible = True # Visible
# Opacity
sprite.opacity = 0.0 # Invisible
sprite.opacity = 0.5 # Semi-transparent
sprite.opacity = 1.0 # Opaque
Common Patterns
HUD/UI Overlay
def create_hud():
# HUD container
hud = mcrfpy.Frame(0, 0, 800, 60)
hud.fill_color = mcrfpy.Color(30, 30, 30, 200)
hud.z_index = 100 # Front layer
# Health text
health_label = mcrfpy.Caption((10, 10), "HP: 100/100")
health_label.font_size = 18
health_label.fill_color = mcrfpy.Color(255, 255, 255)
hud.children.append(health_label)
return hud, health_label
# Update HUD
def update_hud(health_label, current_hp, max_hp):
health_label.text = f"HP: {current_hp}/{max_hp}"
# Color code health
if current_hp < max_hp * 0.3:
health_label.fill_color = mcrfpy.Color(255, 0, 0) # Red
elif current_hp < max_hp * 0.6:
health_label.fill_color = mcrfpy.Color(255, 255, 0) # Yellow
else:
health_label.fill_color = mcrfpy.Color(0, 255, 0) # Green
Particle-Like Effects
def create_explosion(x, y):
"""Create explosion effect using animated sprites."""
particles = []
for i in range(10):
particle = mcrfpy.Sprite("particle.png", x, y)
particle.z_index = 50
# Random direction
import random
target_x = x + random.randint(-50, 50)
target_y = y + random.randint(-50, 50)
# Animate outward
mcrfpy.animate(particle, "x", target_x, 500, "ease_out_quad")
mcrfpy.animate(particle, "y", target_y, 500, "ease_out_quad")
mcrfpy.animate(particle, "opacity", 0.0, 500, "linear")
particles.append(particle)
mcrfpy.sceneUI("game").append(particle)
# Remove after animation
def cleanup(runtime_ms):
for p in particles:
mcrfpy.sceneUI("game").remove(p)
mcrfpy.setTimer("explosion_cleanup", cleanup, 600)
Health Bars
class HealthBar:
def __init__(self, x, y, width, height, max_hp):
self.max_hp = max_hp
self.current_hp = max_hp
# Background (red)
self.bg = mcrfpy.Frame(x, y, width, height)
self.bg.fill_color = mcrfpy.Color(255, 0, 0)
self.bg.z_index = 90
# Foreground (green)
self.fg = mcrfpy.Frame(x, y, width, height)
self.fg.fill_color = mcrfpy.Color(0, 255, 0)
self.fg.z_index = 91
def set_hp(self, current):
self.current_hp = max(0, min(current, self.max_hp))
# Scale foreground to represent HP
ratio = self.current_hp / self.max_hp
target_width = int(self.bg.w * ratio)
# Animate width change
mcrfpy.animate(self.fg, "w", target_width, 200, "ease_out_quad")
# Color code
if ratio < 0.3:
self.fg.fill_color = mcrfpy.Color(255, 0, 0)
elif ratio < 0.6:
self.fg.fill_color = mcrfpy.Color(255, 255, 0)
Grid Rendering
See Grid-System for complete grid documentation.
Basic Grid
# Create grid
grid = mcrfpy.Grid(50, 50, 16, 16)
grid.texture = mcrfpy.createTexture("tiles.png")
grid.pos = (100, 100)
# Set tiles
for x in range(50):
for y in range(50):
if x == 0 or x == 49 or y == 0 or y == 49:
grid.at((x, y)).tilesprite = 1 # Wall
else:
grid.at((x, y)).tilesprite = 0 # Floor
Grid Colors
# Tint specific tiles
grid.at((10, 10)).color = mcrfpy.Color(255, 0, 0) # Red highlight
# Background color
grid.background_color = mcrfpy.Color(8, 8, 8) # Dark background
Grid Viewport
# Zoom
grid.zoom = 2.0 # 2x zoom
# Pan/scroll
grid.left_edge = 10 # Start viewing from tile (10, 0)
grid.top_edge = 5 # Start viewing from tile (0, 5)
# Animate viewport
mcrfpy.animate(grid, "zoom", 1.5, 1000, "ease_in_out_quad")
mcrfpy.animate(grid, "left_edge", 20, 1000, "ease_in_out_quad")
Performance Tips
Minimize Draw Calls
# Good: Group related UI in Frames
hud_frame = mcrfpy.Frame(0, 0, 800, 600)
hud_frame.children.append(label1)
hud_frame.children.append(label2)
hud_frame.children.append(label3)
# Avoid: Many top-level UI elements
# (Each top-level element is a separate draw call)
Use Visibility
# Hide off-screen elements
for element in all_elements:
if not in_viewport(element):
element.visible = False
Sprite Sheet Benefits
# Good: One texture, many sprites
texture = mcrfpy.createTexture("all_sprites.png")
for i in range(100):
sprite = mcrfpy.Sprite("dummy.png", x, y)
sprite.texture = texture # Reuse texture
sprite.sprite_index = i
# Avoid: Loading same texture multiple times
# (Wastes memory and loading time)
Related Documentation
- UI-Component-Hierarchy - UI element details
- Grid-System - Grid rendering details
- Animation-System - Animating visual properties
- Performance-and-Profiling - Rendering performance
API Reference: mcrfpy UI Classes