GERLA.CC

tutorial · commodore 64

Gli sprite del C64, spiegati mettendoli in strada

Matteo85 è alle prime esperienze con la grafica sul Commodore 64, e mi ha mandato due disegni: un SUV e una rana. Uno sprite però si capisce molto prima vedendolo muovere che leggendone la definizione, quindi ho fatto la cosa più diretta: in un paio d'ore, in una domenica, li ho messi in strada. È venuto fuori Save The Frogs, il nome gliel'ha dato lui. Questa è la spiegazione che ci è cresciuta intorno.

01 · che cos'è

Otto disegni che il chip video sposta da solo

Su questa macchina uno sprite non è un'immagine che disegni tu sullo schermo: è una cosa che il chip video mette sopra lo sfondo, per conto suo, mentre il pennello elettronico attraversa lo schermo. Tu gli dici dove va, e lui ce lo mette. Lo sfondo sotto non viene toccato, quindi quando l'oggetto si sposta non devi ridisegnare la strada.

Questo è il vero motivo per cui gli sprite esistono, e vale la pena dirlo prima di tutto il resto. Su una macchina che fa un milione di operazioni al secondo, cancellare e ridisegnare un'automobile cinquanta volte al secondo si mangerebbe da sola buona parte del tempo. Gli sprite tolgono quel lavoro alla CPU e lo danno a un circuito che lo fa gratis.

Gli sprite sono otto. Non nove. È un numero fisso, cablato nel chip, e la maggior parte del mestiere su questa macchina consiste nel far bastare otto cose in movimento.

morale: uno sprite non è un disegno, è un disegno più un pezzo di hardware che lo porta in giro. Se ti ricordi solo questo, il resto sono dettagli.

02 · la griglia

24 per 21, e due modi di riempirla

Ogni sprite nasce su una griglia di 24 colonne per 21 righe. Sono misure che sembrano arbitrarie e non lo sono: 24 punti sono esattamente tre byte per riga, e ventuno righe per tre byte fanno 63 byte, che è quasi un blocco tondo di memoria. Torneremo su quel «quasi».

Quella griglia si può riempire in due modi, e la scelta è per sprite.

In alta risoluzione ogni punto è un bit: acceso o spento. Hai la forma più fine che la macchina sappia fare, ma due soli esiti, trasparente oppure il colore assegnato a quello sprite. Un colore. Uno.

In multicolor i bit si leggono a coppie, e ogni coppia fa un punto largo il doppio. Le combinazioni sono quattro, e qui sta tutto il senso della modalità:

00 trasparente, si vede lo sfondo 01 colore comune 1 ($d025) uguale per TUTTI gli sprite 10 colore dello sprite ($d027 + n) suo, e solo suo 11 colore comune 2 ($d026) uguale per TUTTI gli sprite
le quattro combinazioni della modalità multicolor

Quindi non è «quattro colori a scelta libera»: è un colore tuo più due presi in prestito da tutti, più la trasparenza. Se cambi il comune 1 per far contenta la rana, lo cambi anche al SUV. È un vincolo che decide come si disegna, e che non si aggira: si progetta intorno.

E si paga: i punti sono larghi il doppio, quindi in orizzontale sono dodici, non ventiquattro. Le forme vengono a blocchi. Matteo ha scelto il multicolor, ed è la scelta giusta per questi due soggetti: con un colore solo, un SUV che deve avere carrozzeria, vetri e ruote diventa una sagoma.

La griglia 24 per 21 dei tre sprite di Save The Frogs

i tre sprite sulla griglia vera. Si vedono i punti larghi il doppio, e si vede che il SUV occupa due griglie e la rana una.

03 · i dati

63 byte usati, 64 occupati, e un puntatore

Il disegno finisce in memoria come una sequenza piatta: tre byte per riga, ventuno righe, in ordine dall'alto in basso. Sessantatré byte. Il chip però non va a prendersi i dati a un indirizzo qualunque: legge un puntatore, un numero solo, e lo moltiplica per 64. Ecco il «quasi» di prima: i blocchi sono da 64, il disegno ne usa 63, e il sessantaquattresimo byte è lì e non serve a niente.

