Update "Rendering-and-Visuals.-"
parent
3cbfcf060b
commit
e2a4e179fa
2 changed files with 370 additions and 386 deletions
370
Rendering-and-Visuals.-.md
Normal file
370
Rendering-and-Visuals.-.md
Normal file
|
|
@ -0,0 +1,370 @@
|
||||||
|
# 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 with layers
|
||||||
|
- `Entity` - Grid-based sprites
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Basic Rendering
|
||||||
|
|
||||||
|
### Creating UI Elements
|
||||||
|
|
||||||
|
```python
|
||||||
|
import mcrfpy
|
||||||
|
|
||||||
|
# Create scene
|
||||||
|
scene = mcrfpy.Scene("game")
|
||||||
|
ui = scene.children
|
||||||
|
|
||||||
|
# Rectangle/Frame
|
||||||
|
frame = mcrfpy.Frame(pos=(100, 100), size=(200, 150),
|
||||||
|
fill_color=mcrfpy.Color(50, 50, 50))
|
||||||
|
frame.outline_color = mcrfpy.Color(255, 255, 255)
|
||||||
|
frame.outline = 2
|
||||||
|
ui.append(frame)
|
||||||
|
|
||||||
|
# Text
|
||||||
|
label = mcrfpy.Caption(text="Hello World!", pos=(10, 10))
|
||||||
|
label.font_size = 24
|
||||||
|
label.fill_color = mcrfpy.Color(255, 255, 255)
|
||||||
|
ui.append(label)
|
||||||
|
|
||||||
|
# Sprite
|
||||||
|
sprite = mcrfpy.Sprite(x=50, y=50, sprite_index=0)
|
||||||
|
ui.append(sprite)
|
||||||
|
|
||||||
|
mcrfpy.current_scene = scene
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Textures and Sprite Sheets
|
||||||
|
|
||||||
|
### Loading Textures
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Load a sprite sheet with tile dimensions
|
||||||
|
texture = mcrfpy.Texture("assets/sprites/tileset.png", 16, 16)
|
||||||
|
|
||||||
|
# Use with sprite
|
||||||
|
sprite = mcrfpy.Sprite(x=100, y=100)
|
||||||
|
sprite.texture = texture
|
||||||
|
sprite.sprite_index = 5 # Use 6th sprite (0-indexed)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sprite Sheets with Grids
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Load tileset for grid layers
|
||||||
|
texture = mcrfpy.Texture("assets/sprites/tileset.png", 16, 16)
|
||||||
|
terrain = mcrfpy.TileLayer(name="terrain", z_index=-1, texture=texture)
|
||||||
|
|
||||||
|
grid = mcrfpy.Grid(grid_size=(50, 50), pos=(100, 100), size=(400, 400),
|
||||||
|
layers=[terrain])
|
||||||
|
|
||||||
|
# Set tiles using the TileLayer
|
||||||
|
for x in range(50):
|
||||||
|
for y in range(50):
|
||||||
|
terrain.set((x, y), 0) # Floor tile index
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Z-Order Layering
|
||||||
|
|
||||||
|
Control render order with `z_index` (higher = front):
|
||||||
|
|
||||||
|
```python
|
||||||
|
scene = mcrfpy.Scene("game")
|
||||||
|
ui = scene.children
|
||||||
|
|
||||||
|
# Background layer (z=0)
|
||||||
|
background = mcrfpy.Frame(pos=(0, 0), size=(800, 600),
|
||||||
|
fill_color=mcrfpy.Color(20, 20, 20))
|
||||||
|
background.z_index = 0
|
||||||
|
ui.append(background)
|
||||||
|
|
||||||
|
# Game layer (z=10)
|
||||||
|
grid = mcrfpy.Grid(grid_size=(50, 50), pos=(50, 50), size=(700, 500))
|
||||||
|
grid.z_index = 10
|
||||||
|
ui.append(grid)
|
||||||
|
|
||||||
|
# UI layer (z=100)
|
||||||
|
hud = mcrfpy.Frame(pos=(0, 0), size=(800, 50),
|
||||||
|
fill_color=mcrfpy.Color(30, 30, 30, 200))
|
||||||
|
hud.z_index = 100
|
||||||
|
ui.append(hud)
|
||||||
|
|
||||||
|
# Renders: background -> grid -> hud
|
||||||
|
mcrfpy.current_scene = scene
|
||||||
|
```
|
||||||
|
|
||||||
|
**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)
|
||||||
|
# color.r, color.g, color.b, 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
|
||||||
|
|
||||||
|
# Opacity
|
||||||
|
sprite.opacity = 0.5 # 50% transparent
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Visual Effects
|
||||||
|
|
||||||
|
### Animations
|
||||||
|
|
||||||
|
See [[Animation-System]] for complete animation documentation.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Fade in
|
||||||
|
frame.animate("opacity", 1.0, 1.0, mcrfpy.Easing.EASE_IN_QUAD)
|
||||||
|
|
||||||
|
# Color transition
|
||||||
|
frame.animate("fill_color", (255, 0, 0, 255), 0.5, mcrfpy.Easing.LINEAR)
|
||||||
|
|
||||||
|
# Movement
|
||||||
|
frame.animate("x", 500.0, 0.3, mcrfpy.Easing.EASE_OUT_CUBIC)
|
||||||
|
frame.animate("y", 300.0, 0.3, mcrfpy.Easing.EASE_OUT_CUBIC)
|
||||||
|
|
||||||
|
# With completion callback
|
||||||
|
def on_done(target, prop, value):
|
||||||
|
print(f"{prop} reached {value}")
|
||||||
|
frame.animate("x", 500.0, 0.3, mcrfpy.Easing.EASE_OUT_CUBIC, callback=on_done)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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(scene):
|
||||||
|
ui = scene.children
|
||||||
|
|
||||||
|
hud = mcrfpy.Frame(pos=(0, 0), size=(800, 60),
|
||||||
|
fill_color=mcrfpy.Color(30, 30, 30, 200))
|
||||||
|
hud.z_index = 100
|
||||||
|
ui.append(hud)
|
||||||
|
|
||||||
|
health_label = mcrfpy.Caption(text="HP: 100/100", pos=(10, 10))
|
||||||
|
health_label.font_size = 18
|
||||||
|
health_label.fill_color = mcrfpy.Color(255, 255, 255)
|
||||||
|
hud.children.append(health_label)
|
||||||
|
|
||||||
|
return health_label
|
||||||
|
|
||||||
|
def update_hud(health_label, current_hp, max_hp):
|
||||||
|
health_label.text = f"HP: {current_hp}/{max_hp}"
|
||||||
|
|
||||||
|
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(scene, x, y):
|
||||||
|
"""Create explosion effect using animated frames."""
|
||||||
|
import random
|
||||||
|
ui = scene.children
|
||||||
|
particles = []
|
||||||
|
|
||||||
|
for i in range(10):
|
||||||
|
p = mcrfpy.Frame(pos=(x, y), size=(4, 4),
|
||||||
|
fill_color=mcrfpy.Color(255, 200, 50))
|
||||||
|
p.z_index = 50
|
||||||
|
|
||||||
|
target_x = x + random.randint(-50, 50)
|
||||||
|
target_y = y + random.randint(-50, 50)
|
||||||
|
|
||||||
|
p.animate("x", float(target_x), 0.5, mcrfpy.Easing.EASE_OUT_QUAD)
|
||||||
|
p.animate("y", float(target_y), 0.5, mcrfpy.Easing.EASE_OUT_QUAD)
|
||||||
|
p.animate("opacity", 0.0, 0.5, mcrfpy.Easing.LINEAR)
|
||||||
|
|
||||||
|
particles.append(p)
|
||||||
|
ui.append(p)
|
||||||
|
|
||||||
|
# Cleanup after animation
|
||||||
|
def cleanup(runtime):
|
||||||
|
for p in particles:
|
||||||
|
ui.remove(p)
|
||||||
|
timer = mcrfpy.Timer("explosion_cleanup", cleanup, 600)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Health Bars
|
||||||
|
|
||||||
|
```python
|
||||||
|
class HealthBar:
|
||||||
|
def __init__(self, parent, pos, width, height, max_hp):
|
||||||
|
self.max_hp = max_hp
|
||||||
|
self.width = width
|
||||||
|
|
||||||
|
# Background (red)
|
||||||
|
self.bg = mcrfpy.Frame(pos=pos, size=(width, height),
|
||||||
|
fill_color=mcrfpy.Color(255, 0, 0))
|
||||||
|
self.bg.z_index = 90
|
||||||
|
parent.children.append(self.bg)
|
||||||
|
|
||||||
|
# Foreground (green)
|
||||||
|
self.fg = mcrfpy.Frame(pos=pos, size=(width, height),
|
||||||
|
fill_color=mcrfpy.Color(0, 255, 0))
|
||||||
|
self.fg.z_index = 91
|
||||||
|
parent.children.append(self.fg)
|
||||||
|
|
||||||
|
def set_hp(self, current):
|
||||||
|
current = max(0, min(current, self.max_hp))
|
||||||
|
ratio = current / self.max_hp
|
||||||
|
target_width = int(self.width * ratio)
|
||||||
|
|
||||||
|
self.fg.animate("w", float(target_width), 0.2,
|
||||||
|
mcrfpy.Easing.EASE_OUT_QUAD)
|
||||||
|
|
||||||
|
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
|
||||||
|
# Load tileset
|
||||||
|
texture = mcrfpy.Texture("assets/sprites/tileset.png", 16, 16)
|
||||||
|
terrain = mcrfpy.TileLayer(name="terrain", z_index=-1, texture=texture)
|
||||||
|
|
||||||
|
# Create grid with layer
|
||||||
|
grid = mcrfpy.Grid(grid_size=(50, 50), pos=(100, 100), size=(400, 400),
|
||||||
|
layers=[terrain])
|
||||||
|
|
||||||
|
# Set tiles via the TileLayer
|
||||||
|
for x in range(50):
|
||||||
|
for y in range(50):
|
||||||
|
if x == 0 or x == 49 or y == 0 or y == 49:
|
||||||
|
terrain.set((x, y), 1) # Wall
|
||||||
|
else:
|
||||||
|
terrain.set((x, y), 0) # Floor
|
||||||
|
```
|
||||||
|
|
||||||
|
### Grid Viewport
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Zoom
|
||||||
|
grid.zoom = 2.0
|
||||||
|
|
||||||
|
# Center camera on tile coordinates
|
||||||
|
grid.center_camera((25, 25))
|
||||||
|
|
||||||
|
# Animate viewport
|
||||||
|
grid.animate("zoom", 1.5, 1.0, mcrfpy.Easing.EASE_IN_OUT)
|
||||||
|
grid.animate("center_x", 100.0, 1.0, mcrfpy.Easing.EASE_IN_OUT)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Performance Tips
|
||||||
|
|
||||||
|
### Minimize Draw Calls
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Good: Group related UI in Frames
|
||||||
|
hud_frame = mcrfpy.Frame(pos=(0, 0), size=(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
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reuse Textures
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Good: One texture, many sprites
|
||||||
|
texture = mcrfpy.Texture("assets/sprites/all_sprites.png", 16, 16)
|
||||||
|
for i in range(100):
|
||||||
|
sprite = mcrfpy.Sprite(x=i * 20, y=0)
|
||||||
|
sprite.texture = texture
|
||||||
|
sprite.sprite_index = i
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
- [[UI-Component-Hierarchy]] - UI element details
|
||||||
|
- [[Grid-System]] - Grid rendering details
|
||||||
|
- [[Animation-System]] - Animating visual properties
|
||||||
|
- [[Performance-and-Profiling]] - Rendering performance
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Last updated: 2026-02-07*
|
||||||
|
|
@ -1,386 +0,0 @@
|
||||||
# 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…
Add table
Add a link
Reference in a new issue