You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

18 KiB

Capitolo 8: Personalizzazione e Configurazione

File di Configurazione

Tutto è configurabile tramite config/settings.py. Non serve modificare il codice sorgente!

Modificare le Dimensioni del Terreno

Grid Size (Numero di Tiles)

TERRAIN = {
    'grid_size': 20,  # Griglia 20×20
    ...
}

Effetti

grid_size = 10:          grid_size = 30:
┌────────────┐           ┌────────────────────┐
│ 10×10      │           │      30×30         │
│  tiles     │           │    molte tiles     │
│            │           │                    │
└────────────┘           └────────────────────┘
Meno dettaglio           Più dettaglio
Più veloce               Più lento

Consigli

  • 10×10: Test rapidi, PC lenti
  • 20×20: Bilanciato (default)
  • 30×30: Dettaglio alto
  • 50×50: Molto dettagliato, richiede PC potente

Dimensione Tile

TERRAIN = {
    'tile_width': 30,   # Larghezza in pixel
    'tile_height': 30,  # Altezza in pixel
    ...
}

Effetti

tile_size = 20:          tile_size = 40:
    Small tiles              Big tiles
    ╱╲╱╲╱╲                   ╱──╲╱──╲
   ╱╲╱╲╱╲╱                  ╱────╲──╱
  ╱╲╱╲╱╲╱╲                 ╱──────╲╱

Nota: Se cambi tile_size, adatta anche la camera!

# tile_size piccole → camera più vicina
CAMERA = {
    'distance': 400,  # Invece di 800
    'height': 200,    # Invece di 450
}

Modificare il Terreno

Scala Perlin Noise

TERRAIN = {
    'perlin_scale': 8.0,  # IMPORTANTE!
    ...
}

Effetti

scale = 3.0:                scale = 15.0:
 Grandi formazioni          Piccole colline
   ╱╲____╱╲                  ╱╲╱╲╱╲╱╲
  ╱  ────  ╲                ╱╲╱╲╱╲╱╲╱
 ╱          ╲              ╱╲╱╲╱╲╱╲╱╲
Montagne ampie             Terreno mosso

Regola: scale ≈ grid_size / 2.5

  • Grid 10×10 → scale = 4.0
  • Grid 20×20 → scale = 8.0
  • Grid 30×30 → scale = 12.0
  • Grid 50×50 → scale = 20.0

Moltiplicatore Altezza

TERRAIN = {
    'height_multiplier': 80.0,
    ...
}

Effetti

multiplier = 30:           multiplier = 150:
   Colline basse              Montagne alte
    ___╱╲___                      ╱╲
  ╱        ╲                     ╱  ╲
 ╱__________╲                   ╱    ╲
                               ╱______╲

Consigli:

  • 30-50: Terreno pianeggiante
  • 60-80: Colline (default)
  • 100-150: Montagne
  • 200+: Drammatico, picchi estremi

Octaves (Dettaglio)

TERRAIN = {
    'perlin_octaves': 4,
    ...
}

Effetti

octaves = 1:               octaves = 6:
  Forma base                 Molti dettagli
   ╱╲                          ╱╲╱╲
  ╱  ╲                       ╱╲╱╲╱╲
 ╱    ╲                     ╱╲╱╲╱╲╱╲
Liscio                    Complesso
Veloce                    Lento

Consigli:

  • 1-2: Forme grandi e semplici
  • 3-4: Bilanciato (default)
  • 5-6: Molto dettagliato
  • 7+: Estremo, rallenta

Persistence (Influenza Dettagli)

TERRAIN = {
    'perlin_persistence': 0.6,
    ...
}

Effetti

persistence = 0.3:         persistence = 0.8:
  Dettagli deboli           Dettagli forti
     ╱╲____                    ╱╲╱╲╱╲
   ╱╲    ╱╲                  ╱╲╱╲╱╲╱╲
  ╱  ────  ╲                ╱╲╱╲╱╲╱╲╱
Forme larghe              Texture ruvida

Range: 0.0 - 1.0

  • 0.3-0.4: Liscio
  • 0.5-0.6: Bilanciato (default)
  • 0.7-0.8: Ruvido