; il puntatore sta negli ultimi 8 byte della memoria dello schermo ; indirizzo dei dati = puntatore x 64 lda #$0d ; 13 x 64 = $0340 sta $07f8 ; sprite 0 -> disegna quello che c'e' a $0340 ; dove va, e di che colore e' lda #172 sta $d000 ; sprite 0, colonna lda #180 sta $d001 ; sprite 0, riga lda #%00000001 sta $d015 ; accendi lo sprite 0 sta $d01c ; ...e leggilo in multicolor
accendere uno sprite, dall'inizio

Il vantaggio di quel puntatore è che cambiare disegno costa una scrittura sola. Un'animazione non sposta byte: cambia un numero, e al quadro dopo lo sprite è un altro disegno. Nel gioco è così che la rana schiacciata diventa una rana schiacciata.

morale: sul C64 le animazioni sono economiche e la memoria è cara. Tutti i quadri stanno già lì, e quello che si muove è il dito che li indica.

04 · metterne due

Perché il SUV sono due sprite sovrapposti

Ventiquattro punti di larghezza, che in multicolor diventano dodici, sono pochi per un'automobile vista da sopra che deve leggersi come un'automobile. E soprattutto un colore proprio per sprite è poco: la carrozzeria se lo prende, e per i vetri restano solo i due colori comuni.

La via d'uscita classica è metterne due, uno sopra l'altro, alla stessa posizione. Costa un secondo sprite su otto, ma raddoppia i colori propri, perché ognuno dei due porta il suo. Il SUV è fatto così, la rana no: le basta uno.

Ed è qui che il numero otto comincia a pesare. Due li ha già presi il SUV, quindi per le rane in strada ne restano sei. Non è un limite teorico: è la ragione per cui il gioco ha quel numero di rane e non il doppio.

05 · l'ombra

Non disegnata: calcolata

Le ombre sotto il SUV e sotto la rana non le ha disegnate nessuno. Le tira fuori una routine che gira prima del gioco, sul computer, e che fa una cosa sola: per ogni punto pieno del disegno guarda la posizione spostata di uno in basso e uno a destra, e se lì c'è trasparenza ci mette un punto nero.

per ogni punto (x, y) del disegno: se il punto e' pieno: se il punto (x+1, y+1) e' trasparente: metti nero in (x+1, y+1)
tutta l'ombra, in quattro righe

Quattro righe, e il risultato è che i due soggetti smettono di stare appiccicati all'asfalto. È il tipo di trucco che mi piace far vedere a chi comincia, perché ribalta l'idea di partenza: non tutto quello che si vede va disegnato. Una parte si scrive, e la scrive il programma.

C'è un motivo pratico in più. L'ombra calcolata resta giusta se Matteo cambia il disegno: ridisegna il SUV, rilancia la conversione, e l'ombra nuova esce da sola. Un'ombra disegnata a mano invece si scollega dal disegno alla prima modifica, e non se ne accorge nessuno finché non si guarda con attenzione.

06 · muoverlo

Il disegno non sa sterzare

Uno sprite acceso e fermo è ancora soltanto un disegno. La posizione sono due numeri in due registri, e muoverlo vuol dire scrivere in quei registri. Il comportamento, cioè il fatto che vada a destra quando spingi a destra, non c'è: lo scrivi tu.

lda $dc00 ; leggi il joystick and #%00001000 ; il bit della destra: 0 = premuto bne fine lda $d000 ; colonna dello sprite 0 clc adc #2 ; spingila di due sta $d000 fine:
leggi, decidi, scrivi: e questo e' tutto il movimento

C'è una trappola in agguato, ed è la prima in cui inciampano tutti. Il registro della colonna è di un byte, quindi arriva a 255, ma lo schermo è più largo. I bit che mancano stanno tutti insieme in un altro registro, uno per sprite: se lo dimentichi, il tuo oggetto arriva a metà schermo e si teletrasporta a sinistra. Non è un difetto del tuo codice, è il nono bit che non hai scritto.

07 · quello che NON è uno sprite

La strada è fatta di caratteri

