Enhance blood stain handling: combine existing and new blood surfaces for better accumulation and add surface management
This commit is contained in:
+17
-4
@@ -47,11 +47,24 @@ class Graphics():
|
||||
if not hasattr(self, 'blood_stains'):
|
||||
self.blood_stains = {}
|
||||
|
||||
# Generate blood surface
|
||||
blood_surface = self.render_engine.generate_blood_surface()
|
||||
self.blood_stains[position] = blood_surface
|
||||
# Generate new blood surface
|
||||
new_blood_surface = self.render_engine.generate_blood_surface()
|
||||
|
||||
# Regenerate background to include the new blood stain
|
||||
if position in self.blood_stains:
|
||||
# If there's already a blood stain at this position, combine them
|
||||
existing_surface = self.blood_stains[position]
|
||||
combined_surface = self.render_engine.combine_blood_surfaces(existing_surface, new_blood_surface)
|
||||
|
||||
# Free the old surfaces
|
||||
self.render_engine.free_surface(existing_surface)
|
||||
self.render_engine.free_surface(new_blood_surface)
|
||||
|
||||
self.blood_stains[position] = combined_surface
|
||||
else:
|
||||
# First blood stain at this position
|
||||
self.blood_stains[position] = new_blood_surface
|
||||
|
||||
# Regenerate background to include the updated blood stain
|
||||
self.regenerate_background()
|
||||
|
||||
def scroll_cursor(self, x=0, y=0):
|
||||
|
||||
+88
-7
@@ -304,13 +304,13 @@ class GameWindow:
|
||||
pixels = cast(blood_surface.contents.pixels, POINTER(c_uint32))
|
||||
pitch = blood_surface.contents.pitch // 4 # pitch in pixel (32-bit)
|
||||
|
||||
# Colori del sangue (variazioni di rosso)
|
||||
# Colori del sangue (variazioni di rosso in formato ABGR)
|
||||
blood_colors = [
|
||||
0xFF8B0000, # Rosso scuro
|
||||
0xFFB22222, # Rosso mattone
|
||||
0xFFDC143C, # Cremisi
|
||||
0xFFFF0000, # Rosso puro
|
||||
0xFF800000, # Marrone
|
||||
0xFF00008B, # Rosso scuro (A=FF, B=00, G=00, R=8B)
|
||||
0xFF002222, # Rosso mattone (A=FF, B=00, G=22, R=22)
|
||||
0xFF003C14, # Cremisi (A=FF, B=00, G=3C, R=14)
|
||||
0xFF0000FF, # Rosso puro (A=FF, B=00, G=00, R=FF)
|
||||
0xFF000080, # Marrone rossastro (A=FF, B=00, G=00, R=80)
|
||||
]
|
||||
|
||||
# Genera la macchia con un algoritmo di diffusione
|
||||
@@ -385,4 +385,85 @@ class GameWindow:
|
||||
# Create texture from the temporary surface
|
||||
texture = self.factory.from_surface(temp_surface)
|
||||
sdl2.SDL_FreeSurface(temp_surface)
|
||||
return texture
|
||||
return texture
|
||||
|
||||
def combine_blood_surfaces(self, existing_surface, new_surface):
|
||||
"""Combine two blood surfaces by blending them together"""
|
||||
# Create a new surface for the combined result
|
||||
combined_surface = sdl2.SDL_CreateRGBSurface(
|
||||
0, self.cell_size, self.cell_size, 32,
|
||||
0x000000FF, # R mask
|
||||
0x0000FF00, # G mask
|
||||
0x00FF0000, # B mask
|
||||
0xFF000000 # A mask
|
||||
)
|
||||
|
||||
if combined_surface is None:
|
||||
return existing_surface
|
||||
|
||||
# Lock both surfaces for pixel manipulation
|
||||
sdl2.SDL_LockSurface(existing_surface)
|
||||
sdl2.SDL_LockSurface(new_surface)
|
||||
sdl2.SDL_LockSurface(combined_surface)
|
||||
|
||||
# Get pixel data
|
||||
existing_pixels = cast(existing_surface.contents.pixels, POINTER(c_uint32))
|
||||
new_pixels = cast(new_surface.contents.pixels, POINTER(c_uint32))
|
||||
combined_pixels = cast(combined_surface.contents.pixels, POINTER(c_uint32))
|
||||
|
||||
pitch = combined_surface.contents.pitch // 4 # pitch in pixels (32-bit)
|
||||
|
||||
# Combine pixels manually for better blending
|
||||
for y in range(self.cell_size):
|
||||
for x in range(self.cell_size):
|
||||
idx = y * pitch + x
|
||||
|
||||
existing_pixel = existing_pixels[idx]
|
||||
new_pixel = new_pixels[idx]
|
||||
|
||||
# Extract RGBA components
|
||||
existing_a = (existing_pixel >> 24) & 0xFF
|
||||
existing_r = (existing_pixel >> 16) & 0xFF
|
||||
existing_g = (existing_pixel >> 8) & 0xFF
|
||||
existing_b = existing_pixel & 0xFF
|
||||
|
||||
new_a = (new_pixel >> 24) & 0xFF
|
||||
new_r = (new_pixel >> 16) & 0xFF
|
||||
new_g = (new_pixel >> 8) & 0xFF
|
||||
new_b = new_pixel & 0xFF
|
||||
|
||||
# Blend the colors (additive blending for blood accumulation)
|
||||
if new_a > 0: # If new pixel has color
|
||||
if existing_a > 0: # If existing pixel has color
|
||||
# Combine both colors, making it darker/more opaque
|
||||
final_r = min(255, existing_r + (new_r // 2))
|
||||
final_g = min(255, existing_g + (new_g // 2))
|
||||
final_b = min(255, existing_b + (new_b // 2))
|
||||
final_a = min(255, existing_a + (new_a // 2))
|
||||
else:
|
||||
# Use new pixel color
|
||||
final_r = new_r
|
||||
final_g = new_g
|
||||
final_b = new_b
|
||||
final_a = new_a
|
||||
else:
|
||||
# Use existing pixel color
|
||||
final_r = existing_r
|
||||
final_g = existing_g
|
||||
final_b = existing_b
|
||||
final_a = existing_a
|
||||
|
||||
# Pack the final pixel
|
||||
combined_pixels[idx] = (final_a << 24) | (final_r << 16) | (final_g << 8) | final_b
|
||||
|
||||
# Unlock surfaces
|
||||
sdl2.SDL_UnlockSurface(existing_surface)
|
||||
sdl2.SDL_UnlockSurface(new_surface)
|
||||
sdl2.SDL_UnlockSurface(combined_surface)
|
||||
|
||||
return combined_surface
|
||||
|
||||
def free_surface(self, surface):
|
||||
"""Safely free an SDL surface"""
|
||||
if surface is not None:
|
||||
sdl2.SDL_FreeSurface(surface)
|
||||
Reference in New Issue
Block a user