[#_lesson_1_hello] == Lezione 1: Ciao image::learn/01-hello.png[La lezione finita, 480] Ecco che cosa avrai alla fine di questa lezione. Non è granché da vedere. È anche un programma scritto da te, che gira su un vero motore di gioco, e tutto il resto di questo libro è costruito sulle cinque righe che l'hanno creato. [#_set_up_your_work_folder] === Prepara la cartella di lavoro Crea una cartella in cui tenere tutto, chiamata `singe` o come preferisci, e mettici dentro la tua copia di Singe. Questa è la tua *cartella di lavoro*, e ogni lezione di questo libro ci mette dentro una nuova cartella. La crei una volta e non ci pensi più. Dentro la cartella di lavoro crea una cartella chiamata `hello`, e dentro quella un file chiamato `hello.singe`. [literal] ---- singe/ <- la tua cartella di lavoro, con dentro Singe hello/ hello.singe ---- Questo annidamento non è pignoleria. Singe considera la cartella da cui lo esegui come il posto in cui vivono i giochi, una cartella per gioco, e ci tiene anche i propri file. Il tuo gioco va nella sua cartella, un livello più giù. Dalla seconda lezione in poi ogni lezione è un'altra cartella accanto a `hello`. Due cose sui nomi. La parte dopo il punto, `.singe`, è il modo in cui Singe sa che questo è uno script. E sulla maggior parte dei computer che non usano Windows le maiuscole contano: `Hello.singe` e `hello.singe` sono due file diversi. Prendi fin da ora l'abitudine di scrivere i nomi esattamente. Conta anche dare alla cartella e allo script lo stesso nome, e tra un momento vedrai perché. Apri `hello.singe` nel tuo editor di testo. È vuoto. È giusto così. [#_type_this_in] === Scrivi questo [source,lua] ---- function onOverlayUpdate() overlayClear() overlayPrint(2, 2, "Hello!") return OVERLAY_UPDATED end ---- Salvalo. Non preoccuparti ancora di che cosa voglia dire. Prima di eseguirlo vale la pena notare due cose, perché varranno per ogni programma che scriverai. La prima è che gli spazi all'inizio delle tre righe centrali sono lì apposta. Al programma non fanno proprio niente -- Singe lo eseguirebbe esattamente allo stesso modo anche senza -- ma ti mostrano a colpo d'occhio che quelle tre righe stanno *dentro* la cosa che comincia con `function` e finisce con `end`. Lo fanno tutti i programmatori. Fallo dal primo giorno e non dovrai mai impararlo dopo. La seconda è l'ordine delle righe. Avvengono dall'alto in basso, una dopo l'altra, come i passi di una ricetta. È la cosa più importante in assoluto di un programma, e quasi tutto ciò che confonde un principiante nasce dal dimenticarlo. [#_run_it] === Avvialo Apri un terminale, vai nella tua *cartella di lavoro* -- non nella cartella `hello` che c'è dentro -- e indica la cartella che vuoi eseguire: ---- Singe hello ---- Su Windows è `Singe.exe hello`. Se la tua copia di Singe sta da un'altra parte, scrivi il percorso per arrivarci, come `../Singe hello`. Ecco perché la cartella e lo script hanno lo stesso nome. Quando gli dai una cartella, Singe ci cerca dentro uno script che si chiama allo stesso modo. Dagli nomi diversi e ottieni `Error: Unable to locate the game.`, che è il motore che ti dice di aver cercato senza trovare niente che riconoscesse. In alternativa puoi sempre essere esplicito e scrivere `Singe hello/hello.singe`, che fa lo stesso lavoro. Si apre una finestra nera con la parola `Hello!` vicino all'angolo in alto a sinistra. Premi *Esc* o *Q* per uscire. Saranno successe due cose che non hai chiesto, ed entrambe sono normali. Nella tua cartella di lavoro, accanto a `hello`, sono comparse le cartelle `Singe` e `data`: la prima è il motore che estrae i file che gli servono, la seconda è dove finirà tutto ciò che i tuoi giochi salvano. Lasciale stare tutte e due. E la finestra è quasi tutta nera, perché non hai disegnato niente a parte sei caratteri. [#_what_just_happened] === Cos'è appena successo Ora le cinque righe, una alla volta. [source,lua] ---- function onOverlayUpdate() ---- `function` comincia un gruppo di istruzioni e gli dà un nome. Tutto ciò che c'è da qui fino al suo `end` gli appartiene. Questa si chiama `onOverlayUpdate`, e le parentesi vuote dopo il nome avranno senso nella quinta lezione. Quel nome non lo scegli tu. Singe cerca una funzione con esattamente quel nome e la chiama circa sessanta volte al secondo, per sempre, così hai l'occasione di disegnare. Se la scrivi `onoverlayupdate` o `onOverlayUpdated`, Singe non la trova, la finestra resta nera e niente ti dirà che hai sbagliato. Ecco la prima vera lezione: il computer fa quello che hai scritto, non quello che intendevi. Una funzione che scrivi tu e che chiama il motore è una *callback*. Non la chiami tu, e non puoi decidere quando viene eseguita: tu la scrivi, e Singe ti richiama quando c'è qualcosa da fare. Ogni nome di questo libro che comincia con `on` è una callback, e ce n'è una per quasi tutto ciò che può succedere: un pulsante premuto, un tasto digitato, un suono che finisce, il disco che raggiunge un fotogramma. `onOverlayUpdate` è quella per disegnare, ed è l'unico posto in cui è permesso disegnare. [source,lua] ---- overlayClear() ---- Anche questa è una funzione, ma non una che devi scrivere tu: la fornisce Singe, insieme a diverse centinaia di altre, e tu la stai *chiamando*. Chiamare una funzione vuol dire dire il suo nome seguito dalle parentesi. Questa pulisce lo schermo. Viene per prima perché disegnare non sostituisce quello che c'era prima: ci disegna sopra. Pulisci, poi disegna, ogni volta. [source,lua] ---- overlayPrint(2, 2, "Hello!") ---- Un'altra chiamata, e a questa bisogna dire tre cose, che vanno dentro le parentesi separate da virgole. Le cose che passi così a una funzione si chiamano *argomenti*. I primi due sono numeri: quanto più a destra e quanto più in basso. Il terzo è il testo da stampare, ed è tra virgolette doppie perché è così che dici al computer che `Hello!` è un pezzo di testo e non il nome di qualcosa. Il testo tra virgolette si chiama *stringa*, e userai le stringhe di continuo. Prima o poi vorrai delle virgolette doppie dentro una stringa, e il modo ovvio non funziona: la seconda virgoletta chiude la stringa troppo presto, e ottieni lo stesso errore `unfinished string` che incontrerai alla fine di questa lezione. Ci sono due modi per aggirarlo, e conviene conoscerli entrambi. [source,lua] ---- overlayPrint(2, 2, "She said \"hello\" to me.") overlayPrint(2, 4, 'She said "hello" to me.') ---- Il primo mette una barra rovesciata davanti a ogni virgoletta che fa parte del testo. La barra rovesciata dice «il carattere successivo fa parte della stringa, non ne è la fine», e la coppia si chiama *sequenza di escape*. Il secondo usa le virgolette singole per segnare i due capi della stringa, e così le virgolette doppie restano libere di essere testo normale. Lua accetta tutti e due i tipi di virgolette, purché la stringa finisca con lo stesso tipo con cui è cominciata. Quelle due righe stampano esattamente la stessa cosa. Usa quella più facile da leggere, che di solito è quella con le virgolette singole quando il testo è pieno di virgolette doppie. I due numeri non sono pixel. `overlayPrint` è il testo semplice del motore, e conta in celle di carattere: `(0, 0)` è proprio l'angolo in alto a sinistra, `(1, 0)` è una lettera più a destra e `(0, 1)` è una riga più in basso. Quindi `(2, 2)` è due lettere verso destra e due righe verso il basso. Altri modi di disegnare il testo contano invece in pixel, e li incontrerai nella diciannovesima lezione. [source,lua] ---- return OVERLAY_UPDATED ---- `return` restituisce una risposta a chi ha chiamato la funzione. Ogni volta che chiama la tua `onOverlayUpdate`, Singe le fa una domanda: hai cambiato qualcosa? `OVERLAY_UPDATED` vuol dire sì, quindi mettilo sullo schermo. `OVERLAY_UPDATED` non ha virgolette intorno perché non è testo. È un nome che Singe ha già dato a un valore, così puoi scrivere qualcosa che sai leggere invece di un numero che dovresti ricordare. [source,lua] ---- end ---- La fine corrispondente della `function`. Ogni `function` ne ha esattamente una, e dimenticarla è in assoluto l'errore più comune che ci sia. [#_try_it] === Prova tu Cambia una cosa alla volta, salva ed eseguilo di nuovo. Quel ciclo -- cambia, esegui, guarda -- è tutto il lavoro. . *Sposta il testo.* Cambia `overlayPrint(2, 2, "Hello!")` in `overlayPrint(10, 5, "Hello!")`. Poi prova `(0, 0)`. Poi prova `(200, 2)`, e scopri perché è sparito. . *Di' qualcos'altro.* Metti il tuo nome tra le virgolette. . *Di' due cose.* Aggiungi una seconda riga `overlayPrint` sotto la prima, con un numero di riga diverso e un testo diverso. Niente ti impedisce di averne quante ne vuoi. . *Togli la pulizia.* Cancella la riga `overlayClear()` ed eseguilo. Non cambia niente, perché sullo schermo ancora non si muove niente. Rimettila comunque. Nella seconda lezione conterà moltissimo, ed è un buon momento per vedere che certi errori aspettano prima di mordere. [#_break_it_on_purpose] === Rompilo apposta I principianti passano più tempo a leggere messaggi di errore che libri di programmazione, quindi togliamoci subito il pensiero del primo. Cancella la virgoletta di chiusura dopo `Hello!`, così la riga diventa `overlayPrint(2, 2, "Hello!)`, ed eseguilo. Singe si rifiuta di partire e dice: ---- Error running script: hello/hello.singe:3: unfinished string near '"Hello!)' ---- Leggilo da sinistra. `hello/hello.singe` è il file: la cartella, poi lo script che contiene. `3` è la riga. Il resto è che cosa è andato storto, in questo caso un pezzo di testo aperto e mai chiuso. Vai alla riga tre, rimetti la virgoletta, e parte. Quasi ogni errore che vedrai ha questa forma: un file, una riga e una lamentela. La lamentela a volte è scritta per qualcuno che conosce già Lua, ma il file e la riga sono sempre giusti, e nove volte su dieci basta la riga. [#_stop_restarting_it] === Smetti di riavviarlo Ormai hai avviato Singe a mano cinque o sei volte. Smetti di farlo. Avvialo invece così: ---- Singe -R hello ---- `-R` dice a Singe di tenere d'occhio il tuo script. Salva una modifica nel tuo editor, e un attimo dopo il gioco riparte da solo con la modifica dentro, senza chiudere la finestra. Se salvi un errore, l'errore viene stampato e la finestra resta vuota finché non salvi una correzione. Usa `-R` per il resto di questo libro. [#_what_you_learned] === Cosa hai imparato * Un programma è un file di istruzioni che avvengono in ordine, dall'alto in basso. * Una `function` raggruppa delle istruzioni sotto un nome e si ferma al suo `end`. * `onOverlayUpdate` è un nome che Singe cerca e chiama molte volte al secondo, ed è lì che va tutto ciò che disegni. * Chiamare una funzione vuol dire scriverne il nome e le parentesi. Tutto ciò che sta dentro le parentesi è un argomento. * Una funzione che il motore chiama per te, invece di una che chiami tu, è una callback. `onOverlayUpdate` è una di queste. * Il testo tra virgolette doppie è una stringa. * Pulisci lo schermo prima di disegnarci sopra. * Un errore ti dice il file e la riga. Comincia da lì. [#_next_time] === La prossima volta Il tuo `Hello!` sta dove l'hai messo e non si muove mai. Per farlo muovere ti serve un posto dove tenere un numero che cambia -- una *variabile* -- ed è di questo che parla tutta la seconda lezione.