|
|
|
@ -1,8 +1,10 @@ |
|
|
|
import os |
|
|
|
import os |
|
|
|
|
|
|
|
import random |
|
|
|
import sdl2 |
|
|
|
import sdl2 |
|
|
|
import sdl2.ext |
|
|
|
import sdl2.ext |
|
|
|
from sdl2.ext.compat import byteify |
|
|
|
from sdl2.ext.compat import byteify |
|
|
|
from ctypes import * |
|
|
|
from ctypes import * |
|
|
|
|
|
|
|
import ctypes |
|
|
|
|
|
|
|
|
|
|
|
from PIL import Image |
|
|
|
from PIL import Image |
|
|
|
from sdl2 import SDL_AudioSpec |
|
|
|
from sdl2 import SDL_AudioSpec |
|
|
|
@ -47,7 +49,9 @@ class GameWindow: |
|
|
|
self.audio_devs["base"] = sdl2.SDL_OpenAudioDevice(None, 0, SDL_AudioSpec(freq=22050, aformat=sdl2.AUDIO_U8, channels=1, samples=2048), None, 0) |
|
|
|
self.audio_devs["base"] = sdl2.SDL_OpenAudioDevice(None, 0, SDL_AudioSpec(freq=22050, aformat=sdl2.AUDIO_U8, channels=1, samples=2048), None, 0) |
|
|
|
self.audio_devs["effects"] = sdl2.SDL_OpenAudioDevice(None, 0, SDL_AudioSpec(freq=22050, aformat=sdl2.AUDIO_U8, channels=1, samples=2048), None, 0) |
|
|
|
self.audio_devs["effects"] = sdl2.SDL_OpenAudioDevice(None, 0, SDL_AudioSpec(freq=22050, aformat=sdl2.AUDIO_U8, channels=1, samples=2048), None, 0) |
|
|
|
self.audio_devs["music"] = sdl2.SDL_OpenAudioDevice(None, 0, SDL_AudioSpec(freq=22050, aformat=sdl2.AUDIO_U8, channels=1, samples=2048), None, 0) |
|
|
|
self.audio_devs["music"] = sdl2.SDL_OpenAudioDevice(None, 0, SDL_AudioSpec(freq=22050, aformat=sdl2.AUDIO_U8, channels=1, samples=2048), None, 0) |
|
|
|
|
|
|
|
|
|
|
|
def create_texture(self, tiles: list): |
|
|
|
def create_texture(self, tiles: list): |
|
|
|
|
|
|
|
# Always create a fresh surface since we free it after use |
|
|
|
bg_surface = sdl2.SDL_CreateRGBSurface(0, self.width, self.height, 32, 0, 0, 0, 0) |
|
|
|
bg_surface = sdl2.SDL_CreateRGBSurface(0, self.width, self.height, 32, 0, 0, 0, 0) |
|
|
|
for tile in tiles: |
|
|
|
for tile in tiles: |
|
|
|
dstrect = sdl2.SDL_Rect(tile[1], tile[2], self.cell_size, self.cell_size) |
|
|
|
dstrect = sdl2.SDL_Rect(tile[1], tile[2], self.cell_size, self.cell_size) |
|
|
|
@ -274,3 +278,111 @@ class GameWindow: |
|
|
|
|
|
|
|
|
|
|
|
def get_view_center(self): |
|
|
|
def get_view_center(self): |
|
|
|
return self.w_offset + self.width // 2, self.h_offset + self.height // 2 |
|
|
|
return self.w_offset + self.width // 2, self.h_offset + self.height // 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def generate_blood_surface(self): |
|
|
|
|
|
|
|
"""Genera dinamicamente una superficie di macchia di sangue usando SDL2""" |
|
|
|
|
|
|
|
size = self.cell_size |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Crea una superficie RGBA per la macchia di sangue |
|
|
|
|
|
|
|
blood_surface = sdl2.SDL_CreateRGBSurface( |
|
|
|
|
|
|
|
0, size, size, 32, |
|
|
|
|
|
|
|
0x000000FF, # R mask |
|
|
|
|
|
|
|
0x0000FF00, # G mask |
|
|
|
|
|
|
|
0x00FF0000, # B mask |
|
|
|
|
|
|
|
0xFF000000 # A mask |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not blood_surface: |
|
|
|
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Blocca la superficie per il disegno pixel per pixel |
|
|
|
|
|
|
|
sdl2.SDL_LockSurface(blood_surface) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Ottieni i dati dei pixel |
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
blood_colors = [ |
|
|
|
|
|
|
|
0xFF8B0000, # Rosso scuro |
|
|
|
|
|
|
|
0xFFB22222, # Rosso mattone |
|
|
|
|
|
|
|
0xFFDC143C, # Cremisi |
|
|
|
|
|
|
|
0xFFFF0000, # Rosso puro |
|
|
|
|
|
|
|
0xFF800000, # Marrone |
|
|
|
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Genera la macchia con un algoritmo di diffusione |
|
|
|
|
|
|
|
center_x, center_y = size // 2, size // 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Inizia dal centro e espandi verso l'esterno |
|
|
|
|
|
|
|
max_radius = size // 3 + random.randint(-3, 5) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for y in range(size): |
|
|
|
|
|
|
|
for x in range(size): |
|
|
|
|
|
|
|
# Calcola la distanza dal centro |
|
|
|
|
|
|
|
distance = ((x - center_x) ** 2 + (y - center_y) ** 2) ** 0.5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Probabilità di avere sangue basata sulla distanza |
|
|
|
|
|
|
|
if distance <= max_radius: |
|
|
|
|
|
|
|
# Più vicino al centro, più probabile avere sangue |
|
|
|
|
|
|
|
probability = max(0, 1 - (distance / max_radius)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Aggiungi rumore per forma irregolare |
|
|
|
|
|
|
|
noise = random.random() * 0.7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if random.random() < probability * noise: |
|
|
|
|
|
|
|
# Scegli un colore di sangue casuale |
|
|
|
|
|
|
|
color = random.choice(blood_colors) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Aggiungi variazione di alpha per trasparenza |
|
|
|
|
|
|
|
alpha = int(255 * probability * random.uniform(0.6, 1.0)) |
|
|
|
|
|
|
|
color = (color & 0x00FFFFFF) | (alpha << 24) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pixels[y * pitch + x] = color |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
# Pixel trasparente |
|
|
|
|
|
|
|
pixels[y * pitch + x] = 0x00000000 |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
# Fuori dal raggio, trasparente |
|
|
|
|
|
|
|
pixels[y * pitch + x] = 0x00000000 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Aggiungi alcune gocce sparse intorno alla macchia principale |
|
|
|
|
|
|
|
for _ in range(random.randint(3, 8)): |
|
|
|
|
|
|
|
drop_x = center_x + random.randint(-max_radius - 5, max_radius + 5) |
|
|
|
|
|
|
|
drop_y = center_y + random.randint(-max_radius - 5, max_radius + 5) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if 0 <= drop_x < size and 0 <= drop_y < size: |
|
|
|
|
|
|
|
drop_size = random.randint(1, 3) |
|
|
|
|
|
|
|
for dy in range(-drop_size, drop_size + 1): |
|
|
|
|
|
|
|
for dx in range(-drop_size, drop_size + 1): |
|
|
|
|
|
|
|
nx, ny = drop_x + dx, drop_y + dy |
|
|
|
|
|
|
|
if 0 <= nx < size and 0 <= ny < size: |
|
|
|
|
|
|
|
if random.random() < 0.6: |
|
|
|
|
|
|
|
color = random.choice(blood_colors[:3]) # Colori più scuri per le gocce |
|
|
|
|
|
|
|
alpha = random.randint(100, 200) |
|
|
|
|
|
|
|
color = (color & 0x00FFFFFF) | (alpha << 24) |
|
|
|
|
|
|
|
pixels[ny * pitch + nx] = color |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Sblocca la superficie |
|
|
|
|
|
|
|
sdl2.SDL_UnlockSurface(blood_surface) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Converte la superficie in una texture usando il factory del gioco |
|
|
|
|
|
|
|
return blood_surface |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def draw_blood_surface(self, blood_surface, position): |
|
|
|
|
|
|
|
# Create a new surface for the blood texture since bg_surface may have been freed |
|
|
|
|
|
|
|
temp_surface = sdl2.SDL_CreateRGBSurface(0, self.cell_size, self.cell_size, 32, 0, 0, 0, 0) |
|
|
|
|
|
|
|
if temp_surface is None: |
|
|
|
|
|
|
|
sdl2.SDL_FreeSurface(blood_surface) |
|
|
|
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Copy the blood surface to the temporary surface |
|
|
|
|
|
|
|
sdl2.SDL_BlitSurface(blood_surface, None, temp_surface, None) |
|
|
|
|
|
|
|
sdl2.SDL_FreeSurface(blood_surface) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Create texture from the temporary surface |
|
|
|
|
|
|
|
texture = self.factory.from_surface(temp_surface) |
|
|
|
|
|
|
|
sdl2.SDL_FreeSurface(temp_surface) |
|
|
|
|
|
|
|
return texture |