Lacunarity (Frequenza Dettagli)

TERRAIN = {
    'perlin_lacunarity': 2.5,
    ...
}

Effetti

lacunarity = 1.5:         lacunarity = 3.0:
  Dettagli sparsi          Dettagli densi
    ╱╲  ╱╲                   ╱╲╱╲╱╲
   ╱  ──  ╲                 ╱╲╱╲╱╲╱
  ╱        ╲               ╱╲╱╲╱╲╱╲

Range: 1.0 - 4.0

  • 1.5-2.0: Dettagli distanziati
  • 2.0-2.5: Bilanciato (default)
  • 2.5-3.0: Dettagli fitti

Smoothing (Levigatura)

TERRAIN = {
    'enable_smoothing': False,  # Default: disabilitato
    'smoothing_iterations': 2,
    'smoothing_factor': 0.5,
    ...
}

Effetti

Smoothing OFF:            Smoothing ON:
    ╱╲╱╲                      ╱──╲
   ╱╲╱╲╱╲                    ╱    ╲
  ╱╲╱╲╱╲╱                   ╱      ╲
Originale Perlin          Levigato

Nota: Lo smoothing riduce le caratteristiche uniche del Perlin noise!

Configurare la Camera

Distanza e Altezza

CAMERA = {
    'distance': 800,
    'height': 450,
    ...
}

Visualizzazione

Distanza piccola (400):   Distanza grande (1200):
      Camera                    Camera
        ●                           ●
       ╱│                          ╱│
      ╱ │                         ╱ │
     ╱  │                        ╱  │
  Terreno                     Terreno
  Vista vicina                Vista lontana
  Dettaglio alto              Panoramica

Altezza: Quanto "sopra" il terreno

  • Bassa (200): Vista laterale
  • Media (450): Vista isometrica (default)
  • Alta (800): Vista dall'alto

Velocità Controlli

CAMERA = {
    'zoom_speed': 10.0,     # Velocità zoom (UP/DOWN)
    'height_speed': 10.0,   # Velocità altezza (LEFT/RIGHT)
    ...
}

Consigli:

  • 5.0: Controlli lenti, precisi
  • 10.0: Bilanciato (default)
  • 20.0: Controlli veloci

Field of View

CAMERA = {
    'fov': 45,  # Gradi
    ...
}

Effetti

FOV = 30:                 FOV = 70:
   Zoom in                  Zoom out
     │╲                       ╲___
     │ ╲                      │   ___
     │  ╲                     │      ___
  Teleobiettivo            Grandangolo

Range: 30-90

  • 30-40: Zoom, distorsione minima
  • 45: Bilanciato (default)
  • 60-90: Grandangolo, più distorsione

Clipping Planes

CAMERA = {
    'near_clip': 0.1,
    'far_clip': 5000.0,
    ...
}

near_clip: Quanto vicino puoi avvicinarti far_clip: Quanto lontano puoi vedere

       Far Plane
           │
     ╱╲    │
    ╱  ╲   │
   ╱ ●  ╲  │
  Near Plane

Nota: Se oggetti scompaiono, aumenta far_clip!

Limiti

CAMERA = {
    'min_distance': 200,
    'max_distance': 2000,
    ...
}

Previene:

  • Zoom troppo vicino (camera dentro terreno)
  • Zoom troppo lontano (terreno invisibile)

Modificare i Biomi

Colori

BIOME_COLORS = {
    'water': (65, 105, 225),      # Blu
    'sand': (238, 214, 175),      # Beige
    'grass_low': (34, 139, 34),   # Verde scuro
    'grass_mid': (107, 142, 35),  # Verde oliva
    'grass_high': (85, 107, 47),  # Verde scuro oliva
    'rock': (139, 137, 137),      # Grigio
    'snow': (255, 250, 250)       # Bianco neve
}

Sperimentare