Guardando il gioco sembra che il SUV corra. Non corre: resta quasi alla stessa altezza, ed è la strada che gli scorre sotto come un tappeto mobile. E la strada non è uno sprite, perché non potrebbe esserlo: gli sprite sono otto e sono piccoli.

La pista è una tabella di righe. Ogni voce dice dove stanno i bordi e che fascia di colore usare, e il programma legge una voce, sceglie i tasselli, li scrive nella memoria dello schermo e passa alla riga dopo. Fuori dalla carreggiata erba, ai lati guardrail e cordoli, al centro asfalto e mezzeria discontinua. Sono caratteri, cioè pezzetti da otto per otto ridisegnati una volta e riusati ovunque.

Le curve vengono a gradini, e non è un difetto: è la conseguenza visibile di quella scelta. Riusare tasselli costa molto meno che ridisegnare ogni punto, e su questa macchina il prezzo lo paghi in aspetto, non in tempo.

Save The Frogs in esecuzione: la strada, i bordi, la mezzeria e il pannello dei punteggi

tutto quello che si vede qui, tranne il SUV, è fatto di caratteri: l'erba, i cordoli, l'asfalto, la mezzeria a tratti e il pannello dei punteggi in alto. Gli sprite sono due, e sono l'automobile.

morale: la regola pratica è questa. Sprite per le poche cose che si muovono da sole; caratteri per tutto il resto, compreso quello che sembra muoversi ma in realtà scorre. Sbagliare questa divisione è il modo più veloce per restare senza macchina.

08 · gli urti

Il chip te lo dice, ma non abbastanza

Il chip video sa fare da solo una cosa comoda: si accorge quando due sprite si toccano, o quando uno sprite tocca lo sfondo, e lo scrive in due registri. Sembra la risposta a tutto, e per un gioco come questo non lo è.

Il registro ti dice quali sprite sono coinvolti, ma non dove, e soprattutto si azzera quando lo leggi: se lo leggi due volte nello stesso giro, la seconda volta l'urto non è mai successo. Poi il chip considera contatto qualunque punto non trasparente che si sovrappone, ombra compresa. Un'ombra che sfiora una rana non è un investimento.

Quindi nel gioco l'urto non lo chiedo al chip: lo calcolo. Il programma sa dove sono le cose, confronta la riga della rana con quella dell'auto e poi la distanza in orizzontale, e se è sotto una certa soglia considera avvenuto l'investimento. Non è una simulazione fisica, ed è meglio così: i risultati devono essere prevedibili per chi gioca, non fedeli alla realtà. Una soglia in numeri la puoi allargare o stringere finché il gioco non è giusto; il registro del chip non si può regolare.

in sintesi

Cosa resta, se resta una cosa sola

Uno sprite è un disegno da 24 per 21 che un circuito ti porta in giro gratis, ne hai otto, e ognuno ha un colore suo più due presi in prestito da tutti. Tutto il resto della schermata sono caratteri. Il disegno non sa sterzare, non sa cadere e non sa morire: quello lo scrive il programma, e il programma è la parte in cui un disegno diventa un gioco.

Save The Frogs è nato in un paio d'ore e si vede: è una corsa senza fine, tre vite, punti che salgono con la velocità, e nessun traguardo. Non doveva essere altro. Serviva a rispondere a una domanda concreta, i miei disegni funzionano?, e la risposta si dà più in fretta facendoli girare che spiegandoli.

Otto minuti, dal disegno al gioco

Se preferisci sentirtelo raccontare, tutto quello che c'è qui sopra sta anche in un video: gli sprite, la strada, il ciclo di gioco, gli urti, i menu e il difetto di scorrimento che ho dovuto sistemare.

i sottotitoli si accendono dal menu del lettore, il fumetto in basso a destra: non partono da soli.

savethefrogs.prg

14 KB · Commodore 64 · si carica in VICE o su macchina vera
si carica a $0801 e parte con RUN

Scarica il PRG

Crediti. Game design e grafica degli sprite: Matteo85, che ha anche dato il nome al test. La programmazione è mia.

← Tutti i tutorial Il C64 su questo sito →