Giocare e vincere con Excel Gianclaudio Floria - Andrea Terzaghi Giocare e vincere con Excel Autore: Gianclaudio Floria - Andrea Terzaghi Collana: Coordinamento collana: Fabrizio Comolli Progetto grafico: escom - Milano Prima edizione ISBN: 88-8233-????? Copyright © 2006 Edizioni FAG Milano Via G.Garibaldi 5 – 20090 Assago (MI) - www.fag.it Finito di stampare: nel mese di marzo 2006 da G. Canale & C. S.p.a., Borgaro Torinese (Torino) Edizione Speciale per Vogel Burda Communications srl stampata su licenza di FAG Nessuna parte del presente libro può essere riprodotta, memorizzata in un sistema che ne permetta l’elaborazione, né trasmessa in qualsivoglia forma e con qualsivoglia mezzo elettronico o meccanico, né può essere fotocopiata, riprodotta o registrata altrimenti, senza previo consenso scritto dell’editore, tranne nel caso di brevi citazioni contenute in articoli di critica o recensioni. La presente pubblicazione contiene le opinioni dell’autore e ha lo scopo di fornire informazioni precise e accurate. L’elaborazione dei testi, anche se curata con scrupolosa attenzione, non può comportare specifiche responsabilità in capo all’autore e/o all’editore per eventuali errori o inesattezze. Nomi e marchi citati nel testo sono generalmente depositati o registrati dalle rispettive aziende. L’autore detiene i diritti per tutte le fotografie, i testi e le illustrazioni che compongono questo libro. 7. Costruire i videogiochi interattivi Se siete curiosi di capire come è possibile realizzare i giochi del capitolo precedente, scoprirete adesso che i principi alla base della programmazione dei giochi sono semplici. La difficoltà vera non è nella programmazione, ma nel trovare un’idea creativa. Dopo aver visto Pacman su Excel, vogliamo mostrare al lettore nel dettaglio come costruire questo tipo di giochi interattivi. Di fatto servono soprattutto fantasia, immaginazione e tanta voglia di divertirsi, mentre non sono richieste grandi capacità di programmazione. In questo capitolo ci concentreremo sulla programmazione, lasciando a voi il piacere di scatenare le vostre capacità creative. Gli elementi di base, comuni a tutti i giochi interattivi, sono tre: • la gestione degli eventi da tastiera: il giocatore deve premere i tasti per interagire con il gioco; 123 Giocare e vincere con Excel • la gestione del timer, per dare l’impressione del movimento facendo scorrere il tempo a intervalli regolari, in modo da far succedere continuamente qualcosa (un quadretto che si muove, una pallina che rimbalza, un fiore che gira…); • la gestione delle immagini che rappresentano gli elementi del gioco (eroi, mostri, palline, spade, proiettili, mura, cibo ecc.). Vediamo prima degli esempi semplici, in poche righe di codice, di gestione della tastiera e del timer, per comprenderne il significato. Comporremo i due elementi in un primo gioco interattivo, Snake (lo stesso che si trova sui cellulari) e infine mostreremo ancora una volta con poche righe di codice come gestire le immagini. A questo punto il lettore avrà tutti gli elementi per comprendere appieno il codice di Pacman e, dando fondo alla sua creatività e alla sua fantasia, potrà sviluppare un suo proprio gioco interattivo. Gestire gli eventi di tastiera La prima cosa da avere chiara è che il gioco deve girare all’interno di una macro, dunque non è possibile sfruttare la gestione della tastiera normale di Excel, per intenderci quella che usiamo quando scriviamo qualcosa in una cella o spostiamo il cursore nel foglio. Per fare in modo che una macro di Excel rilevi gli eventi di tastiera (pressione e rilascio di un tasto) è necessario utilizzare una funzione di libreria di Windows: Declare Function GetAsyncKeyState Lib “User32.dll” (ByVal vKey As Long) As Long La funzione GetAsyncKeyState appartiene alla libreria User32.dll. Questa, a sua volta, è una API (Application Programming Interface) di Windows. Le API sono uno strumento che ogni versione del sistema operativo Windows mette a disposizione. Esse permettono di accedere a funzionalità comuni a tutte le versioni del sistema sfruttandone appieno le potenzialità. Quella che sfrutteremo in questo caso è una semplice funzione che rileva lo stato (premuto o rilasciato) di ogni singolo tasto. La funzione restituisce un valore diverso da zero se il tasto è premuto nello stesso esatto momento in cui essa viene eseguita. 124 Giocare e vincere con Excel Il funzionamento di questa funzione è molto semplice. Richiede come argomento un numero intero che rappresenta il codice del tasto virtuale (Virtual-key Code) della tastiera. Per dirla in parole semplici, a ogni tasto corrisponde un numero, e la funzione GetAsyncKeyState interroga lo stato di quel tasto specifico che corrisponde al numero passatole. Il codice che rileva lo stato dei tasti è il seguente: Declare Function GetAsyncKeyState Lib “User32.dll” (ByVal vKey As Long) As Long Const Const Const Const Const Const VK_LEFT As Long = 37 VK_DOWN As Long = 40 VK_RIGHT As Long = 39 VK_UP As Long = 38 VK_Z As Long = 90 VK_SHIFT As Long = 16 Sub start() Dim Direzione As String While True If GetAsyncKeyState(VK_LEFT) <> 0 Then Direzione = “Sinistra” ElseIf GetAsyncKeyState(VK_RIGHT) <> 0 Then Direzione = “Destra” ElseIf GetAsyncKeyState(VK_UP) <> 0 Then Direzione = “Su” ElseIf GetAsyncKeyState(VK_DOWN) <> 0 Then Direzione = “Giu” Else Direzione = “” End If Cells(1, 1) = Direzione Wend End Sub La prima parte dichiara che nel codice verrà utilizzata la funzione e che quindi essa deve essere recuperata dalla corrispondente libreria. Si definiscono quindi delle costanti che rappresentano i codici di tasto virtuale appena discussi. Finalmente, si giunge al codice vero e proprio. Si tratta di un semplice ciclo perpetuo senza uscita dove t è sempre vero. Dunque, non si esce mai dal ciclo while-wend se non premendo Esc, cioè interrom- 125 Giocare e vincere con Excel pendo l’esecuzione della macro. All’interno del ciclo vi è una variabile Direzione che assume il valore corrispondente alla freccia premuta. Nel ciclo (che data la velocità dei calcolatori attuali viene eseguito centinaia di volte al secondo) viene infatti verificata la pressione di quattro tasti: le quattro frecce di direzione. Nel caso in cui una determinata freccia sia premuta, la funzione GetAsyncKeyState corrispondente a quel tasto restituisce un valore diverso da zero, quindi viene eseguita la parte then del corrispondente if e la variabile Direzione assume il valore corrispondente alla freccia premuta. Tale valore viene poi presentato all’utente nella cella A1, (Cells(1,1)) del foglio di lavoro attivo. Non c’e’ nulla di più. Se volete verificare la pressione di un altro tasto oltre ai tasti freccia dovete solo reperire da Internet il codice del tasto virtuale corrispondente e aggiungere un altro if-then nel ciclo. Gestire il timer per dare un ritmo al gioco Nei giochi interattivi si sfrutta quindi lo stesso principio alla base dei filmati. Si eseguono i fotogrammi del gioco in modo veloce uno sull’altro in modo da dare l’impressione del movimento. Per fare questo bisogna avere un timer che faccia eseguire il codice a un ritmo costante e sufficientemente elevato per dare alla sequenza di immagini statiche l’aspetto di un movimento. Per fare in modo che una porzione di codice venga eseguita con un ritmo cadenzato constante, anche in questo caso sono necessarie poche righe. Vediamo un piccolo programma che muove avanti e indietro una scritta sullo schermo: Sub Dim Dim Dim Dim Dim Dim Dim timer_esempio() F As Worksheet Stato As Range TIMEDELAY As Double StartTimer NSpace As Integer DIR As Integer testo As String Set F = Worksheets(“Esempio”) Set Stato = F.Cells(5, 5) 126 Giocare e vincere con Excel TIMEDELAY = 0.05 ʻvelocità di movimento DIR = 1 NSpace = 1 testo = “vado a destra -->” Do While Stato.Value <> “” DoEvents NSpace = NSpace + DIR F.Cells(10, 5).Value = Space(NSpace) & testo If NSpace < 1 Then DIR = -DIR testo = “vado a destra -->” End If If NSpace > 80 Then DIR = -DIR testo = “<-- vado a sinistra” End If StartTimer = Timer While Timer < StartTimer + TIMEDELAY Wend Loop End Sub Il codice viene eseguito fintanto che nella cella Stato è presente un valore qualunque (<>””). Il comando DoEvents permette all’utente di muovere il cursore e gestire il foglio di lavoro esattamente come se la macro non fosse in esecuzione. Ciò consente all’utente di modificare la condizione di Stato a suo piacimento. In questo caso si utilizza la funzione Timer per rilevare il tempo in termini di secondi. Timer è già inclusa in Excel, ed è sufficiente per i nostri scopi di gestione. Se si desidera invece anche in questo caso utilizzare una funzione delle API vi consigliamo GetTickCount, che rileva il numero di millisecondi trascorsi. Osservando il codice appare evidente che ci sono due cicli uno nell’altro. Il ciclo: StartTimer = Timer While Timer < StartTimer + TIMEDELAY è semplicemente un ciclo di ritardo all’interno del ciclo principale. Questo ciclo fa in modo che il ciclo principale venga eseguito una volta ogni TI- 127 Giocare e vincere con Excel MEDELAY secondi. In questo caso il ciclo principale viene eseguito una volta ogni 0,05 secondi, cioè 20 volte al secondo. Potete dunque sbizzarrirvi nella programmazione per trovare il modo migliore di dare il ritmo al vostro codice, utilizzando le funzioni di Excel oppure sfruttando le API di Windows. Torniamo al ciclo principale, che a sua volta aggiunge e toglie dalla scritta uno spazio (Space(NSpace) & testo). In questo modo la scritta si sposta di uno spazio a destra o a sinistra 20 volte al secondo. Ammettendo che sul vostro monitor uno spazio abbia le dimensioni di 2 mm, la scritta si sposterà sul vostro monitor di 2*20mm ogni secondo, cioè avrà una velocità di 4 cm al secondo. La Figura 7.1 rappresenta, uno sotto l’altro, diversi momenti dell’esecuzione della macro per dare l’idea del movimento al quale si assiste sullo schermo. Figura 7.1 - Il programma di gestione del timer in vari momenti della sua esecuzione. 128 Giocare e vincere con Excel Scriviamo un gioco interattivo: Snake Snake è un simpatico serpente che si muove all’interno di un campo di celle dove trova ostacoli e cibo. Ogni volta che mangia un boccone di cibo, oltre a fare punti, il nostro cresce di dimensioni. Lo scopo del gioco è mangiare quanto più cibo possibile senza andare a sbattere contro gli ostacoli e senza mangiarsi la coda. Per costruire questo gioco in Excel utilizzeremo lo stesso principio visto nel labirinto: coloreremo le celle in tinte diverse a seconda del loro significato. Le celle nere saranno gli ostacoli, le celle blu il cibo e le celle amaranto il nostro serpente che si sposta. In Figura 7.2 è mostrato lo schema iniziale di gioco. Figura 7.2 - La posizione iniziale di Snake. Il serpente si muove da sinistra verso destra. Lanciando l’esecuzione della macro di gioco il serpente si sposta verso destra. È possibile controllare il serpente con i tasti freccia come nell’esempio precedente fino a mangiare il cibo (Figura 7.3). Figura 7.3 - Snake, guidato dal giocatore, si avventa sul cibo. 129 Giocare e vincere con Excel Il punto è: come facciamo a muovere il serpente nella griglia? Il principio utilizzato qui è molto semplice: se il serpente non mangia il cibo allora bisogna colorare di amaranto la cella nella direzione in cui il serpente si muove e cancellare l’ultima casella della coda. Possiamo semplicemente aggiungere una casella all’inizio del serpente e toglierne una alla fine: poiché tutte le caselle che rappresentano il serpente sono uguali tra loro, questa procedura crea l’illusione che tutte le celle si spostino di una posizione nella direzione indicata. Il punto importante da rilevare è che bisogna memorizzare le coordinate di tutte le caselle del serpente, dato che prima o poi tutte verranno cancellate. Se invece il serpente mangia qualcosa allora basterà mettere una casella amaranto davanti al serpente senza cancellare l’ultima in fondo. L’effetto netto sarà l’allungamento del serpente di una casella. Per memorizzare le coordinate di tutte le caselle del serpente useremo un array circolare realizzato su un secondo foglio di supporto. Analizziamo il codice. Per prima cosa dobbiamo definire un gran numero di variabili per strutturare in modo completo il gioco (Figura 7.4). Figura 7.4 - Definizioni delle variabili necessarie per descrivere compiutamente il gioco. 130 Giocare e vincere con Excel Scorrendo le variabili si trova di tutto: le coordinate del campo di gioco sul foglio di Excel, la lunghezza del serpente, la direzione di movimento del serpente stesso, la posizione sul foglio di supporto della cella rappresentativa della testa e della coda, i colori del serpente e del cibo e altro ancora. Vale la regola che è sempre meglio abbondare con le variabili anziché cercare di complicare il codice per metterne di meno. È necessario infatti che il ciclo che genera l’illusione del movimento si ripeta il più velocemente possibile, dunque al suo interno si deve evitare di effettuare calcoli per non rallentare inutilmente il codice. Tutto ciò che si risparmia in termini di calcoli ripetuti si guadagna in fluidità e giocabilità. Definiamo a questo punto le funzioni e le costanti per la gestione della tastiera (Figura 7.5). Figura 7.5 - Definizioni delle variabili necessarie per gestire l’interazione con la tastiera. Ora inizializziamo il gioco definendo le variabili, pulendo l’area di gioco, creando il nuovo serpente e collocando il cibo in una posizione casuale nell’area di gioco: Sub init() Dim i As Integer XStart = 4 ʻ definizione della posizione YStart = 7 ʻ dellʼarea di gioco XMax = 43 YMax = 46 Area = (XMax - XStart + 1) * (YMax - YStart + 1) Set S = Worksheets(“S”) ʻ contiene le posizioni delle caselle del serpente Set C = Worksheets(“SNAKE”) ʻ contiene lʼarea di gioco Set STATUS = C.Cells(6, 3) ʻ cella contenente un valore che 131 Giocare e vincere con Excel indica se il gioco è in corso o meno Set DIR = C.Cells(5, 5) ʻ cella contenente la direzione del serpente Set PuntiCELL = C.Cells(3, XMax + 3) ʻ cella contenente il punteggio Set ExtraPuntiCell = C.Cells(4, XMax + 3) ʻ cella contenente lʼextrapunteggio STATUS.Value = “” ʻ il gioco non è in corso ʻ copiamo uno schema vuoto e pulito: azzeriamo lʼarea di gioco Sheets(“SNAKE (2)”).Select Range(“C6:AR47”).Select Selection.Copy Sheets(“SNAKE”).Select Range(“C6”).Select ActiveSheet.Paste ʻ inzializzazione del serpente L = 9 ʻlunghezza serpente iniziale XCoord = Int((XMax + XStart) / 2) - L YCoord = Int((YMax + YStart) / 2) ʻ definizione dei colori degli elementi del gioco ColorSnake = 9 ʻcolore amaranto ColorFood = 11 ʻcolore blu ʻdisegniamo il serpente For i = 1 To L S.Cells(i, 1).Value = XCoord S.Cells(i, 2).Value = YCoord C.Cells(YCoord, XCoord).Interior.ColorIndex = ColorSnake XCoord = XCoord + 1 Next SnakeHeadX = XCoord - 1 SnakeHeadY = YCoord DIR.Value = “dx” CURDIR = “dx” C.Cells(5, 5).Value = DIR SnakeStart = 9 SnakeEnd = 1 TIMEDELAY = 0.1 ʻvelocità del gioco ʻinserisci cibo in una posizione casuale ʻcerca una posizione che non contiene nulla prima di posizionare il cibo Do 132 Giocare e vincere con Excel XCoord = Int(((XMax - XStart + 1) * Rnd) + 1) + XStart YCoord = Int(((YMax - YStart + 1) * Rnd) + 1) + YStart Loop Until C.Cells(YCoord, XCoord).Interior.ColorIndex = xlNone C.Cells(YCoord, XCoord).Interior.ColorIndex = ColorFood Step = 0 Punti = 0 MaxExtraPunti = 30 Extrapunti = MaxExtraPunti PuntiCELL.Value = Punti ExtraPuntiCell = Extrapunti DIR.Select DIR.Value = “dx” ʻil gioco comincia! STATUS.Value = “On” Call snake ʻroutine di gestione del gioco End Sub Il codice è molto semplice. Genera in modo coerente tutte le variabili. Definisce e pulisce l’area di gioco, posiziona il serpente da sinistra verso destra e indica che il serpente deve muoversi a destra nel prossimo passo, quindi cerca una casella vuota dove poter collocare il cibo e lo posiziona. A questo punto attiva il gioco e fa partire la routine di gestione del serpente: Sub snake() Dim Start, Delay Dim Moved As Boolean Do While STATUS.Value = “On” Start = Timer ʻDetermina lʼistante di partenza Delay = Start + TIMEDELAY Moved = False Do If Timer > Delay Then If Not Moved Then Moved = True Extrapunti = Extrapunti - 1 If Extrapunti > 0 Then ExtraPuntiCell.Value = Extrapunti Else ExtraPuntiCell.Value = “” Extrapunti = 0 133 Giocare e vincere con Excel End If If GetAsyncKeyState(VK_LEFT) <> 0 Then DIR.Value = “sx” ElseIf GetAsyncKeyState(VK_RIGHT) <> 0 Then DIR.Value = “dx” ElseIf GetAsyncKeyState(VK_UP) <> 0 Then DIR.Value = “su” ElseIf GetAsyncKeyState(VK_DOWN) <> 0 Then DIR.Value = “giu” End If Select Case DIR.Value Case “dx” If CURDIR <> “sx” Then SnakeHeadX = SnakeHeadX CURDIR = “dx” Else SnakeHeadX = SnakeHeadX CURDIR = “sx” End If Case “su” If CURDIR <> “giu” Then SnakeHeadY = SnakeHeadY CURDIR = “su” Else SnakeHeadY = SnakeHeadY CURDIR = “giu” End If Case “giu” If CURDIR <> “su” Then SnakeHeadY = SnakeHeadY CURDIR = “giu” Else SnakeHeadY = SnakeHeadY CURDIR = “su” End If Case “sx” If CURDIR <> “dx” Then SnakeHeadX = SnakeHeadX CURDIR = “sx” Else SnakeHeadX = SnakeHeadX CURDIR = “dx” 134 + 1 - 1 - 1 + 1 + 1 - 1 - 1 + 1 Giocare e vincere con Excel End If End Select SnakeStart = (SnakeStart + 1) Mod Area S.Cells(SnakeStart + 1, 1).Value = SnakeHeadX S.Cells(SnakeStart + 1, 2).Value = SnakeHeadY ʻverifica scontro If C.Cells(SnakeHeadY, SnakeHeadX).Interior.ColorIndex = 1 Or C.Cells(SnakeHeadY, SnakeHeadX).Interior.ColorIndex = ColorSnake Then STATUS.Value = “” GoTo FineGioco ElseIf C.Cells(SnakeHeadY, SnakeHeadX).Interior. ColorIndex = ColorFood Then C.Cells(SnakeHeadY, SnakeHeadX).Interior. ColorIndex = ColorSnake ʻinserisci cibo Punti = Punti + 1 + Extrapunti Extrapunti = Extrapunti + MaxExtraPunti PuntiCELL.Value = Punti Do XCoord = Int(((XMax - XStart + 1) * Rnd) + 1) + XStart YCoord = Int(((YMax - YStart + 1) * Rnd) + 1) + YStart Loop Until C.Cells(YCoord, XCoord).Interior. ColorIndex = xlNone C.Cells(YCoord, XCoord).Interior.ColorIndex = ColorFood Else C.Cells(S.Cells(SnakeEnd + 1, 2).Value, S.Cells(SnakeEnd + 1, 1).Value).Interior.ColorIndex = xlNone SnakeEnd = (SnakeEnd + 1) Mod Area C.Cells(SnakeHeadY, SnakeHeadX).Interior. ColorIndex = ColorSnake End If End If If GetAsyncKeyState(VK_ESCAPE) <> 0 Then GoTo FineGioco End If Loop Until Moved Loop FineGioco: temp = MsgBox(“Il tuo punteggio è:” & Punti, vbOKOnly, “Snake!”) End Sub 135 Giocare e vincere con Excel Questa routine si può dividere in più parti. Vediamo un ciclo esterno che verifica lo stato del gioco: Do While STATUS.Value = “On” … Loop Al suo interno viene ripetuto indefinitamente e in modo ritmico con la funzione Timer: Start = Timer Delay = Start + TIMEDELAY Moved = False Do If Timer > Delay Then … End if Loop Until Moved Questo ciclo è leggermente differente rispetto a quello presentato nel paragrafo che descrive la funzione Timer. Il suo scopo è quello di eseguire il contenuto dell’if centrale una volta sola a ogni mossa, cioè una sola volta per ogni incremento del timer di TIMEDELAY secondi. La variabile booleana Moved gestisce il flusso del codice permettendo che l’if centrale venga eseguito una volta ogni TIMEDELAY secondi. Questa parte del codice muove di un passo il serpente. Per prima cosa deve verificare se un tasto è stato premuto: If GetAsyncKeyState(VK_LEFT) <> 0 Then DIR.Value = “sx” ElseIf GetAsyncKeyState(VK_RIGHT) <> 0 Then DIR.Value = “dx” ElseIf GetAsyncKeyState(VK_UP) <> 0 Then DIR.Value = “su” ElseIf GetAsyncKeyState(VK_DOWN) <> 0 Then DIR.Value = “giu” End If 136 Giocare e vincere con Excel Il codice è identico a quanto già visto in precedenza. In questo caso il risultato dell’analisi della tastiera viene memorizzato in una cella del foglio di lavoro, rappresentata dall’oggetto DIR (si veda la funzione Init precedente). Ora che abbiamo recuperato la direzione voluta dal giocatore, calcoliamo la nuova posizione della testa del serpente: Select Case DIR.Value Case “dx” If CURDIR <> “sx” Then SnakeHeadX = SnakeHeadX + 1 CURDIR = “dx” Else SnakeHeadX = SnakeHeadX - 1 CURDIR = “sx” End If … End Select Il codice verifica se la direzione voluta dal giocatore è “dx” e, in questo caso, prima di modificare la direzione mandando il serpente verso destra verifica che il serpente non si stia muovendo verso sinistra. In questo caso, infatti, farebbe tornare il serpente sui suoi passi, il che non è concesso dal gioco: solo se la direzione attuale non è “sx” gira il serpente nella direzione “dx”, altrimenti lo lascia proseguire verso “sx”. Lo stresso identico controllo viene eseguito per le altre tre direzioni. Memorizziamo ora la nuova posizione della testa nell’array circolare: SnakeStart = (SnakeStart + 1) Mod Area S.Cells(SnakeStart + 1, 1).Value = SnakeHeadX S.Cells(SnakeStart + 1, 2).Value = SnakeHeadY La funzione Mod consente di realizzare l’array corcolare senza sforzo. Con questo comando SnakeStart si incrementa sempre di uno; quando raggiunge la dimensione massima (Area) allora ricomincia da 0 restando sempre confinato tra i valori 0 e Area-1. Le coordinate della testa del serpente verranno memorizzate nelle celle con riga da 1 a Area. 137 Giocare e vincere con Excel Verifichiamo lo scontro della testa con un ostacolo (colore 1) o con se stesso: If C.Cells(SnakeHeadY, SnakeHeadX).Interior.ColorIndex = 1 Or C.Cells(SnakeHeadY, SnakeHeadX).Interior.ColorIndex = ColorSnake Then STATUS.Value = “” GoTo FineGioco In questo caso annulliamo lo stato del gioco e terminiamo la partita portando l’esecuzione alla posizione del codice indicata con FineGioco. In caso contrario (il serpente non è morto) verifichiamo se c’era del cibo nella posizione ora occupata dalla testa: ElseIf C.Cells(SnakeHeadY, SnakeHeadX).Interior.ColorIndex = ColorFood Then In questo caso il codice colora il cibo con la tinta della testa (il serpente mangia il cibo), incrementa il punteggio e inserisce un nuovo boccone di cibo: C.Cells(SnakeHeadY, SnakeHeadX).Interior.ColorIndex = ColorSnake ʻinserisci cibo Punti = Punti + 1 + Extrapunti Extrapunti = Extrapunti + MaxExtraPunti PuntiCELL.Value = Punti Do XCoord = Int(((XMax - XStart + 1) * Rnd) + 1) + XStart YCoord = Int(((YMax - YStart + 1) * Rnd) + 1) + YStart Loop Until C.Cells(YCoord, XCoord).Interior. ColorIndex = xlNone C.Cells(YCoord, XCoord).Interior.ColorIndex = ColorFood Infine, se il serpente non si è scontrato con gli ostacoli o con se stesso e non ha mangiato cibo, significa che si è mosso in una casella vuota. Dunque bisogna semplicemente spostarlo di una casella cancellando l’ultimo pezzo di coda: Else C.Cells(S.Cells(SnakeEnd + 1, 2).Value, S.Cells(SnakeEnd + 1, 1).Value).Interior.ColorIndex = xlNone 138 Giocare e vincere con Excel SnakeEnd = (SnakeEnd + 1) Mod Area C.Cells(SnakeHeadY, SnakeHeadX).Interior. ColorIndex = ColorSnake End If In tutto questo giro le variabili SnakeEnd e SnakeStart tengono traccia delle coordinate della testa e della coda all’interno dell’array circolare. La routine di gestione del serpente è terminata. In essa vi è anche la gestione della variabile ExtraPunti, di cui non abbiamo parlato. Lasciamo al lettore la curiosità di verificare direttamente sul gioco qual è lo scopo di questa variabile. Migliorare la grafica con gli sprite Il gioco Snake che abbiamo appena costruito, pur essendo perfettamente funzionante, ha un grave difetto: la grafica è orribile. Il gioco si realizza con caselle di Excel che si colorano di amaranto, blu e nero. La testa del serpente è identica alla coda; si intuisce la differenza tra testa e coda solo guardando il movimento. La grafica, insomma, ricorda i primi videogiochi degli anni Settanta. Per fortuna con Excel si può fare di meglio! In questa parte del capitolo vedremo come fare in modo che in Excel possano vedersi astronavi che sfrecciano, palle che rotolano e omini che saltano con la stessa qualità grafica che abbiamo visto nel Pacman del capitolo precedente. Per dare l’illusione di un movimento fluido degli oggetti si utilizza ancora una volta la logica del cinema o, per rendere meglio l’idea, lo stesso principio dei libretti dei bambini con le immagini in movimento. Sono libretti con tante pagine ognuna delle quali rappresenta un oggetto in una posizione leggermente differente; sfogliando velocemente il libretto si vedono si ha l’impressione di un oggetto in movimento. Nel linguaggio dei videogiochi, ognuna delle immagini che rappresenta l’oggetto in pose leggermente diverse è detta sprite. Per muovere gli oggetti dovremo generare una sequenza di immagini (sprite) della stessa dimensione e leggermente differenti l’una dall’altra. Per farlo in Excel, per prima cosa dobbiamo avere uno spazio adeguato dove rappresentare gli oggetti: dimensioniamo tutte le colonne a una larghezza di 0,42 e tutte le righe a un’altezza di 8, in modo che appaiano 139 Giocare e vincere con Excel quadrate sullo schermo, e riduciamo lo zoom al 10%. In questo modo ogni singola cella è diventata molto piccola e si confonde con i pixel dello schermo. Sfrutteremo proprio questa confusione per utilizzare aree di 30x30 celle e realizzare immagini che appariranno sullo schermo di dimensioni 30x30 pixel. Coloreremo lo sfondo di ogni singola cella come se fosse un pixel di un’immagine. Per dare l’illusione del movimento è ora sufficiente creare tanti sprite dello stesso oggetto leggermente differenti l’uno dall’altro e scrivere una macro che sostituisce gli sprite velocemente sul foglio di Excel. Se studiamo con attenzione lo zoom del foglio e le dimensioni delle righe e delle colonne, il risultato sarà molto piacevole. Vediamo, per esempio, come far rotolare una palla colorata sul foglio di Excel. In Figura 7.6 potete osservare il foglio di lavoro ridotto a dimensioni minuscole e la palla disegnata su di esso colorando ad arte le celle. Figura 7.6 - Esempio di pallina generata su un gruppo di celle Excel ridotte a dimensioni minimali. Il risultato è ottimo se confrontato con Snake. Si noti che la dimensione della visualizzazione delle celle è stata ridotta al 10%. Ingrandiamo l’area della pallina per verificare come è realizzata (Figura 7.7). Come risulta evidente, le singole caselle sono state dimensionate in modo da apparire quadrate sullo schermo e colorate per formare una pallina dalle dimensioni di 30x30 pixel. Passiamo ora alla seconda fase: far rotolare la pallina sullo schermo: come si è detto sono sufficienti alcune immagini differenti per le diverse posizioni della pallina stessa durante il rotolamento (Figura 7.8). 140 Giocare e vincere con Excel Figura 7.7 - Lo stesso foglio di lavoro dell’immagine precedente ingrandito per mostrare i dettagli di realizzazione della pallina. Figura 7.8 - Le varie posizioni della pallina durante il rotolamento. Tante più immagini differenti si realizzano, tanto più il movimento apparirà fluido e senza scatti. Questo comporterà però uno sforzo di progettazione delle immagini maggiore. Inserendo le palline di Figura 7.8 in un foglio di supporto e scrivendo una macro che sostituisce velocemente le immagini sul campo di gioco otterremo l’effetto del rotolamento. Il codice è il seguente: Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim P As Worksheet C As Worksheet Pallina As Range Dest As Range Nulla As Range X As Long Y As Long L As Integer H As Integer Ogni As Integer Sub Muovi_SPRITE() 141 Giocare e vincere con Excel Dim Start Dim Img As Integer Dim passi As Long Dim VarPassi As Integer Dim Vx As Integer Dim Vy As Integer Dim OldImg As Integer Dim TIMEDELAY As Double On Error GoTo ErrH Application.EnableCancelKey = xlErrorHandler TIMEDELAY = 0.012 Ogni = 6 Cells.Select Selection.Interior.ColorIndex = 1 Range(“A1”).Select Set P = Worksheets(“Pallina”) Set C = Worksheets(“Campo”) X = 100 Y = 100 L = 31 H = 30 Vx = 1 Vy = -1 Set Pallina = P.Cells(1 + 35 * SPRITE, 2).Resize(L, H) Set Nulla = P.Cells(1, 90).Resize(L, H) Set Dest = C.Cells(Y, X).Resize(L, H) Pallina.Copy Destination:=Dest passi = 1 VarPassi = 1 OldImg = 1 Do While True passi = passi + VarPassi Img = (passi \ Ogni) Mod 18 If Img <> OldImg Then Set Pallina = P.Cells(1 + 35 * Img, 2).Resize(L, H) OldImg = Img End If Nulla.Copy Destination:=Dest X = X + Vx Y = Y + Vy If X > 220 Then Vx = -Vx If X < 5 Then Vx = -Vx If Y < 5 Then Vy = -Vy If Y > 500 Then Vy = -Vy Set Dest = C.Cells(Y, X).Resize(L, H) 142 Giocare e vincere con Excel Pallina.Copy Destination:=Dest Start = Timer ʻDetermina lʼistante di partenza Do While Timer < Start + TIMEDELAY Loop Loop ErrH: Temp = MsgBox(“Uscire dalla rountine?”, vbYesNo, “Pallina!!!”) If Temp = vbNo Then Resume Next End Sub Ancora una volta, la prima parte del codice è dedicata alla definizione delle variabili necessarie. Il tutto è inserito in una routine Muovi_SPRITE, che utilizza il foglio definito come “P” per recuperare le varie immagini della pallina in posizioni diverse e il foglio “C” come campo di gioco della pallina nel suo rotolamento. Si utilizzano tre variabili: • “Pallina” per definire l’insieme (range) di celle che contiene l’immagine corrente della pallina; • “Nulla” per definire un’area delle medesime dimensioni della precedente ma contenente solo celle senza colore; • “Dest” per definire il range di celle che conterrà la pallina sul campo di gioco. L’algoritmo, in estrema sintesi, colora Dest alternativamente con i colori presenti nei range rappresentati da Pallina e da Nulla per generare l’effetto di rotazione. Contemporaneamente, sposta le coordinate di Dest per trasformare la rotazione in rotolamento. Per sostituire rapidamente i colori da un gruppo di celle a un altro si sono sfruttati i comandi: Pallina.Copy Destination:=Dest Nulla.Copy Destination:=Dest Che copiano rispettivamente il contenuto di Pallina e di Nulla in Dest. 143 Giocare e vincere con Excel Per muovere la Pallina si utilizzano due variabili Vx e Vy che rappresentano la velocità lungo gli assi X e Y della pallina stessa. Quando la pallina raggiunge i bordi del campo di gioco, la routine inverte Vx o Vy costringendola a ritornare verso il centro del campo. Il risultato è una pallina che rimbalza da tutte le parti mentre, sostituendo rapidamente le immagini della pallina stessa ad angoli differenti, si ha l’impressione che rotoli. La Figura 7.9 rappresenta la posizione della pallina in istanti successivi dell’esecuzione della macro. La freccia indica il movimento compiuto dalla pallina, che rimbalza sul bordo dell’area di lavoro mentre ruota su se stessa. Figura 7.9 - Alcuni momenti dell’esecuzione della macro. Per terminare la descrizione dell’algoritmo si è inserito il ciclo di ritardo per dare il ritmo al codice: Do While Timer < Start + TIMEDELAY Loop Migliorare la grafica con le immagini L’atra tecnica che si può sfruttare per gestire una grafica accattivante in Excel è quella suggerita da Carlos Rondão sul suo sito www.cyberbolsa. cea.ucp.pt/informatica/download. Carlos utilizza la tecnica degli shapes. In un foglio di Excel è possibile collocare vari oggetti oltre a formule e 144 Giocare e vincere con Excel scritte. A noi interessa inserire un’immagine con il comando Inserisci > Immagine > Da file (Figura 7.10). Figura 7.10 - Il comando per inserire un’immagine in un file di Excel. Una volta selezionata, l’immagine essa apparirà nella cartella di lavoro e farà parte integrante del foglio. Sarà tanto integrata che Excel stesso le darà un nome, come mostrato in Figura 7.11. Figura 7.11 - Immagine inserita e nominata automaticamente da Excel. La faccina che sorride è inserita nel foglio e Excel le ha assegnato il nome “Immagine 1”. A questo punto potete rinominare l’immagine come meglio credete. Poiché tale oggetto ha un nome, è possibile riferirsi a esso all’interno del codice VBA: Sub sposta_faccina() Worksheets(“Foglio1”).Shapes(“Immagine 1”).Top = 50 145 Giocare e vincere con Excel Worksheets(“Foglio1”).Shapes(“Immagine 1”).Left = 200 Worksheets(“Foglio1”).Shapes(“Immagine 1”).IncrementRotation 30 End Sub Il codice dice di spostare l’angolo in alto a sinistra dell’immagine (Top, Left) alle coordinate 50,200 e di ruotare l’immagine di 30° in senso orario. Il risultato è mostrato in Figura 7.12. Figura 7.12 - L’immagine manipolata dal codice VBA. È anche possibile sfruttare (come Carlos fa nelle sue macro) le coordinate delle celle di Excel. Si possono recuperare nel codice VBA le coordinate dell’angolo in alto a sinistra di una specifica cella attraverso i comandi: Sub sposta_faccina2() T = Worksheets(“Foglio1”).Cells(4, 5).Top L = Worksheets(“Foglio1”).Cells(4, 5).Left Worksheets(“Foglio1”).Shapes(“Immagine 1”).Top = T Worksheets(“Foglio1”).Shapes(“Immagine 1”).Left = L End Sub Si ottiene così il risultato di Figura 7.13, dove l’immagine si sovrappone alla cella. 146 Giocare e vincere con Excel Figura 7.13 - Il posizionamento dell’immagine dipende dalle coordinate della cella. Attraverso questa tecnica è possibile evitare di colorare una cella (come abbiamo fatto nell’esempio di Snake) e inserire invece un’immagine che la copra perfettamente. Tale immagine rappresenterà una pallina, un mostro, un insetto. Questa tecnica è utilizzata magistralmente da Carlos Rondão nel suo gioco Snake, dove le immagini che si sovrappongono alle celle sono i vari segmenti del serpente. Vediamo ora un esempio di un codice che muove un’immagine inserita in un foglio Excel. Si tratta di una piccola pallina che ruota intorno a un centro; con i tasti Freccia destra e Freccia sinistra è possibile modificare la distanza della pallina stessa dal centro per farle compiere delle spirali (Figura 7.14). Figura 7.14 - Immagine di una palla che gira in tondo sul foglio di Excel. 147 Giocare e vincere con Excel La palla che deve girare per il foglio di lavoro è stata nominata codice che la fa muovere è il seguente: PALLA. Option Explicit Declare Function GetAsyncKeyState Lib “User32.dll” (ByVal vKey As Long) As Long Const VK_LEFT As Long = 37 Const VK_DOWN As Long = 40 Const VK_RIGHT As Long = 39 Const VK_UP As Long = 38 Const VK_Z As Long = 90 Const VK_SHIFT As Long = 16 Sub muovi_PALLA() Dim a As Double Dim TIMETOT As String Dim T, TInit, TStep Dim step As Integer Dim Direzione As String Dim raggio As Integer Direzione = “” raggio = 60 TIMETOT = 1 T = 0.03 TInit = Timer a = 0 step = 2 While Timer < TInit + TIMETOT DoEvents Application.Interactive = False If GetAsyncKeyState(VK_LEFT) <> 0 Then Direzione = “Sinistra” raggio = raggio - 1 If raggio < 10 Then raggio = 10 ElseIf GetAsyncKeyState(VK_RIGHT) <> 0 Then Direzione = “Destra” raggio = raggio + 1 If raggio > 100 Then raggio = 100 Else Direzione = “” End If Cells(1, 1) = Direzione Cells(3, 13) = raggio a = a + 2 * 3.141592 / 360 * step 148 Il Giocare e vincere con Excel Worksheets(“Sheet1”).Shapes(“PALLA”).Top = Round(150 + Sin(a) * raggio) Worksheets(“Sheet1”).Shapes(“PALLA”).Left = Round(150 + Cos(a) * raggio) TStep = Timer While Timer < TStep + T Wend Wend Application.Interactive = True End Sub Il codice è basato su un ciclo esterno di venti secondi regolabile con la variabile TIMETOT. L’animazione, dunque, durerà venti secondi; in questo tempo verrà eseguita continuativamente la parte interna del ciclo che muove la palla sullo schermo. La sua velocità di movimento è regolata attraverso un ciclo di ritardo dalla variabile T. Nel ciclo while-wend vengono eseguite le seguenti azioni: • verifica della pressione dei tasti. Se sono state premuti i tasti Freccia destra e sinistra viene modificato il raggio del cerchio; • si calcola il nuovo angolo e si sposta la PALLA nella nuova posizione. Per visualizzare il movimento della palla si utilizza il comando DoEvents, che consente a Excel di aggiornare la posizione della palla sullo schermo. Tale istruzione, però, permette anche all’utente di spostare il cursore, di inserire testi nelle celle, di interagire insomma con Excel esattamente come se la macro non ci fosse. Questo comporta un problema di gestione dell’interfaccia di importanza cruciale. È quindi necessario permettere a Excel di eseguire gli eventi (dunque di spostare l’oggetto) ma bisogna inibire l’interattività con l’utente. L’istruzione: Application.Interactive = False ha esattamente questo scopo. Attenzione: se eseguite una macro con questa istruzione e non eseguite l’istruzione: Application.Interactive = True che riporta le cose alla normalità, non potrete più interagire con Excel! 149 Giocare e vincere con Excel L’unica alternativa che avrete a questo punto è chiudere Excel da Program Manager e ovviamente perdere tutto ciò che non era stato salvato. Fate quindi molta attenzione quando usate questi comandi ed evitate che la macro si interrompa a metà! In questo caso, infatti, sarà stato eseguito il comando: Application.Interactive = False ma non la sua controparte e dunque, anche se il codice fosse stato corretto, si avrebbe comunque la perdita della sessione aperta. Ci sono anche altri due modi per ottenere lo stesso risultato. La prima alternativa, meno piacevole dal punto di vista dell’esperienza di gioco, è quella di eliminare i comandi: • DoEvents; • Application.Interactive = True; • Application.Interactive = False. e inserire al loro posto il comando Application.ScreenUpdating = True all’interno del ciclo while-wend. Questa istruzione esegue un refresh di tutto lo schermo (e non solo della palla) producendo un risultato analogo a DoEvents, ma con lo svantaggio che l’immagine diventa leggermente tremolante. Il vantaggio è che non si rischia di perdere il controllo di Excel. L’altra possibilità che ci sentiamo di consigliare per la gestione della tastiera è quella di lasciare il comando DoEvents senza però i due comandi Application.Interactive. In questa situazione l’utente può spostare il cursore tra le celle liberamente come se la macro non stesse funzionando. Si gestisce allora l’evento Worksheet_SelectionChange del foglio di lavoro per riportare sempre il cursore nella stessa cella (in questo caso E3): Private Sub Worksheet_SelectionChange(ByVal Target As Range) Range(“E3”).Activate End Sub Questo codice non deve essere inserito in un modulo ma nel foglio di lavoro nel quale si trova la palla (o il gioco da gestire) facendo doppio clic sul nome del foglio nell’area del progetto di Figura 1.1. 150 Giocare e vincere con Excel Anche questo metodo ha vantaggi e svantaggi: il vantaggio, ancora una volta, è che non si rischia di perdere il controllo di Excel; lo svantaggio è che anche quando la macro non funziona l’evento Worksheet_SelectionChange viene eseguito e il cursore resta incastrato sempre nella cella E3. La soluzione si complica, allora, perché bisogna avere una cella del foglio di lavoro controlli se la macro sia attivata o meno. Solo sapendo se la macro è in funzione è possibile definire il comportamento dell’evento incriminato, lasciando libero il cursore quando la macro è inattiva e invece incastrando il cursore quando la macro è attiva: Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Cells(2, 2) = “On” Then Range(“E3”).Activate End Sub Ovviamente la cella (2,2) viene posta a “On” all’inizio della macro (cells(2,2)=”On”) e azzerata (Cells(2,2)=””) al termine della stessa. A voi resta solo la scelta di quale tecnica sia meglio utilizzare tra quelle esposte. Con poche modifiche al codice, seguendo la falsa riga di quanto fatto per gli sprite, potrete persino gestire le immagini in movimento: come per gli sprite, così per le immagini basta creare una sequenza di immagini leggermente diverse le une dalle altre, e periodicamente sostituire nella posizione dell’oggetto le immagini che lo costituiscono. L’effetto è assicurato! Immagini 3D Per utilizzare una grafica tridimensionale sul proprio foglio di Excel è necessario gestire moltissime informazioni riguardo alla scena che si vuole rappresentare, a partire dal punto di vista e dalle posizioni nello spazio tridimensionale dei vertici di tutte le figure che si devono proiettare sullo schermo. Oltre a una base di dati molto complessa dove tracciare tutte le informazioni riguardanti la scena, è necessaria anche una discreta potenza di calcolo. Proprio per questo motivo, i giochi tridimensionali più affermati utilizzano delle librerie grafiche, che consentono di sfruttare appieno la potenza degli acceleratori presenti in tutte le moderne schede video. La mole di calcoli e la velocità necessarie per rendere un effetto realistico non consentono di realizzare gli stessi effetti semplicemente utilizzando il VBA di Excel. 151 Giocare e vincere con Excel È invece possibile creare e gestire su un foglio di lavoro degli oggetti tridimensionali sfruttando le caratteristiche grafiche del programma. L’esempio che segue è ancora una volta basato su un’idea di Carlos Rondão. Si tratta di utilizzare le forme di Excel e di aggiungere a queste la terza dimensione mediante l’utilizzo della barra dei comandi Impostazioni 3D, attivabile con un pulsante a partire dalla barra Disegno. Figura 7.15 - La barra Impostazioni 3D. Si parte disegnando una forma qualsiasi (per esempio un rettangolo) e attraverso la barra Impostazioni 3D si aggiunge la terza dimensione, si imposta la direzione di illuminazione e lo spessore dell’oggetto. Con pochi e semplici passaggi si ottiene l’oggetto rappresentato in Figura 7.16. Figura 7.16 - Un rettangolo a cui è stata aggiunta la terza dimensione per renderlo un parallelepipedo. In Figura 7.17 sono invece mostrate alcune delle opzioni configurabili nella barra Impostazioni 3D. Ovviamente le capacità di Excel nella rappresentazione di oggetti 3D sono limitate, ma comprendono tutti gli elementi di base per costruire strutture 152 Giocare e vincere con Excel interessanti e gradevoli. In queste pagine vedremo solo come muovere questi oggetti, lasciando al lettore il compito di inventare nuovi modi per utilizzare questa tecnica al fine di creare immagini più complesse. Figura 7.17 - Alcune opzioni per le impostazioni 3D. Vediamo ora il codice per muovere la “scatola” appena costruita. La premessa fondamentale per comprendere il codice è che al parallelepipedo è stato associato il nome figura. Il codice è costituito da due elementi: • il primo si trova all’interno del modulo Modulo1; • il secondo è associato ai pulsanti e risiede fisicamente all’interno dello spazio del codice associato al foglio di lavoro Foglio1. Vediamo il codice presente in Modulo1; si noti sulla sinistra (Figura 7.18) che il Modulo1 è evidenziato come attivo. 153 Giocare e vincere con Excel Figura 7.18 - La prima parte del codice. Il codice presenta una prima parte di dichiarazione che definisce tre variabili: • l’angolo di rotazione lungo l’asse X (RotX); • l’angolo di rotazione lungo l’asse Y (RotY); • una variabile di controllo del flusso della macro (FINECOMPITO). Queste variabili saranno utilizzate sia nel codice sottostante sia nella seconda parte del codice. La procedura CliccaFigura() è chiamata ogni volta che con il mouse si fa clic con il pulsante sinistro sulla scatola in movimento. Questa procedura gestisce l’interattività con l’utente. La procedura cambia verso di rotazione sia sull’asse X sia sull’asse Y e modifica il colore della figura (.Fill.ForeColor.SchemeColor), facendo ruotare i colori tra il codice 2 e il codice 8. Si noti l’uso del comando with per evitare di ripetere a ogni riga il codice ActiveSheet.Shapes(NomeShape). Per fare in modo che a ogni clic sulla figura corrisponda l’esecuzione della macro CliccaFigura() bisogna associare alla figura stessa la macro come mostrato in Figura 7.19. 154 Giocare e vincere con Excel Figura 7.19 - Alla figura deve essere associato il codice che permette l’interazione con l’utente. Vediamo ora la seconda parte del codice, che esegue effettivamente la rotazione della figura. Figura 7.20 - La parte del codice che esegue la rotazione della figura. 155 Giocare e vincere con Excel Per prima cosa notiamo che questa parte si trova all’interno di Foglio1. Questo per mostrare come non sia necessario creare un modulo ogni volta che si inserisce del codice. Il codice inserito in questo spazio può essere attivato anche a seguito di eventi che avvengono all’interno del foglio di lavoro. Ogni volta che si compie un’azione su un foglio, come spostare il cursore, modificare una cella, fare clic con il mouse e così via, Excel va a verificare all’interno di questo spazio se esiste una porzione di codice corrispondente all’evento. Nel caso la trovi, la esegue all’istante. Nel nostro esempio abbiamo sfruttato questa funzionalità. I due pulsanti che compaiono nel foglio di lavoro sono stati nominati INIZIO e FINE. Al clic sul pulsante INIZIO viene eseguita la porzione di codice identificata all’interno della procedura Private Sub INIZIO_Click(). Alla pressione del pulsante FINE viene invece eseguita la porzione di codice presente nella procedura Private Sub FINE_Click(). La procedura INIZIO_Click() definisce la variabile FINECOMPITO a False e poi entra in un ciclo infinito, dato che all’interno di tale ciclo non viene mai modificato il valore della variabile FINECOMPITO che consente di terminare il ciclo stesso. La variabile viene invece modificata da FINE_Click(). La domanda che ci dobbiamo porre è: ma se sono all’interno del ciclo infinito di INIZIO_Click(), quando viene eseguita la routine FINE_Click()? Questo mistero si risolve pensando con una logica di esecuzione del codice non sequenziale ma a eventi: la routine di FINE viene eseguita al momento del clic sul pulsante corrispondente, interrompendo l’esecuzione del ciclo infinito. A questo punto, terminata la gestione dell’evento FINE_Click(), l’esecuzione del codice riprenderà il ciclo infinito di INIZIO_Click(), ma ora la variabile FINECOMPITO ha cambiato stato e dunque il ciclo non sarà più infinito, ma terminerà anch’esso. La garanzia che si possa fare clic sul pulsante FINE è data dal fatto che all’interno della gestione di INIZIO appare il comando DoEvents, che rende appunto possibile il gioco degli eventi appena descritto. Passiamo ora all’analisi del codice. Il codice permette di ruotare la scatola lungo tutti e tre gli assi con i comandi: • .IncrementRotation per lʼasse Z; • .ThreeD.RotationX per lʼasse X; 156 Giocare e vincere con Excel • .ThreeD.RotationY per lʼasse Y. Il codice in se è molto semplice in quanto ruota la scatola lungo i tre assi a ogni ciclo e poi attende un decimo di secondo prima di eseguire la successiva rotazione. In questo tempo Excel si mette in ascolto dell’utente con l’istruzione DoEvents, mentre l’utente può fare clic su FINE oppure sulla scatola stessa. Nel primo caso interrompe la rotazione, mentre nel secondo fa eseguire la routine CliccaFigura() cambiando il colore alla scatola e il senso di rotazione. In Figura 7.21 potete apprezzare varie posizioni e colori della scatola durante l’esecuzione della macro. Figura 7.21 - Alcuni momenti dell’esecuzione della macro. E adesso, la palla passa a voi! Abbiamo descritto tutti gli elementi di base per la costruzione di un gioco interattivo. Il prossimo passo, che lasciamo al lettore, è quello di combinare gli sprite o la gestione delle immagini con la gestione dell’interattività per costruire un gioco avvincente con una grafica accattivante. Sul sito collegato al libro potrete trovare gli esempi di queste pagine. Vi invitiamo a scaricare il file Excel contenente la pallina colorata dell’esempio degli sprite e di concepire un vostro gioco per Excel. Potreste realizzare, per esempio: • un gioco di ping-pong; 157 Giocare e vincere con Excel • • • • il gioco del muretto; una simulazione di una pallina elastica che rimbalza su un pavimento; una simulazione del pianeta Terra che ruota attorno al Sole; un gioco dove la pallina è magnetizzata e attratta dagli altri elementi del campo di gioco; • qualsiasi altra cosa vi venga in mente! Gli autori sono a vostra disposizione per raccogliere i vostri giochi e inserirli nei propri siti Web (www.excelling.it e www.terzaghi.it), nelle pagine dedicate a questo libro, citandovi come autori del gioco. A questo punto, possiamo solo augurarvi buon divertimento! Risorse sul Web Per informazioni riguardo alle API e alla funzione di gestione della tastiera cercate sul sito ufficiale di Microsoft: • documentazione sulle API: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog/winprog/overview_of_the_ windows_api.asp; • gestione della tastiera: http://msdn.microsoft.com/library/default. asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/getasynckeystate.asp; • elenco dei codici dei tasti virtuali: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/WindowsUserInterface/UserInput/VirtualKeyCodes.asp; • la funzione per determinare il numero di millisecondi trascorsi: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ sysinfo/base/gettickcount.asp; • il sito di Carlos Rondão: www.cyberbolsa.cea.ucp.pt/informatica/ download. 158