# Terreno desertico
BIOME_COLORS = {
    'water': (139, 69, 19),       # Marrone (oasi fangose)
    'sand': (244, 164, 96),       # Arancione sabbia
    'grass_low': (218, 165, 32),  # Oro (dune)
    'grass_mid': (210, 180, 140), # Tan (roccia)
    'grass_high': (160, 82, 45),  # Sienna (roccia)
    'rock': (139, 90, 43),        # Marrone scuro
    'snow': (255, 228, 181)       # Crema (sale?)
}
# Terreno alieno
BIOME_COLORS = {
    'water': (255, 0, 255),       # Magenta
    'sand': (0, 255, 255),        # Ciano
    'grass_low': (255, 255, 0),   # Giallo
    'grass_mid': (0, 255, 0),     # Verde brillante
    'grass_high': (255, 128, 0),  # Arancione
    'rock': (128, 0, 255),        # Viola
    'snow': (255, 0, 0)           # Rosso
}

Soglie Biomi

BIOME_THRESHOLDS = {
    'water': -10,
    'sand': 0,
    'grass_low': 10,
    'grass_mid': 25,
    'grass_high': 40,
    'rock': 55,
    'snow': 70
}

Logica

Altezza < -10  → Acqua
-10 ≤ Altezza < 0   → Sabbia
0 ≤ Altezza < 10  → Erba bassa
10 ≤ Altezza < 25  → Erba media
25 ≤ Altezza < 40  → Erba alta
40 ≤ Altezza < 55  → Roccia
55 ≤ Altezza < 70  → Neve
70 ≤ Altezza       → Neve

Modificare Distribuzione

# Più acqua, meno montagne
BIOME_THRESHOLDS = {
    'water': 0,    # Era -10
    'sand': 15,    # Era 0
    'grass_low': 30,   # Era 10
    'grass_mid': 45,   # Era 25
    'grass_high': 60,  # Era 40
    'rock': 80,    # Era 55
    'snow': 100    # Era 70
}
Prima (default):          Modificato:
███████ Snow              ████ Snow
████████ Rock             █████ Rock
█████████ Grass High      ███████ Grass High
██████████ Grass Mid      ████████ Grass Mid
████████████ Grass Low    █████████ Grass Low
████ Sand                 ███████ Sand
██ Water                  ████████ Water

Aggiungere Nuovi Biomi

# 1. Aggiungi colore
BIOME_COLORS = {
    ...
    'lava': (255, 69, 0),      # Rosso-arancione
    'ice': (173, 216, 230)     # Azzurro ghiaccio
}

# 2. Aggiungi soglia
BIOME_THRESHOLDS = {
    ...
    'lava': -20,   # Sotto acqua = lava
    'ice': 85      # Sopra neve = ghiaccio
}

# 3. Modifica get_color_for_height in terrain_renderer.py
def get_color_for_height(self, height):
    if height < BIOME_THRESHOLDS['lava']:
        return BIOME_COLORS['lava']
    elif height < BIOME_THRESHOLDS['water']:
        return BIOME_COLORS['water']
    # ... altri biomi ...
    elif height < BIOME_THRESHOLDS['ice']:
        return BIOME_COLORS['snow']
    else:
        return BIOME_COLORS['ice']

Rendering

Bordi Griglia

RENDERING = {
    'line_width': 5.0,  # Spessore bordi tile
    ...
}

Effetti

line_width = 1.0:        line_width = 8.0:
   ╱─╲╱─╲                  ╱══╲╱══╲
  ╱─╲╱─╲╱                 ╱══╲╱══╲╱
Bordi sottili           Bordi spessi

Range: 1.0 - 10.0

Colore Griglia

RENDERING = {
    'line_color': (0, 0, 0),  # Nero (R, G, B)
    ...
}

Esempi:

  • (0, 0, 0): Nero (default)
  • (255, 255, 255): Bianco
  • (128, 128, 128): Grigio
  • (255, 0, 0): Rosso

Illuminazione

RENDERING = {
    'light_position': (1.0, 1.0, 1.0, 0.0),
    'light_ambient': (0.3, 0.3, 0.3, 1.0),
    'light_diffuse': (0.8, 0.8, 0.8, 1.0),
    ...
}

light_position

