Il quiz viene utilizzato in vari ambiti e ovviamente, con Internet, i quiz si sono espansi a macchia d'olio, ciò grazie soprattutto alla possibilità di creare delle strutture popolabili con domande prese da fonti esterne.
Utilizzando Flash CS3 e Actionscript 3 è possibile creare un filmato in grado di caricare una serie di domande e risposte, da un file XML, basterà variare la fonte per trovarci di fronte un quiz totalmente nuovo, pur mantenendo la struttura "principale" e tutte le sue caratteristiche: in pratica con una sola struttura "base" potremo caricare qualsiasi tipo di quiz, a patto ovviamente che il file XML rispetti la struttura richiesta dal filmato.
Preparazione dello stage
Il nostro quiz avrà una semplice schermata iniziale (graficamente uguale alle schermate di gioco) e una schermata finale per informare il giocatore del termine del gioco, andremo quindi a creare due fotogrammi chiave sulla linea temporale di un nuovo FLA.
Nel primo fotogramma inseriamo il pulsante per avviare il gioco (pulsante con nome istanza gioca
), oltre ad eventuali elementi decorativi (titolo del quiz, logo, linee o altri elementi grafici per delimitare la domanda e dividerla dalle risposte).
La stessa struttura sarà riproposta nel secondo fotogramma, che però avrà per il pulsante una diversa etichetta (ad esempio "Gioca ancora") e nome istanza rigioca
.
Creazione delle icone per le risposte
Oltre alle schermate di inizio e fine gioco avremo anche bisogno di alcuni elementi aggiuntivi (che aggiungeremo dinamicamente al nostro filmato durante l'esecuzione) e precisamente delle "icone/cursori" per le alternative (che saranno anche il metodo con cui l'utente potrà dare la sua risposta) e un clip che funzionerà da timer.
Possiamo creare la clip per le icone inserendo un nuovo simbolo (Insert -> New Symbol oppure Ctrl+F8), scegliendo come tipologia Movieclip. Poichè creeremo dinamicamente tramite Actionscript un'icona per ogni risposta andiamo ad impostare l'esportazione per Actionscript di questa clip.
Ogni icona avrà al suo interno una campo di testo dinamico (con nome istanza lettera
) che utilizzeremo per dare un'identificazione alla risposta (le classiche "A", "B", "C", "D" che si vedono nei quiz) e uno sfondo, che nell'esempio è un cerchio con gli stessi colori del logo usato nel filmato.
Il testo dovrà essere di tipo single line e non essere selezionabile.
Non posizioniamo istanze di questa clip sullo stage, ma ne manteniamo solo una copia nella libreria.
Creazione della clip timer
Per quanto riguarda la creazione della clip timer, realizzeremo semplicemente un movieclip con un'animazione della durata di circa 3 secondi (ovvero il tempo che daremo all'utente per rispondere); anche in questo caso creiamo una nuova clip e ne impostiamo il linkage per Actionscript con identificativo Tempo. L'animazione può essere a piacere, il suo avanzamento verrà regolato tramite Actionscript.
Come ultima operazione impostiamo la Document Class su quiz, quindi salviamo il FLA come quiz.fla.
Impostazione della classe
Una volta predisposto lo stage passiamo al lato Actionscript: praticamente tutti gli aspetti del gioco saranno regolati dalla classe quiz.as; per prima cosa creiamo un nuovo documento Actionscript e salviamolo come quiz.as.
Le prime righe di codice da inserire nella classe sono relative ai package da importare; per il nostro quiz useremo i seguenti package:
- flash.display.*: per l'uso delle icone, del timer e per l'estensione dell'oggetto MovieClip;
- flash.text.*: per la creazione dei campi di testo di domande, risposte e suggerimenti;
- flash.events.*: per gestire il caricamento del file XML delle domande, gli input dell'utente e il timer durante il gioco;
- flash.net.URLLoader e flash.net.URLRequest: per caricare il file XML;
- import flash.utils.Timer: per gestire il timer.
Ecco quindi il codice con cui iniziare la classe:
Listato 1. Importa i package
package {
// importazione dei vari package
import flash.display.*;
import flash.text.*;
import flash.events.*;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.utils.Timer;
public class quiz extends MovieClip { }
}
All'interno del nostro quiz avremo diversi elementi in gioco per ogni domanda, oltre ad alcuni valori "generali" quali ad esempio il punteggio; inoltre, poichè vogliamo creare una struttura utilizzabile in diverse occasioni, sfruttiamo alcuni oggetti TextFormat per variare comodamente l'aspetto dei campi di testo relativi a domande, risposte e suggerimenti.
Di seguito è riportato l'intero elenco delle variabili da dichiarare all'inizio della classe, lo scopo di alcune di esse sarà più facilmente comprensibile nel prosieguo dell'articolo.
Listato 2. Variabili da settare
// oggetto contenente le informazioni ricavate dal file XML
private var sorgenteXML:XML;
// oggetti textformat per la formattazione dei testi
private var frmt_domanda:TextFormat;
private var frmt_risposte:TextFormat;
private var formt_suggerimento:TextFormat;
// riferimenti per i campi di testo
private var txt_messaggio:TextField;
private var txt_domanda:TextField;
// Oggetti generali del gioco
private var sprite_gioco:Sprite;
private var sprite_domanda:Sprite;
private var sprite_risposte:Sprite;
private var btn_gioco:Button;
private var btn_suggerimento:Button;
private var clip_tempo:Tempo;
// variabili del gioco
private var numero_domanda:int;
private var risposta_corretta:String;
private var domande_passate:int;
private var risposte_corrette:int;
private var arr_risposte:Array;
private var timer_domanda:Timer;
private var punti_domanda:int;
private var punti:int;
Per facilitare la divisione delle variabili abbiamo usato degli affissi tipo btn
per gli oggetti di tipo Button, clip per i MovieClip, sprite per gli Sprite e così via. Non è chiaramente una pratica obbligatoria, tuttavia, avendo molte variabili da gestire può risultare comodo avere delle regole comuni per le variabili dello stesso tipo.
Una volta importati i package e dichiarate le variabili possiamo passare alla scrittura delle funzioni, tramite le quali gestiremo sia gli eventi svolti automaticamente dal sistema (ad esempio il caricamento e la scelta di ogni domanda) sia quelli conseguenti ad azioni dell'utente.
Impostare l'area di gioco
La prima funzione sarà quiz, che chiamerà a sua volta quella che sarà la funzione principale della nostra classe, ovvero impostaPartita; tale funzione si occuperà di impostare le variabili generali di gioco, di creare gli oggetti TextFormat e di mostrare il messaggio di caricamento delle domande, che sarà visibile fino al completo caricamento del file XML. Ecco il codice delle funzioni:
Listato 3. Quiz e impostapartita
public function quiz(){
impostaPartita()
}
private function impostaPartita():void {
// creiamo lo sprite di gioco
sprite_gioco = new Sprite();
addChild(sprite_gioco);
// impostiamo i TextFormat dei vari testi
frmt_domanda = new TextFormat("Arial",24,0x330000,true,false,false,null,null,"center");
frmt_risposte = new TextFormat("Arial",18,0x330000,true,false,false,null,null,"left");
frmt_suggerimento = new TextFormat("Arial",14,0x330000,true,false,false,null,null,"center");
// creiamo il testo di caricamento domande
txt_messaggio = creaTesto("Caricamento domande in corso...",frmt_domanda,sprite_gioco,0,200,550);
// impostiamo le variabili generali
numero_domanda = 0;
domande_passate = 0;
risposte_corrette = 0;
punti = 0;
// carichiamo le domande dal file XML
caricaDomande();
}
impostaPartita
potrà essere richiamata in seguito per iniziare un nuovo quiz senza dover chiudere e riaprire il filmato.
Per prima cosa viene creato lo sprite di gioco (sprite_gioco
), che conterrà i vari elementi, quindi vengono impostati i vari TextFormat, dopo di che viene creato un campo di testo (xt_messaggio
); per la creazione di quest'ultimi imposteremo una funzione di nome creaTesto che prevederà come parametri il testo da mostrare, il TextFormat da utilizzare, lo sprite dove aggiungere il testo creato, le coordinate x e y a cui posizionare il campo di testo e la sua larghezza.
Listato 4. Crea il testo
public function creaTesto(testo:String, formato:TextFormat, s:Sprite, x,y: Number, width:Number): TextField {
// creiamo il nuovo campo di testo
var campo_testo:TextField = new TextField();
// lo posizioniamo
campo_testo.x = x;
campo_testo.y = y;
// impostiamo la larghezza
campo_testo.width = width;
// settiamo il formato
campo_testo.defaultTextFormat = formato;
// lo rendiamo non selezionabile, multilinea e con il wordWrap
campo_testo.selectable = false;
campo_testo.multiline = true;
campo_testo.wordWrap = true;
// impostiamo l'autoSize del campo di testo in base al suo allineamento
if (formato.align == "left") {
campo_testo.autoSize = TextFieldAutoSize.LEFT;
} else {
campo_testo.autoSize = TextFieldAutoSize.CENTER;
}
// scriviamo il testo
campo_testo.text = testo;
// aggiungiamo il campo di testo allo sprite
s.addChild(campo_testo);
// restituiamo come oggetto il campo di testo creato
return campo_testo;
}
Possiamo commentare il richiamo alla funzione caricaDomande
(che non abbiamo ancora dichiarato) e testare il filmato per vedere il risultato. Notiamo come la scritta creata dinamicamente sia visibile nel filmato; in realtà è presente anche il testo relativo al punteggio, ma poichè al momento è ancora vuoto non è visibile sullo stage.
Caricare il set di domande
La scritta di caricamento delle domande sarà una sorta di messaggio di precaricamento: quando il file XML sarà effettivamente stato caricato nel nostro filmato andremo a nascondere questo messaggio e inviteremo l'utente a iniziare la partita.
Analizzeremo in seguito la struttura del file caricato dal nostro quiz; per ora limitiamoci ad impostare la funzione che si occuperà di caricare il file, ovvero caricaDomande
. Questa funzione sfrutterà le classi URLRequest e URLLoader per caricare nel file SWF il contenuto di domande.xml, quindi, a caricamento avvenuto (che intercetteremo grazie all'evento Event.COMPLETE
), richiamerà la funzione domandeCaricate
. Ecco il codice della funzione caricaDomande
:
Listato 5. Funzione caricaDomande
private function caricaDomande():void{
// impostiamo il percorso del file
var url_file:URLRequest = new URLRequest("domande.xml")
// carichiamo il file
var carica_file:URLLoader = new URLLoader(url_file)
// una volta completato il caricamento avviamo la funzione domandeCaricate
carica_file.addEventListener(Event.COMPLETE,domandeCaricate)
}
Scopo di domandeCaricate
sarà, invece, memorizzare le domande dal file XML e informare l'utente che può iniziare a giocare. Per rendere il gioco più longevo utilizzeremo un XML composto da un certo numero di domande e risposte ma, per ogni partita, ne estrarremo solo alcune; in questo modo anche con uno stesso set di domande l'utente potrebbe trovarsi con quiz differenti tra loro; di questo si occuperà la funzione scegliDomande
, che analizzeremo più avanti.
Di seguito è possibile vedere il codice della funzione domandeCaricate
.
Listato 6. Codice della funzione domandeCaricate
private function domandeCaricate(evt:Event):void{
// memorizziamo i dati del file XML
var dati_xml = XML(evt.target.data)
// scegliamo 5 domande tra quelle presenti nel file
sorgenteXML = scegliDomande(dati_xml,5)
// rimuoviamo il messaggio di caricamento
sprite_gioco.removeChild(txt_messaggio)
// creiamo un nuovo messaggio che sostituisca il precedente
txt_messaggio = creaTesto("Premi il pulsante e inizia a giocare!",frmt_domanda,sprite_gioco,0,200,550);
// abilitiamo il pulsante "gioca"
gioca.addEventListener(MouseEvent.CLICK,avviaGioco)
}
Scegliere le domande per la partita
Ad ogni esecuzione del gioco verranno scelte 5 domande tra quelle presenti nel file XML; per eseguire la scelta sfrutteremo le possibilità date dallo standard E4X nella lettura dei file XML, argomento su cui è presente un articolo in questo sito.
Prima di vedere come estrarre casualmente le domande, per ogni partita, è però necessario stabilire la struttura da utilizzare nel file XML.
Struttura del file XML
Come abbiamo detto, il nostro quiz prevederà una domanda con 4 alternative e ci sarà per ogni domanda la possibilità di avere un suggerimento; possiamo facilmente intuire che la domanda, le sue risposte e il suggerimento andranno contenute all'interno di uno stesso oggetto, ma separate tra loro. Avremo quindi una struttura del tipo:
- oggetto
- domanda
- risposte
- suggerimento
- fine oggetto
Il file XML conterrà poi più "oggetti", uno per ogni domanda.
Poiché le possibili risposte saranno 4, può essere una buona idea dividere l'oggetto "risposte" in 4 sotto-elementi, uno per ogni alternativa:
- oggetto
- domanda
- risposte
- risposta
- risposta
- risposta
- risposta
- suggerimento
- fine oggetto
Traducendo questa struttura in tag XML, avremmo:
<oggetto>
<domanda>...</domanda>
<risposte>
<risposta>...</risposta>
<risposta>...</risposta>
<risposta>...</risposta>
<risposta>...</risposta>
</risposte>
<suggerimento>...</suggerimento>
</oggetto>
Per comodità identificheremo la risposta corretta in base alla sua posizione nel file XML, quindi la prima risposta presente nel file sarà sempre quella corretta.
Una volta stabilita la struttura per ogni domanda possiamo facilmente creare l'intero file XML: di seguito è riportato il codice del file usato nell'esempio:
Listato 7. Struttura del file XML
<quiz>
<oggetto>
<domanda>In che anno è nato Roberto Baggio?</domanda>
<risposte>
<risposta>1967</risposta>
<risposta>1971</risposta>
<risposta>1963</risposta>
<risposta>1969</risposta>
</risposte>
<suggerimento>Ha più di 40 anni</suggerimento>
</oggetto>
<oggetto>
<domanda>In che giorno fu ucciso Giulio Cesare?</domanda>
<risposte>
<risposta>15 Marzo</risposta>
<risposta>18 Febbraio</risposta>
<risposta>3 Aprile</risposta>
<risposta>5 Maggio</risposta>
</risposte>
<suggerimento>Le famose Idi di....</suggerimento>
</oggetto>
..//
<oggetto>
<domanda>Quale tag HTML apre una lista puntata ?</domanda>
<risposte>
<risposta><ul></risposta>
<risposta><li></risposta>
<risposta><p></risposta>
<risposta><list></risposta>
</risposte>
<suggerimento><li> viene usato per gli elementi della lista</suggerimento>
</oggetto>
</quiz>
Ora che abbiamo visto la struttura del file possiamo proseguire, analizzando le funzioni che andranno a interagire con i dati caricati da questo file (che nell'esempio si chiama domande.xml)
La funzione scegliDomande
Analizziamo ora la funzione scegliDomande
, che con i commenti e dopo aver visto la struttura del file dovrebbe risultare facilmente comprensibile:
Listato 8. Sceglie la domanda
private function scegliDomande(sorgente:XML,quante:int):XML{
// creiamo l'oggetto XML che conterrà le domande scelte
var domande_scelte:XML = <quiz></quiz>;
// finché non abbiamo abbastanza domande, eseguiamo il ciclo
while(domande_scelte.child("*").length() < quante) {
// scegliamo una domanda casuale e la copiamo nel nostro XML
var casuale:int = Math.floor(Math.random()*sorgente.child("*").length());
domande_scelte.appendChild(sorgente.oggetto[casuale].copy());
// rimuoviamo la domanda scelta dall'XML sorgente, per evitare doppioni
delete sorgente.oggetto[casuale];
}
// restituiamo l'oggetto XML popolato con le domande scelte
return domande_scelte;
}
Per prima cosa creiamo un nuovo oggetto XML, domande_scelte
: al suo interno inseriremo solamente le domande estrapolate dal file XML completo (che viene passato con il parametro sorgente alla funzione). Tramite un ciclo while
facciamo sì che finché le domande sono minori di quelle necessarie venga estratta una domanda casuale; otteniamo tale estrazione andando a generare un numero casuale compreso tra zero a il numero di domande presenti in sorgente: ad ogni estrazione la domanda selezionata viene prima copiata da sorgente a domande_scelte
, quindi viene rimossa per evitare la presenza di doppioni.
Una volta che il numero di domande estratte sarà pari a quello richiesto, l'oggetto domande_scelte
verrà restituito dalla funzione e quindi nel nostro caso associato alla variabile sorgenteXML.
Avviare il gioco
Quando l'oggetto contenente le domande è pronto, possiamo far partire il gioco vero e proprio, mostrando la prima domanda al giocatore.
Di questo si occuperà la funzione avviaGioco
, che abbiamo precedentemente associato alla pressione del pulsante gioca e che andrà a rimuovere dallo stage sia il tasto gioca che il messaggio di avvio partita (txt_messaggio
), quindi richiamerà una ulteriore funzione (poniDomanda
) che si occuperà di mostrare le varie domande al giocatore e che utilizzeremo quindi per tutto il gioco.
Ecco il codice della funzione avviaGioco:
Listato 9. Avvia il gioco
private function avviaGioco(evt:Event){
// rimuoviamo il bottone "gioca"
removeChild(gioca);
// rimuoviamo il messaggio di avvio partita
sprite_gioco.removeChild(txt_messaggio);
poniDomanda()
}
Mostrare le domande
La funzione poniDomanda
è sicuramente tra le principali del nostro sistema: essa, infatti, si occuperà di creare la domanda e le risposte e di impostare gli eventi, sia quelli relativi all'interazione con l'utente (richiesta di suggerimento o tentativo di dare la risposta) che quelli automatici (gestione del timer per la risposta).
Anche poniDomanda
sarà "supportata" da altre funzioni che assoceremo a determinate operazioni ed eventi, ma possiamo sicuramente considerarla il gestore principale di tutte le domande del nostro quiz.
Per prima cosa la funzione dovrà memorizzare la domanda attuale (il numero della domanda da mostrare è memorizzato nella variabile numero_domanda
), quindi ricavare le risposte alla domanda. La domanda e le risposte verranno mostrate in alcuni sprite che andremo a creare in questa funzione.
Listato 10. Prima parte della funzione poniDomanda
private function poniDomanda():void{
// creiamo un nuovo sprite dove mostrare la domanda
sprite_domanda = new Sprite();
sprite_gioco.addChild(sprite_domanda);
// creiamo il campo di testo contenente la domanda
var domanda_attuale:String = sorgenteXML.oggetto[numero_domanda].domanda;
txt_domanda = creaTesto(domanda_attuale,frmt_domanda,sprite_domanda,0,100,550);
// creiamo uno sprite per le risposte, memorizziamo quella corretta a parte
sprite_risposte = new Sprite();
risposta_corretta = sorgenteXML.oggetto[numero_domanda].risposte.risposta[0];
// memorizziamo tutte le risposte alla domanda
arr_risposte = new Array(sorgenteXML.oggetto[numero_domanda].risposte.risposta[0],sorgenteXML.oggetto[numero_domanda].risposte.risposta[1],sorgenteXML.oggetto[numero_domanda].risposte.risposta[2],sorgenteXML.oggetto[numero_domanda].risposte.risposta[3]);
Notiamo l'utilizzo della struttura del file XML per ricavare la domanda (sorgenteXML.oggetto[numero_domanda].domanda;)
) e le risposte (sorgenteXML.oggetto[numero_domanda].risposte.risposta[x]
, dove x è il numero della risposta, nel nostro esempio da 0 a 3).
Una volta ricavata la domanda e le risposte (memorizzando a parte quella corretta) possiamo creare i vari campi di testo e le icone, andandoli a disporre sullo stage e possiamo impostare i punti a disposizione per la domanda:
Listato 11. seconda parte della funzione
// creiamo gli sprite per le risposte
var posX = 20
var posY = 200
for(var i:int=0;i<arr_risposte.length;i++) {
// memorizziamo il testo della risposta corrente
var risposta:String = arr_risposte[i];
// creiamo uno sprite per la risposta
var sprite_risposta:Sprite = new Sprite();
// prepariamo la lettera (A, B, C o D) per l'icona
var lettera_risposta:String = String.fromCharCode(65+i);
// scriviamo il testo della risposta
var txt_risposta:TextField = creaTesto(risposta,frmt_risposte,sprite_risposta,60,10,450);
// creiamo l'icona
var icona:Icona = new Icona();
icona.lettera.text = lettera_risposta;
// posizioniamo lo sprite della risposta
sprite_risposta.x = posX;
sprite_risposta.y = posY;
posX += 230
if(i == 1){
posX = 20
posY += 80
}
// aggiungiamo l'icona nello sprite della risposta
sprite_risposta.addChild(icona);
// rendiamo lo sprite cliccabile come bottone
sprite_risposta.addEventListener(MouseEvent.CLICK,rispostaCliccata);
sprite_risposta.buttonMode = true;
// aggiungiamo lo sprite della riposta allo sprite "sprite_risposte"
sprite_risposte.addChild(sprite_risposta);
}
// aggiungiamo lo sprite delle risposte nello sprite "sprite_domanda"
sprite_domanda.addChild(sprite_risposte);
// impostiamo i punti a disposizione per la domanda
punti_domanda = 100;
Per ogni risposta dell'array arr_risposte
andiamo a creare uno sprite (sprite_risposta
) che conterrà a sua volta l'icona e il testo; tutti gli sprite delle singole risposte saranno inseriti dentro sprite_risposte
che sarà a sua volta posizionato all'interno di sprite_domanda
.
Ogni icona delle risposte viene resa cliccabile e quando cliccata richiamerà la funzione rispostaCliccata
.
Qualora volessimo testare il filmato potremmo commentare la riga sprite_risposta.addEventListener(MouseEvent.CLICK,rispostaCliccata);
(dato che non abbiamo ancora dichiarato la funzione Flash ci restituirebbe un errore), quindi premere Ctrl+Invio.
Il codice per mostrare domanda e risposte è completo, ma noi vogliamo inserire nel nostro quiz anche un timer e la possibilità per il giocatore di ricevere un suggerimento: andremo quindi ad aggiungere sullo stage un'istanza della clip Tempo che abbiamo creato nel nostro file FLA, inoltre aggiungeremo dinamicamente anche un pulsante per richiedere il suggerimento.
Listato 12. Aggiunge tempo e suggerimento
// creiamo l'istanza della clip Tempo
clip_tempo = new Tempo();
// lo fermiamo al primo fotogramma
clip_tempo.stop()
clip_tempo.x = 100;
clip_tempo.y = 380;
// lo aggiungiamo a sprite_domanda
sprite_domanda.addChild(clip_tempo);
// creiamo il timer
timer_domanda = new Timer(500,20);
// a ogni ripetizione del timer chiamiamo la funzione aggiornaTimer
timer_domanda.addEventListener(TimerEvent.TIMER,aggiornaTimer);
// avviamo il timer
timer_domanda.start();
// creiamo il bottone per il suggerimento
btn_suggerimento = new Button();
// ne impostiamo la label su "Aiuto"
btn_suggerimento.label = "Aiuto";
// lo posizioniamo
btn_suggerimento.x = 220;
btn_suggerimento.y = 350;
// e lo inseriamo nello sprite di gioco
sprite_gioco.addChild(btn_suggerimento);
// quando clicato, richiamerà la funzione mostraSuggerimento
btn_suggerimento.addEventListener(MouseEvent.CLICK,mostraSuggerimento);
Il timer andrà a richiamare la funzione aggiornaTimer
, che si occuperà di mandare la clip al fotogramma desiderato (così da mostrare all'utente il tempo residuo per rispondere): poiché il nostro clip è composto da 20 fotogrammi e vogliamo dare 10 secondi di tempo per rispondere facciamo sì che il timer venga richiamato 20 volte, una ogni mezzo secondo (500 millisecondi). Una volta scaduto il tempo informeremo l'utente e mostreremo un pulsante per passare alla domanda seguente (di questo si occuperà la funzione fineDomanda
, che analizzeremo a breve).
Listato 13. Aggiorna il timer
private function aggiornaTimer(evt:Event):void{
// mandiamo la clip al fotogramma corrispondente al numero di ripetizioni del timer
clip_tempo.gotoAndStop(evt.target.currentCount)
// se il tempo è scaduto
if (evt.target.currentCount == evt.target.repeatCount) {
// avvisiamo l'utente
txt_messaggio = creaTesto("Tempo scaduto!",frmt_domanda,sprite_gioco,0,180,550);
// e consideriamo conclusa la domanda
fineDomanda();
}
}
Per quanto riguarda la funzione mostraSuggerimento
, questa semplicemente si occuperà di ricavare la frase di aiuto dal file XML e la mostrerà al giocatore, dando però una "penalità" eliminando 30 punti da quelli a disposizione per la domanda. Il pulsante per il suggerimento verrà rimosso e sarà sostituito dalla frase di aiuto. Ecco il codice:
Listato 14. Mostra il suggerimento
private function mostraSuggerimento(evt:Event):void{
// eliminiamo il bottone di aiuto
sprite_gioco.removeChild(btn_suggerimento);
btn_suggerimento = null;
// diminuiamo i punti in palio
punti_domanda -= 30;
// ricaviamo il suggerimento
var testo_suggerimento:String = sorgenteXML.oggetto[numero_domanda].suggerimento;
// e lo mostriamo al giocatore
var txt_suggerimento:TextField = creaTesto(testo_suggerimento,frmt_suggerimento,sprite_domanda,0,340,550);
}
Analizzare la risposta dell'utente
Quando l'utente clicca su una delle risposte dobbiamo confrontare l'alternativa da lui scelta con la risposta corretta (memorizzata, ricordiamo, nella variabile risposta_corretta
). In caso di risposta esatta andremo a incrementare il punteggio e ci complimenteremo con il giocatore, altrimenti lo informeremo che la sua risposta è sbagliata. In entrambi i casi considereremo conclusa la domanda, richiamando la funzione fineDomanda
.
Listato 15. Restitusce un feedback all'utente
public function rispostaCliccata(evt:MouseEvent):void {
// ricaviamo la risposta scelta
var risposta_scelta = evt.currentTarget.getChildAt(0).text;
// se la risposta è corretta
if (risposta_scelta == risposta_corretta) {
// aumentiamo le risposte esatte
risposte_corrette++;
// informiamo l'utente
txt_messaggio = creaTesto("Risposta esatta!",frmt_domanda,sprite_gioco,0,180,550);
// aumentiamo i punti
punti += punti_domanda;
}else{ // se la risposta è errata
// informiamo l'utente
txt_messaggio = creaTesto("Risposta errata :(",frmt_domanda,sprite_gioco,0,180,550);
}
// consideriamo conclusa la domanda
fineDomanda();
}
Vediamo allora il codice della funzione fineDomanda
, che viene richiamata anche in caso di tempo scaduto. Questa funzione si occuperà molto semplicemente di rimuovere gli elementi visivi relativi alla domanda appena conclusa e di mostrare un pulsante che permetta all'utente di passare alla domanda successiva. Ecco il codice:
Listato 16. Termina la domanda
private function fineDomanda():void{
// per ogni risposta...
for(var i:int=0;i<4;i++) {
// eliminiamo il listener relativo al click
sprite_risposte.getChildAt(i).removeEventListener(MouseEvent.CLICK,rispostaCliccata);
// rendiamo invisibile lo sprite
sprite_risposte.getChildAt(i).visible = false;
}
// se presente, rimuoviamo il pulsante di suggerimento
if (btn_suggerimento != null) {
sprite_gioco.removeChild(btn_suggerimento);
}
// fermiamo il timer
timer_domanda.stop();
// impostiamo il numero di domanda
numero_domanda++;
// impostiamo il numero di domande a cui si è risposto
domande_passate++;
// creiamo il bottone per proseguire
var btn_continua = new Button()
btn_continua.label = "Prosegui"
btn_continua.x = 220
btn_continua.y = 250
sprite_gioco.addChild(btn_continua)
btn_continua.addEventListener(MouseEvent.CLICK,prossimaDomanda)
}
Passare alla domanda successiva
Notiamo per il pulsante btn_continua
il richiamo alla funzione prossimaDomanda
: questa è una funzione molto importante in quanto controllerà il numero di domande a cui si è già risposto e controllerà quindi se si è risposto all'ultima domanda: in questo caso manderà la timeline al fotogramma di fine gioco e mosterà i punti ottenuti dal giocatore.
Listato 17. Passa alla domanda successiva
private function prossimaDomanda(evt:MouseEvent):void{
// rimuoviamo la domanda
sprite_gioco.removeChild(sprite_domanda)
// rimuoviail il bottone "continua"
sprite_gioco.removeChild(evt.target as DisplayObject)
// rimuoviamo il testo informativo
sprite_gioco.removeChild(txt_messaggio)
// se abbiamo esaurito le domande
if(numero_domanda > 4){
// il gioco è finito
fineGioco()
}else{
// facciamo la prossima domanda
poniDomanda()
}
}
Fine del gioco: mostrare i punti
Abbiamo impostato il rilevamento della fine del gioco, quindi ora non ci resta che decidere cosa mostrare all'utente una volta conclusa la partita; innanzitutto manderemo la linea temporale al secondo fotogramma, quindi creeremo un campo di testo con il riepilogo dei punti ottenuti e delle risposte esatte. Andremo poi a impostare la funzione per l'avvio di una nuova partita, funzione che useremo tramite la pressione del pulsante rigioca, a cui andremo ad associare l'evento.
Listato 18. Funzione fine gioco
private function fineGioco():void{
gotoAndStop(2)
txt_messaggio = creaTesto("Hai ottenuto " + punti + " punti rispondendo correttamente a " + risposte_corrette + " domande", frmt_domanda, sprite_gioco, 0, 180, 550)
}