✚ Sviluppo videogiochi

La telecamera 2D: inseguimento, zona morta e scuotimento

Come programmare una telecamera 2D che segue il giocatore senza scatti: zona morta, smorzamento, anticipo, limiti del livello e scuotimento dello schermo.

In un gioco 2D la telecamera decide che cosa vede il giocatore e, di conseguenza, quanto riesce a prevedere ciò che sta per succedere. Una telecamera fissata rigidamente al personaggio funziona, ma trasmette ogni piccolo movimento allo schermo e affatica la vista. Con pochi accorgimenti si ottiene un risultato molto più piacevole e leggibile.

Che cos'è la telecamera in 2D

Tecnicamente la telecamera è solo uno spostamento applicato a tutto ciò che si disegna. Se la telecamera si trova in (cx, cy), un oggetto alla posizione (x, y) del mondo viene disegnato sullo schermo in:

schermo_x = (x - cx) * zoom + larghezza_schermo / 2
schermo_y = (y - cy) * zoom + altezza_schermo / 2

Il punto (cx, cy) corrisponde al centro dello schermo. Lo zoom permette di avvicinare o allontanare la vista. Molti motori e librerie grafiche offrono un oggetto telecamera che applica questa trasformazione automaticamente, ma il principio è sempre lo stesso.

Inseguimento con smorzamento

Invece di copiare la posizione del giocatore, la telecamera si avvicina gradualmente:

cx += (giocatore.x - cx) * fattore

Con un fattore tra 0 e 1, la telecamera percorre ogni volta una frazione della distanza residua: si muove in fretta quando è lontana e rallenta quando si avvicina. L'effetto è morbido e naturale.

C'è però un dettaglio: questa formula dipende dal frame rate. Per renderla indipendente si usa una forma esponenziale:

cx += (giocatore.x - cx) * (1 - exp(-velocita * dt))

Così la telecamera si comporta allo stesso modo a 30, 60 o 144 fotogrammi al secondo.

La zona morta

La zona morta (dead zone) è un rettangolo al centro dello schermo dentro cui il giocatore può muoversi senza che la telecamera si sposti. Solo quando il personaggio ne esce, la telecamera lo segue quanto basta per riportarlo al bordo della zona.

È particolarmente utile nei platform: piccoli passi avanti e indietro, o il saltellare sul posto, non fanno ondeggiare lo schermo. In verticale molti giochi adottano una regola ancora più severa: la telecamera si aggiorna in altezza solo quando il personaggio atterra su una piattaforma più alta o più bassa, ignorando il movimento del salto.

Guardare avanti

Un giocatore che corre verso destra ha bisogno di vedere ciò che arriva da destra, non ciò che si lascia alle spalle. Lo spostamento anticipato (look-ahead) colloca il punto di mira della telecamera davanti al personaggio, nella direzione del movimento:

obiettivo_x = giocatore.x + direzione * anticipo

L'anticipo può dipendere dalla velocità: più il personaggio corre, più la telecamera guarda avanti. Quando cambia direzione, lo smorzamento rende la transizione graduale invece di un salto improvviso.

Rispettare i limiti del livello

Quando il personaggio si avvicina al bordo della mappa, la telecamera non deve mostrare il vuoto oltre il livello. Si limitano le sue coordinate:

cx = limita(cx, mezza_larghezza_vista, larghezza_livello - mezza_larghezza_vista)
cy = limita(cy, mezza_altezza_vista, altezza_livello - mezza_altezza_vista)

Se il livello è più piccolo dello schermo su un asse, conviene semplicemente centrarlo su quell'asse. Molti giochi definiscono anche stanze o zone con limiti propri: entrando in una nuova area, i limiti cambiano e la telecamera scorre fino alla nuova inquadratura.

Pixel art e coordinate intere

Con la grafica in pixel art, una telecamera a coordinate decimali può produrre un fastidioso tremolio: i pixel degli sprite cadono a cavallo dei pixel dello schermo e vengono arrotondati in modi diversi da un fotogramma all'altro. Le soluzioni più comuni:

  • arrotondare la posizione della telecamera al pixel intero prima di disegnare;
  • renderizzare il gioco a bassa risoluzione su una texture e poi ingrandirla di un fattore intero;
  • conservare la posizione decimale per i calcoli, arrotondando solo al momento del rendering.

Scuotimento dello schermo

Lo scuotimento (screen shake) comunica impatto: un'esplosione, un colpo potente, un boss che atterra. L'approccio più controllabile usa un valore di «trauma» tra 0 e 1:

trauma = min(1, trauma + intensita_evento)
scossa = trauma * trauma
offset_x = scossa_max * scossa * rumore(t)
offset_y = scossa_max * scossa * rumore(t + 100)
trauma = max(0, trauma - decadimento * dt)

Elevare il trauma al quadrato rende le scosse leggere quasi impercettibili e quelle forti molto evidenti. Usare una funzione di rumore continuo invece di numeri casuali puri produce un movimento più organico. L'offset si aggiunge solo al rendering, senza modificare la posizione reale della telecamera.

Con lo scuotimento è facile esagerare. È buona pratica offrire un'opzione per ridurlo o disattivarlo, a beneficio di chi soffre di chinetosi o trova fastidiosi i movimenti bruschi.

Parallasse

Infine, per dare profondità, gli strati di sfondo possono muoversi più lentamente della telecamera:

Strato Fattore di parallasse
Cielo 0,0 – 0,1
Montagne lontane 0,2 – 0,4
Colline vicine 0,5 – 0,7
Livello di gioco 1,0
Primo piano 1,1 – 1,3

Ogni strato si disegna con un offset pari alla posizione della telecamera moltiplicata per il suo fattore.

In sintesi

  • La telecamera 2D è uno spostamento applicato a tutto ciò che si disegna.
  • Lo smorzamento esponenziale dà un inseguimento morbido e indipendente dal frame rate.
  • Zona morta e anticipo rendono l'inquadratura stabile e utile al giocatore.
  • I limiti del livello e le coordinate intere evitano vuoti e tremolii.
  • Scuotimento e parallasse aggiungono impatto e profondità, con moderazione.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica, unisce il rigore dell'analisi tecnica all'attenzione per le persone che usano la tecnologia.

Leggi anche