(1, 1, 1, 0) → Luce direzionale da alto-destra
(x, y, z, w)
  w=0 → direzionale
  w=1 → punto luce

light_ambient

Luce "di base" (ombre non completamente nere):

ambient = 0.1:           ambient = 0.5:
 Ombre scure              Ombre chiare
   ███                      ▓▓▓
   ██                       ▓▓

light_diffuse

Luce "diretta" (quanto sono illuminate le superfici):

diffuse = 0.5:           diffuse = 1.0:
 Illuminazione            Illuminazione
 moderata                 piena
   ▓▓▓                      ███
   ▓▓                       ██

Preset Configurazioni

Montagne Drammatiche

TERRAIN = {
    'grid_size': 25,
    'perlin_scale': 10.0,
    'height_multiplier': 150.0,
    'perlin_octaves': 5,
    'perlin_persistence': 0.7,
    'perlin_lacunarity': 2.8,
}

CAMERA = {
    'distance': 1000,
    'height': 600,
}

Colline Dolci

TERRAIN = {
    'grid_size': 20,
    'perlin_scale': 5.0,
    'height_multiplier': 40.0,
    'perlin_octaves': 3,
    'perlin_persistence': 0.4,
    'perlin_lacunarity': 2.0,
    'enable_smoothing': True,
    'smoothing_iterations': 3,
}

CAMERA = {
    'distance': 700,
    'height': 400,
}

Pianure con Dettaglio

TERRAIN = {
    'grid_size': 30,
    'perlin_scale': 12.0,
    'height_multiplier': 30.0,
    'perlin_octaves': 6,
    'perlin_persistence': 0.6,
    'perlin_lacunarity': 2.5,
}

CAMERA = {
    'distance': 1200,
    'height': 500,
}

Isola Tropicale

TERRAIN = {
    'grid_size': 20,
    'perlin_scale': 6.0,
    'height_multiplier': 60.0,
}

BIOME_THRESHOLDS = {
    'water': 5,      # Più acqua
    'sand': 12,      # Spiagge ampie
    'grass_low': 20,
    'grass_mid': 35,
    'grass_high': 50,
    'rock': 70,
    'snow': 90,
}

BIOME_COLORS = {
    'water': (0, 119, 190),      # Blu oceano
    'sand': (255, 233, 127),     # Sabbia dorata
    'grass_low': (0, 155, 119),  # Verde tropicale
    'grass_mid': (34, 139, 34),
    'grass_high': (85, 107, 47),
    'rock': (139, 137, 137),
    'snow': (255, 250, 250),
}

Funzionalità Avanzate

Esportare Heightmap

Aggiungi a terrain_renderer.py:

def export_heightmap(self, filename):
    """Salva heightmap come immagine PNG"""
    from PIL import Image
    import numpy as np
    
    # Normalizza altezze 0-255
    heights = self.terrain_generator.heightmap
    normalized = ((heights - heights.min()) / 
                  (heights.max() - heights.min()) * 255)
    
    # Crea immagine
    img = Image.fromarray(normalized.astype('uint8'))
    img.save(filename)
    print(f"Heightmap salvata: {filename}")

Uso:

# In app.py, handle_events
if event.type == pygame.KEYDOWN:
    if event.key == pygame.K_s:  # Premi S per salvare
        self.terrain_renderer.export_heightmap('heightmap.png')

Salvare/Caricare Seed

Aggiungi a terrain_generator.py:

def generate_with_seed(self, seed):
    """Genera terreno con seed specifico"""
    import random
    random.seed(seed)
    self.seed = seed
    self.generate()

def get_seed(self):
    """Ottieni seed corrente"""
    return self.seed

Uso:

# Genera con seed
generator.generate_with_seed(12345)

# Salva seed
current_seed = generator.get_seed()
print(f"Seed corrente: {current_seed}")

# Ricrea stesso terreno
generator.generate_with_seed(current_seed)

Animazione (Terreno che Cambia)

Aggiungi a app.py:

def __init__(self, ...):
    ...
    self.animation_enabled = False
    self.animation_offset = 0.0

