ColorLayer
Grid layer storing RGBA colors per cell.
Overview
A ColorLayer stores color data for each cell in a Grid. Use color layers for lighting effects, fog of war visualization, terrain tinting, or any per-cell color overlay. Color layers can be stacked with tile layers using z-index ordering.
Quick Reference
# Create standalone, then attach to a Grid
color_layer = mcrfpy.ColorLayer(z_index=1, name="tint")
grid.add_layer(color_layer)
# Set individual cell colors
color_layer.set((5, 5), mcrfpy.Color(255, 0, 0, 128)) # Semi-transparent red
# Fill entire layer
color_layer.fill(mcrfpy.Color(0, 0, 0, 200)) # Dark overlay
# Fill rectangular region
color_layer.fill_rect((10, 10), (20, 20), mcrfpy.Color(50, 50, 100))
# Get cell color
cell_color = color_layer.at((5, 5))
# FOV visualization
color_layer.draw_fov((player_x, player_y), radius=8) # Paint FOV-based visibility colors
Constructor
ColorLayer is created directly, then attached to a Grid with Grid.add_layer()
(or passed via the Grid constructor’s layers= list). A layer created with
grid_size=None (or (0, 0)) auto-resizes to match the Grid when attached.
color_layer = mcrfpy.ColorLayer(z_index=1, name="tint")
grid.add_layer(color_layer)
# Or supply it at construction time
grid = mcrfpy.Grid(grid_size=(80, 45), layers=[color_layer])
Full signature:
mcrfpy.ColorLayer(z_index=-1, name=None, grid_size=None)
| Parameter | Type | Default | Description |
|---|---|---|---|
z_index |
int | -1 | Rendering order relative to entities (negative = background, positive = overlay) |
name |
str | None | Layer name for Grid.layer(name) lookup |
grid_size |
tuple | None | Size (w, h); auto-resizes to match the Grid if None or (0, 0) |
Properties
| Property | Type | Description |
|---|---|---|
z_index |
int | Rendering order relative to entities |
name |
str | Layer name for lookup, read-only |
visible |
bool | Visibility toggle |
grid_size |
tuple | Layer dimensions (w, h), read-only |
grid |
Grid | None | Parent Grid; setting it manages layer association |
Methods
| Method | Description |
|---|---|
at(pos) |
Get Color at cell position |
set(pos, color) |
Set Color at cell position |
fill(color) |
Fill entire layer with color |
fill_rect(pos, size, color) |
Fill rectangular region |
draw_fov(source, radius=None, fov=None, visible=None, discovered=None, unknown=None) |
Paint cells by FOV visibility from source (an (x, y) cell) |
apply_perspective(entity, visible=None, discovered=None, unknown=None) |
Bind layer to an entity for automatic FOV-based coloring |
update_perspective() |
Redraw FOV colors after the bound entity moves |
clear_perspective() |
Remove the perspective binding |
apply_threshold(source, range, color) -> ColorLayer |
Set a fixed color for cells whose heightmap value falls in range |
apply_gradient(source, range, color_low, color_high) -> ColorLayer |
Interpolate color across a heightmap value range |
apply_ranges(source, ranges) -> ColorLayer |
Apply multiple threshold/gradient ranges in one pass |
edit() |
Context manager exposing a zero-copy writable numpy view, shape (h, w, 4), dtype uint8 |
Usage Patterns
Fog of War
# Create darkness layer
fog = mcrfpy.ColorLayer(z_index=10, name="fog")
grid.add_layer(fog)
fog.fill(mcrfpy.Color(0, 0, 0, 255)) # Start fully dark
# Update when the player moves: paint FOV-based visibility colors
def update_fov(player):
fog.draw_fov((player.cell_pos.x, player.cell_pos.y), radius=8,
visible=mcrfpy.Color(0, 0, 0, 0), # fully lit
discovered=mcrfpy.Color(0, 0, 0, 160), # dimmed memory
unknown=mcrfpy.Color(0, 0, 0, 255)) # fully dark
For fog that updates automatically whenever a specific entity moves, bind the
layer to it instead of calling draw_fov() manually:
fog.apply_perspective(player, visible=mcrfpy.Color(0, 0, 0, 0),
discovered=mcrfpy.Color(0, 0, 0, 160),
unknown=mcrfpy.Color(0, 0, 0, 255))
# ... after the player moves:
fog.update_perspective()
Lighting Effects
light_layer = mcrfpy.ColorLayer(z_index=5, name="lights")
grid.add_layer(light_layer)
def add_light(x, y, color, radius):
for dx in range(-radius, radius + 1):
for dy in range(-radius, radius + 1):
dist = (dx*dx + dy*dy) ** 0.5
if dist <= radius:
alpha = int(255 * (1 - dist / radius))
light_layer.set((x + dx, y + dy),
mcrfpy.Color(color.r, color.g, color.b, alpha))
Heightmap Visualization
color_layer = mcrfpy.ColorLayer(z_index=0, name="terrain")
grid.add_layer(color_layer)
# Color by height threshold (one call per range)
color_layer.apply_threshold(heightmap, range=(0.0, 0.5), color=mcrfpy.Color(0, 0, 100)) # Water (blue)
color_layer.apply_threshold(heightmap, range=(0.5, 1.0), color=mcrfpy.Color(0, 100, 0)) # Land (green)
# Or use a smooth gradient across the whole range
color_layer.apply_gradient(
heightmap,
range=(0.0, 1.0),
color_low=mcrfpy.Color(0, 0, 150), # Low = deep water
color_high=mcrfpy.Color(200, 200, 200) # High = mountain
)