{{htmlmetatags>metatag-robots=() metatag-title=(Introduzione (soft) alla grafica | Retro Game Makers with ugBASIC!) metatag-keywords=(ugBASIC,Commodore 64,Commodore PLUS/4,ZX Spectrum) metatag-description=(An useful guide to the secrets of videogame programming using ugBASIC) metatag-media-og:image=(:ugbasic:logo-ugbasic-fb.png) metatag-og:title=(Introduzione (soft) alla grafica | Retro Game Makers with ugBASIC!) metatag-og:description=(An useful guide to the secrets of videogame programming using ugBASIC) }} ====== Creatori di retrogiochi con ugBASIC! ====== ===== Introduzione (soft) alla grafica ===== ==== Premessa ==== All’inizio, ugBASIC può intimidire. Vi sono letteralmente centinaia di comandi diversi con cui confrontarsi, ed è facile impantanarsi in dettagli inutili. Partiamo quindi da un aspetto, che è quello relativo al **sistema grafico**. Mi concentrerò sulle istruzioni specifiche, necessarie per utilizzare al meglio la grafica nei propri programmi. Una volta apprese le idee di base, imparare il resto dei comandi dovrebbe essere facile. Nel caso che tu rimanga bloccato leggendo questa guida, fai riferimento al [[:it:ugbasic:user|manuale utente di ugBASIC]] e alle sue guide pratiche: potrebbero tornarti utili. ==== Risoluzione e colori nel mondo isomorfo ==== {{ :ugbasic:user:guide:introduction:esempio_contrib_light.png?nolink |}} ugBASIC è un linguaggio isomorfo. Ciò significa che non ti costringe a programmare né per un computer specifico, come accade con l’assembly, né per uno che non esiste, come accade con gli altri linguaggi. Non ti offre, in altri termini, una astrazione a cui far riferimento. Questo significa che, quando vai a disegnare una immagine che poi verrà utilizzata nel gioco o vuoi tracciare dei punti sullo schermo, non hai indicazioni precise di quale sarà la risoluzione massima, o il numero di colori contemporanei o altre indicazioni del genere. Questo dipenderà dall’hardware finale. Quello puoi fare è disegnare in base alle informazioni disponibili al momento in cui il programma girerà: sarà il compilatore per quella determinata piattaforma a convertire le operazioni in un formato adatto, o ad avvisarti se qualcosa va cambiato, se (ad esempio) la conversione delle risorse grafiche non dovesse essere possibile. ==== Scegliere lo schermo ==== Quindi, volendo iniziare da qualche parte, se vuoi disegnare qualcosa, hai bisogno di dire a ugBASIC che appunto vuoi iniziare a disegnare dei punti, e poi trovare un modo semplice per specificare la posizione esatta dei punti sullo schermo. Con questa prima istruzione indichiamo quali sono le caratteristiche dello schermo che desideri: BITMAP ENABLE (160,200,16) Stai chiedendo quindi una grafica “bitmap” (''BITMAP ENABLE'') con risoluzione suggerita di 160x200 pixel ''(160,200)'', e con almeno ''16'' colori diversi. Non è detto che queste saranno le caratteristiche effettive che otterrai: l’hardware potrebbe non disporre della modalità bitmap, oppure vi potrebbero essere meno colori disponibili, e così via. Il compilatore specifico per quella piattaforma ha un certo margine di manovra nel decidere come esaudire al meglio la tua richiesta. ==== Introduciamo un sistema di riferimento ==== Ora prendi il comando ''PLOT'', il cui scopo è modificare il colore di un singolo punto (o pixel) dello schermo. Non possiamo semplicemente digitare: PLOT RED poiché vi sono (letteralmente) migliaia di punti diversi tra cui scegliere. Quindi, come può ugBASIC sapere a quale punto preciso ci riferiamo? In pratica, bisogna introdurre un sistema di riferimento nel quale ogni punto sullo schermo potrà essere individuato utilizzando una coppia di numeri. Questa coppia viene chiamata “coordinate” (ascissa e ordinata), e misurano la distanza dall’angolo in alto a sinistra. Quel punto in alto a sinistra si chiama “origine”. {{ :ugbasic:user:guide:introduction:sistema_riferimento.png?nolink&400 |}} Tradizionalmente, alle due componenti di una coordinata vengono dati i nomi ''x'' e ''y'', e rappresentano (rispettivamente) la distanza orizzontale e quella verticale dal punto di origine. Ogni volta che inseriamo le due coordinate nelle nostre istruzioni, le separiamo sempre con una virgola: ''x,y''. È un po' come i riferimenti alla griglia di una mappa, con il primo numero che indica la ''x'' e il secondo la coordinata ''y''. Quindi se la coordinata ''0,0'' indica il punto in alto a sinistra dello schermo, come possiamo sapere dove si trova il punto in basso a destra? Vediamo le istruzioni specifiche di ugBASIC che ci vengono in aiuto: * ''(SCREEN) WIDTH'', per ottenere la larghezza dello schermo effettivo, espressa in pixel; * ''(SCREEN) HEIGHT'', per ottenere l’altezza dello schermo effettivo, espressa in pixel; * ''(SCREEN) COLORS'', per ottenere il numero di colori utilizzabili; * ''(SCREEN) SHADES'', per ottenere il numero di sfumature rappresentabili. In tutte la parola chiave ''SCREEN'' può essere omessa, per brevità. ==== Compiliamo il primo programma! ==== Diamo un'occhiata all'utilizzo di queste coordinate. Carica il tuo editor preferito (noi consigliamo [[https://code.visualstudio.com/|Visual Studio Code]]) e digita il seguente programma e salvalo nel file ''first.bas'': BITMAP ENABLE (160,200,16) PLOT WIDTH / 2, HEIGHT / 2 Adesso compilalo. Una caratteristica unica di ugBASIC è di avere molti compilatori separati, uno per ogni “target” ovvero per ogni modello di retrocomputer, ed eseguibili sia da Linux che da Microsoft Windows. **Non ti spaventare!** Ogni compilatore fa chiaramente la stessa cosa: legge un programma ugBASIC e lo traduce nel linguaggio macchina specifico per quella piattaforma: va da sé che le istruzioni saranno ottimizzate per quello specifico hardware. Per compilare un programma ugBASIC, e ottenere direttamente l’eseguibile, è sufficiente invocare la linea di comando del corrispondente compilatore. Ad esempio: ugbc.atari first.bas -o first.xex genererà un eseguibile su Linux per Atari 400/800, mentre il seguente comando: ugbc.pc128op.exe first.bas -o first.k7 genererà su Microsoft Windows un eseguibile per Olivetti Prodest PC128. Se non ottieni alcun messaggio di errore allora l’eseguibile sarà pronto per essere eseguito sull’emulatore oppure sull’hardware reale, dopo aver opportunamente copiato il file prodotto su di un supporto fisico. ==== Vediamo i risultati ==== Tornando al programma, mandandolo in esecuzione vedrete comparire un punto bianco al centro di uno schermo nero. Il comando ''PLOT'' è disponibile in due versioni. La versione più semplice è: PLOT x, y che traccia un singolo punto alle coordinate ''x, y''. Prova a sostituire queste coordinate con una qualsiasi coppia di valori. In poco tempo, sarai in grado di posizionare il punto in qualsiasi parte dello schermo. ==== Un tocco di colore ==== Il prossimo passo è aggiungere un po' di colore alla scena. Lo schermo selezionato consente di visualizzare fino a ''(SCREEN) COLORS'' colori contemporaneamente (ricorda, è un linguaggio isomorfo!). Ogni colore viene inserito in ugBASIC in due modi: * con un indice numerico tra ''0'' e ''SCREEN COLORS-1''; * con il nome simbolico del colore desiderato, che viene comunque tradotto internamente in uno degli indici numerici di cui sopra. Questo è l’elenco dei colori che possono essere indicati per nome: | BLACK | WHITE | RED | | CYAN | VIOLET | GREEN | | BLUE | YELLOW | ORANGE | | BROWN | LIGHT RED | DARK GREY | | GREY | LIGHT GREEN | LIGHT BLUE | | LIGHT GREY | DARK BLUE | MAGENTA | | PURPLE | LAVENDER | GOLD | | TURQUOISE | TAN | YELLOW GREEN | | OLIVE GREEN | PINK | PEACH | Dimostrerò ora come usare i colori, sfruttando una versione estesa del precedente comando PLOT. Il comando ha la forma PLOT x, y, colore Quindi se digiti e poi compili il programma: PLOT 160, 100, 0 PLOT 50, 50, 5 disegnerai un primo punto a 160 pixel a sinistra dal bordo dello schermo e a 100 pixel dal bordo superiore dello schermo, con il colore che ha indice 0 (di solito è nero, ma non è detto), mentre ne disegnerai un secondo alle coordinate 50 pixel a sinistra, 50 pixel dall’altro, con il colore che ha indice 5 (quale colore è? Non saprei, dipende dall’hardware!). Se vuoi essere sicuro di disegnare un pixel di un certo colore devi usare il nome simbolico: PLOT 160, 100, BLACK PLOT 50, 50, BLUE Vediamo ora un [[https://github.com/spotlessmind1975/ugbasic/blob/main/examples/graphics_plot_01.bas|esempio di programma]]. BITMAP ENABLE(16) CLS BLACK DO x = RND(SCREEN WIDTH-1) y = RND(SCREEN HEIGHT-1) c = RND(SCREEN COLORS-1) PLOT x, y, c LOOP {{ :ugbasic:user:guide:introduction:esempio_graphics_plot_01.png?nolink |}} Quando esegui questo programma, il display del computer si riempirà di centinaia di punti multicolori. Abbastanza noioso. Puoi uscire dal programma resettando il computer. ==== Giochiamo con le sfumature ==== A prima vista, i 16 colori suggeriti possono sembrare limitanti, e in effetti lo sono, ma se si scende al livello di uno specifico retrocomputer, è possibile sfruttarne le caratteristiche per superare questo limite. Per esempio, alcuni computer come l’**Olivetti Prodest 128** oppure l’**ATARI** permettono di ridefinire ogni singolo colore, e quindi a ogni indice può effettivamente essere assegnato una tonalità tra quelle disponibili. I 16 indici rappresentano, a questo punto, una piccola selezione da una vasta gamma di possibili colori. Sta a te decidere quale colore verrà visualizzato da un particolare numero di indice. Se ti va di giocare puoi anche impostare ogni indice esattamente sulla stessa tonalità, per ugBASIC non ha alcuna importanza! Puoi cambiare le tonalità utilizzate di ogni indice di colore in qualsiasi momento con il comando COLOR: COLOR indice, sfumatura Il valore di ''sfumatura'' definisce la precisa sfumatura del colore da assegnare al nostro ''indice''. Se lo desideriamo, possiamo impostare questo numero direttamente su un valore compreso tra ''0'' e ''(SCREEN) SHADES''. In genere, tuttavia, utilizziamo una funzione che consente di mescolare la sfumatura ottenendola dalla somma di tre componenti semplici. La sfumatura può essere ottenuta con al funzione RGB: shade = RGB(21, 11, 23) Ciascuno dei parametri della funzione controlla le quantità (rispettivamente) di rosso, di verde o di blu nel colore finale, e può variare da ''0'' a ''255''. Più alto è il valore, più brillante è la tonalità. Alcuni esempi sono: nero = RGB( 0, 0, 0 ) grigioScuro = RGB( 32, 32, 32 ) rosso = RGB( 128, 0, 0 ) verde = RGB( 0, 128, 0 ) blu= RGB( 0, 0, 128 ) ==== Il colore di sfondo ==== Ogni volta che eseguiamo uno dei nostri programmi ugBASIC, lo schermo viene automaticamente riempito con un blocco di colore ''0''. Normalmente questo sarà impostato su nero ma possiamo cambiarlo, se l’hardware ce lo permette, per trasformare il display in un caleidoscopio di colori. Proviamo a scrivere il seguente programma: BITMAP ENABLE CLS BLACK DO COLOR 0, $555 COLOR 0, $900 COLOR 0, $090 COLOR 0, $009 COLOR 0, $990 LOOP Mandando in esecuzione il programma, potrai vedere cambiare rapidamente lo sfondo con colori piuttosto scuri. La ragione sta nel fatto che hai utilizzato poco più della metà dei livelli di luminosità disponibili. Ad ogni componente può essere assegnata una sfumatura tra le sedici disponibili. Sfortunatamente questo pone un problema, poiché non possiamo rappresentare 16 valori usando una singola cifra, perché vi sono solo 10 cifre (da 0 a 9). ==== Imparare a usare i numeri esadecimali ==== Possiamo aggirare questo dilemma usando i numeri esadecimali. Questi ci forniscono un totale di 16 cifre contemporaneamente. Per distinguerli dai numeri decimali tradizionali, ugBASIC si aspetta che aggiungiamo vicino un segno che li caratterizzi come tali. Il linguaggio supporta una serie molto ampia di prefissi: * ''$'' (dollaro); * ''&H'' (e commerciale e lettera ''h''); * ''0x'' (zero seguito dalla ''x''); oltre al suffisso ''h'' (lettera ''H'' minuscola/maiuscola). Ad ogni modo, le prime 10 cifre sono identiche al normale sistema decimale. Ecco perché gli esempi precedenti sembravano funzionare. Tuttavia, le cifre da 10 a 15 sono rappresentate dalle lettere ''A'', ''B'', ''C'', ''D'', ''E'' e ''F'' (minuscole o maiuscole poco importa). Ecco un elenco completo delle 16 cifre esadecimali, con il loro controvalore decimale. | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Vediamo alcuni esempi con numeri esadecimali: COLOR 0, $FFF : ' BIANCO PURO COLOR 0, $F00 : ' ROSSO LUMINOSO COLOR 0, $0F0 : ' VERDE LUMINOSO COLOR 0, $00F : ' BLU LUMINOSO COLOR 0, $FF0 : ' GIALLO ==== Mostriamo i colori! ==== In generale, i colori attuali per qualsiasi indice possono essere mostrati sullo schermo in formato esadecimale utilizzando la funzione ''COLOR'': PRINT HEX$( COLOR( 0 ) ) Questo comando mostra i valori di colore assegnati all'indice ''0''. La funzione ''HEX$'' converte il numero in esadecimale, in modo che possiamo controllare i suoi singoli componenti di colore. Con la pratica sarai in grado di visualizzare un colore direttamente dai relativi valori di intensità. È davvero facile una volta che ci hai fatto l’occhio. ==== Un comando per tanti colori ==== All'inizio del programma, è spesso necessario impostare un insieme predefinito di colori, tutti in una volta. Poiché è prolisso dover caricare ogni valore utilizzando un'istruzione COLOR separata, ugBASIC include un comando PALETTE che consente di assegnare tutti i colori in una singola riga. PALETTE c0, c1, c2, c3, c4 ... Questa istruzione carica il colore ''c0'' come colore di sfondo, il colore ''c1'' come primo colore, e così via. Il numero di colori può essere quello che si desidera, ma chiaramente ogni singolo target imporrà un certo numero di colori massimo, in base alle capacità del sottosistema grafico. E’ possibile assegnare meno valori di quelli disponibili, e ciò implica che i restanti colori assumeranno il valore di default. Ad esempio, per impostare lo sfondo è possibile farlo con: PALETTE BLACK Se invece assegnate più valori di quelli che il sistema può effettivamente gestire, ugBASIC non emetterà alcun errore ma utilizzerà gli ultimi valori per sovrascrivere i primi. Ad esempio, i sistemi **ATARI** hanno di norma 4 colori e, quindi, il seguente comando: PALETTE BLACK, RED, GREEN, BLUE, WHITE non farà altro che impostare lo sfondo al colore bianco (''WHITE''), perché il quinto colore corrisponderà al colore zero (sfondo). Sul computer **Olivetti Prodest PC128**, invece, lo sfondo rimarrà nero (''BLACK''). Se, ad esempio, si vuol definire una palette formata da sfumature di grigio, si può utilizzare il seguente comando: PALETTE RGB($00,$00,$00), RGB($11,$11,$11), RGB($22,$22,$22), _ RGB($33,$33,$33), RGB($44,$44,$44), RGB($55,$55,$55), _ RGB($66,$66,$66), RGB($77,$77,$77), RGB($88,$88,$88), _ RGB($99,$99,$99), RGB($AA,$AA,$AA), RGB($BB,$BB,$BB), _ RGB($CC,$CC,$CC), RGB($DD,$DD,$DD), RGB($EE,$EE,$EE), _ RGB($FF,$FF,$FF) Notare come utilizziamo il carattere underscore (''_'') per segnalare che la riga logica continua sulla linea fisica successiva. Questo è il modo in cui, su ugBASIC, si possono scrivere istruzioni su più righe. ===== POWERED BY ===== [[:it:ugbasic:user:guide|{{ :ugbasic:user:logo-ugbasic.png?nolink&600 |}}]]