def update(self):
    if self.animation_enabled:
        self.animation_offset += 0.01
        # Rigenera con offset temporale
        for i in range(grid_size):
            for j in range(grid_size):
                x = i / scale
                y = j / scale
                height = noise.pnoise3(
                    x, y, self.animation_offset,  # 3D noise!
                    octaves=octaves, ...
                )

Minimap

Aggiungi nuovo file src/rendering/minimap.py:

class Minimap:
    def __init__(self, terrain_generator, size=200):
        self.terrain = terrain_generator
        self.size = size
    
    def render(self, screen_width, screen_height):
        """Disegna minimap in angolo"""
        glMatrixMode(GL_PROJECTION)
        glPushMatrix()
        glLoadIdentity()
        glOrtho(0, screen_width, 0, screen_height, -1, 1)
        
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadIdentity()
        
        # Disegna minimap
        x = screen_width - self.size - 10
        y = 10
        
        # ... rendering heightmap 2D ...
        
        glPopMatrix()
        glMatrixMode(GL_PROJECTION)
        glPopMatrix()

Troubleshooting

Terreno Troppo Piatto

Soluzione:

  • Aumenta height_multiplier (da 80 a 120)
  • Riduci perlin_scale (da 8.0 a 5.0)
  • Aumenta perlin_persistence (da 0.6 a 0.7)

Terreno Troppo Caotico

Soluzione:

  • Riduci height_multiplier (da 80 a 50)
  • Aumenta perlin_scale (da 8.0 a 12.0)
  • Riduci perlin_octaves (da 4 a 2)
  • Abilita enable_smoothing

Camera Troppo Lontana

Soluzione:

  • Riduci distance (da 800 a 500)
  • Riduci height (da 450 a 300)

Bordi Invisibili

Soluzione:

  • Aumenta line_width (da 5.0 a 8.0)
  • Cambia line_color per contrasto

Performance Basse

Soluzione:

  • Riduci grid_size (da 20 a 15)
  • Riduci perlin_octaves (da 4 a 3)
  • Disabilita enable_smoothing
  • Riduci far_clip (da 5000 a 3000)

Colori Strani

Soluzione:

  • Verifica BIOME_COLORS (RGB 0-255)
  • Verifica BIOME_THRESHOLDS (ordine crescente)
  • Verifica height_multiplier (altezze compatibili con soglie)

Checklist Personalizzazione

Prima di modificare, salva il file originale!

cp config/settings.py config/settings.py.backup

Cambio Dimensioni

  • Modifica grid_size
  • Adatta perlin_scale (≈ grid_size / 2.5)
  • Testa performance
  • Adatta camera.distance se necessario

Cambio Stile Terreno

  • Modifica height_multiplier
  • Modifica perlin_octaves
  • Modifica perlin_persistence
  • Testa con R (rigenera)
  • Verifica distribuzione biomi

Cambio Colori

  • Modifica BIOME_COLORS
  • Verifica valori RGB (0-255)
  • Testa con diversi terreni
  • Screenshot per confronto

Cambio Soglie

  • Modifica BIOME_THRESHOLDS
  • Verifica ordine crescente
  • Testa rigenera più volte
  • Verifica copertura biomi

File Principale

config/settings.py contiene tutto!

Sezioni Importanti

  1. TERRAIN: Dimensioni, Perlin noise
  2. CAMERA: Posizione, controlli, FOV
  3. RENDERING: Bordi, colori, illuminazione
  4. BIOME_COLORS: Colori biomi (RGB)
  5. BIOME_THRESHOLDS: Soglie altezze

Workflow Consigliato

  1. Modifica config/settings.py
  2. Salva file
  3. Esegui python main.py
  4. Premi R per rigenerare
  5. Usa frecce per testare camera
  6. Ripeti fino a soddisfazione!

Backup

Sempre fare backup prima di grandi modifiche:

cp config/settings.py config/settings_backup_YYYYMMDD.py

Congratulazioni! Ora hai tutte le conoscenze per personalizzare completamente il tuo generatore di terreni isometrici!

← Capitolo Precedente | Torna all'indice