Add "Rendering-and-Visuals"
parent
e5309322c9
commit
dab5590077
|
|
@ -0,0 +1,386 @@
|
||||||
|
# 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 containers
|
||||||
|
- `Caption` - Text rendering
|
||||||
|
- `Sprite` - Images and sprite sheets
|
||||||
|
- `Grid` - Tilemaps
|
||||||
|
- `Entity` - Grid-based sprites
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Basic Rendering
|
||||||
|
|
||||||
|
### Creating UI Elements
|
||||||
|
|
||||||
|
```python
|
||||||
|
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
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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):
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```python
|
||||||
|
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
|
||||||
|
|
||||||
|
```python
|
||||||
|
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
|
||||||
|
|
||||||
|
```python
|
||||||
|
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
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Hide off-screen elements
|
||||||
|
for element in all_elements:
|
||||||
|
if not in_viewport(element):
|
||||||
|
element.visible = False
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sprite Sheet Benefits
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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](../../docs/api_reference_dynamic.html)
|
||||||
Loading…
Reference in New Issue