Add semi-transparent tunnel cover overlay for internal passages

- Add sdl2.create_overlay_texture() and draw_overlay_texture(alpha) for
  transparent full-map overlays built from sub-tile surface blits.
- Add Graphics.regenerate_tunnel_cover() which builds an overlay of
  4 random grass sub-tiles (20x20) for every internal tunnel cell,
  defined as a tunnel cell surrounded by occupied cells (wall or
  tunnel) on all four sides. Cells with at least one open side are
  handled by cave_foreground and skipped here.
- Draw the tunnel cover in the game loop after top-layer units/effects
  but before cave_foreground and points, at 95% opacity (alpha=242)
  so the unit and effect passing underneath is just barely visible.
This commit is contained in:
Matteo Benedetto
2026-06-16 23:06:17 +02:00
parent 62a65f599d
commit 2eccf504f5
3 changed files with 104 additions and 1 deletions
+42
View File
@@ -26,6 +26,8 @@ class Graphics:
self.blood_layer_sprites = []
if not hasattr(self, "cave_foreground_tiles"):
self.cave_foreground_tiles = []
if not hasattr(self, "tunnel_cover_texture"):
self.tunnel_cover_texture = None
if not getattr(self, "common_assets_loaded", False):
print("Loading graphics assets...")
@@ -194,6 +196,45 @@ class Graphics:
# Draw blood layer as sprites (optimized - no background regeneration)
self.draw_blood_layer()
def regenerate_tunnel_cover(self):
"""Generate an overlay texture that covers internal tunnel passages with grass sub-tiles.
A tunnel cell is considered an internal passage only when it is surrounded
by occupied cells (walls or tunnels) on all four sides. In that case there is
no cave entrance drawn by cave_foreground, so we cover it here.
"""
tunnel_tiles = []
half_cell = self.game.cell_size // 2
def occupied(x, y):
return self.game.map.in_bounds(x, y) and self.game.map.get_cell(x, y) != maze.MAP_EMPTY
for y, row in enumerate(self.game.map.tiles):
for x, cell in enumerate(row):
if cell != maze.MAP_TUNNEL:
continue
above = occupied(x, y - 1)
below = occupied(x, y + 1)
left = occupied(x - 1, y)
right = occupied(x + 1, y)
if not (above and below and left and right):
continue
px = x * self.game.cell_size
py = y * self.game.cell_size
for qx, qy, sx, sy in [
(0, 0, 0, 0),
(half_cell, 0, half_cell, 0),
(0, half_cell, 0, half_cell),
(half_cell, half_cell, half_cell, half_cell),
]:
grass = random.choice(self.grasses)
tunnel_tiles.append((grass, sx, sy, half_cell, half_cell, px + qx, py + qy))
self.tunnel_cover_texture = self.game.render_engine.create_overlay_texture(tunnel_tiles)
def draw_cave_foreground(self):
active_cave_explosions = {}
for unit in self.game.units.values():
@@ -218,6 +259,7 @@ class Graphics:
"""Generate or regenerate the background texture (static - no blood stains)"""
texture_tiles = []
self.cave_foreground_tiles = []
self.regenerate_tunnel_cover()
half_cell = self.game.cell_size // 2
def draw(surface, x, y):