Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
con Excel
Collana:
Prima edizione
ISBN: 88-8233-?????
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.
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 è possibi-
un’idea creativa.
Dopo aver visto Pacman su Excel, vogliamo mostrare al lettore nel detta-
glio come costruire questo tipo di giochi interattivi.
Di fatto servono soprattutto fantasia, immaginazione e tanta voglia di di-
vertirsi, 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
124
Giocare e vincere con Excel
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 defi-
niscono 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
Sub timer_esempio()
Dim F As Worksheet
Dim Stato As Range
Dim TIMEDELAY As Double
Dim StartTimer
Dim NSpace As Integer
Dim DIR As Integer
Dim testo As String
Set F = Worksheets(“Esempio”)
Set Stato = F.Cells(5, 5)
126
Giocare e vincere con Excel
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 sco-
pi 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
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 mi-
gliore 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 spo-
sterà 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’esecu-
zione 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
129
Giocare e vincere con Excel
Figura 7.4 - Definizioni delle variabili necessarie per descrivere compiutamente il gioco.
130
Giocare e vincere con Excel
Figura 7.5 - Definizioni delle variabili necessarie per gestire l’interazione con la tastiera.
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
Sheets(“SNAKE (2)”).Select
Range(“C6:AR47”).Select
Selection.Copy
Sheets(“SNAKE”).Select
Range(“C6”).Select
ActiveSheet.Paste
ʻ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
End Sub
Sub snake()
Dim Start, Delay
Dim Moved As Boolean
133
Giocare e vincere con Excel
End If
134
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:
Start = Timer
Delay = Start + TIMEDELAY
Moved = False
Do
If Timer > Delay Then
…
End if
Loop Until Moved
136
Giocare e vincere con Excel
137
Giocare e vincere con Excel
If C.Cells(SnakeHeadY, SnakeHeadX).Interior.ColorIndex = 1 Or
C.Cells(SnakeHeadY, SnakeHeadX).Interior.ColorIndex = ColorSnake
Then
STATUS.Value = “”
GoTo FineGioco
In questo caso il codice colora il cibo con la tinta della testa (il serpente man-
gia il cibo), incrementa il punteggio e inserisce un nuovo boccone di cibo:
Else
C.Cells(S.Cells(SnakeEnd + 1, 2).Value,
S.Cells(SnakeEnd + 1, 1).Value).Interior.ColorIndex = xlNone
138
Giocare e vincere con Excel
139
Giocare e vincere con Excel
140
Giocare e vincere con Excel
Dim P As Worksheet
Dim C As Worksheet
Dim Pallina As Range
Dim Dest As Range
Dim Nulla As Range
Dim X As Long
Dim Y As Long
Dim L As Integer
Dim H As Integer
Dim 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:
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 diver-
se 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’imma-
gine corrente della pallina;
• “Nulla” per definire un’area delle medesime dimensioni della pre-
cedente ma contenente solo celle senza colore;
• “Dest” per definire il range di celle che conterrà la pallina sul cam-
po 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’effet-
to 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
143
Giocare e vincere con Excel
144
Giocare e vincere con Excel
Sub sposta_faccina()
Worksheets(“Foglio1”).Shapes(“Immagine 1”).Top = 50
145
Giocare e vincere con Excel
End Sub
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
146
Giocare e vincere con Excel
147
Giocare e vincere con Excel
La palla che deve girare per il foglio di lavoro è stata nominata PALLA. Il
codice che la fa muovere è il seguente:
Option Explicit
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
Giocare e vincere con Excel
End Sub
Application.Interactive = False
Application.Interactive = True
che riporta le cose alla normalità, non potrete più interagire con Excel!
149
Giocare e vincere con Excel
Application.Interactive = False
150
Giocare e vincere con Excel
Immagini 3D
Per utilizzare una grafica tridimensionale sul proprio foglio di Excel è neces-
sario gestire moltissime informazioni riguardo alla scena che si vuole rappre-
sentare, a partire dal punto di vista e dalle posizioni nello spazio tridimen-
sionale dei vertici di tutte le figure che si devono proiettare sullo schermo.
Oltre a una base di dati molto complessa dove tracciare tutte le informazio-
ni 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
In Figura 7.17 sono invece mostrate alcune delle opzioni configurabili nel-
la 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
153
Giocare e vincere con Excel
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 se-
conda 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 rotazio-
ne sia sull’asse X sia sull’asse Y e modifica il colore della figura (.Fill.Fo-
reColor.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.
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 vol-
ta 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 sfrut-
tato questa funzionalità.
I due pulsanti che compaiono nel foglio di lavoro sono stati nominati INI-
ZIO 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_Cli-
ck()? 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’esecu-
zione del ciclo infinito. A questo punto, terminata la gestione dell’evento
FINE_Click(), l’esecuzione del codice riprenderà il ciclo infinito di INI-
ZIO_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 al-
l’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
157
Giocare e vincere con Excel
158