[TUTORIAL] Piccolo tutorial per la gestione degli stati
GESTIONE DEGLI STATI
Olà! Oggi risolverò un problema che ritengo sia molto sentito agli inizi: la gestione degli stati di un programma.
Supponiamo di avere nel nostro gioco tre stati:
- Menu
- Gioco
- Pausa
La prima idea che ci verrebbe sarebbe questa: teniamo una variabile chiamata “stato” e la gestiamo in questo modo: int stato=0;
<programma>
Codice:
switch (stato)
{
case 0: //gioco normale;
break;
case 1: //menu;
break;
case 2://pausa
break;
}
Questo può andare bene per un po’, ma con la crescita della complessità, con possibili intersezioni tra vari casi, e magari anche dei sottostati (ad esempio quando nel menu passiamo il mouse su un tasto, e vogliamo che venga animato) il tutto diverrà decisamente troppo complicato.
Come possiamo fare allora? Pensiamo ad un sistema organizzato in questo modo: abbiamo una pila di stati, e quello che faremo sarà eseguire quello in cima a questa pila.
Quando sarà necessario, metteremo uno stato in cima alla pila, in modo che venga eseguito, e quando questo stato non ci servirà più,
lo toglieremo, così ricomincerà ad essere eseguito quello che ci stava sotto.
Facciamo un esempio:
Supponiamo che il nostro programma debba funzionare così: appena lanciato, lancia il menù. Da questo menù potremo scegliere se giocare od uscire (c'erano dei giochi per console dove c'era solo "gioca" http://forumtgmonline.futuregamer.it...icon_smile.gif).
Una volta nel gioco, premendo ESC sarà possibile tornare al menù, e premendo “I” aprirà la pagina del nostro inventario.
Dall'inventario, premendo ESC si tornerà al gioco.
Vediamo come organizzare questa cosa con il sistema spiegato sopra:
PILA:
MENU -> In esecuzione
Ora, nostro malgrado, qualcuno preme il tasto "Gioca". Accade questo:
PILA:
GIOCO -> In esecuzione
MENU
Notiamo che ora il menù è sotto il gioco, poiché questo è stato inserito in cima. Il gioco, essendo in cima, viene eseguito.
Ora qualche uomo dalla scarsa morale certamente vorrà tornare al menù, premendo ESC:
PILA:
MENU -> In esecuzione
Il gioco è stato eliminato, e siamo nel menù. Questa è una situazione teorica, per mostrare come funzionano gli stati; in realtà il menù dovrebbe essere diverso, per adattarsi al fatto che siamo in gioco.
Ora premendo di nuovo il tasto "Gioco" torniamo al gioco:
PILA:
GIOCO -> In esecuzione
MENU
Di certo ora qualche protervo marrano vorrà vedere l'inventario, premendo I:
PILA:
INVENTARIO -> In esecuzione
GIOCO
MENU
Ora dovremmo iniziare a capire la faccenda. Quando avremo finito con l'inventario, tornerà il gioco perchè è sotto.
Vediamo come fare tutto ciò con una comoda classe C++.
Codice:
class jManagerStati
{
struct stato
{
void (*Funzione)(void *Ptr,long Scopo);
stato *prossimo;
stato()
{
Funzione=NULL;
prossimo=NULL;
}
~stato()
{
delete prossimo;
}
};
protected:
stato *jstackstati;
public:
jManagerStati();
~jManagerStati();
void Push(void (*Funzione)(void *ptr,long Scopo),void *Dataptr);
BOOL Pop(void *Dataptr=NULL);
void PopAll(void *Dataptr=NULL);
BOOL Process(void *Dataptr=NULL);
};
La struttura di questa classe è la tipica di una pila, tranne per il metodo "Process".
Notiamo che la “Pop” non restituisce altro che un BOOL. Questo perché a noi non interessa la funzione, poiché è un dato a noi ben noto e sempre reperibile; l’unica cosa che ci interessa è che venga tolto.
La “j” davanti al nome della classe sta per “July”, il software di cui questa classe fa parte.
Vediamo l’implementazione:
Codice:
jManagerStati::jManagerStati()
{
jstackstati=NULL;
}
jManagerStati::~jManagerStati()
{
PopAll();
}
BOOL jManagerStati::Pop(void *Dataptr)
{
stato *tempptr;
if ((tempptr= jstackstati) !=NULL)
{
jstackstati->Funzione(Dataptr,SCOPOFINE);
jstackstati=tempptr->prossimo;
tempptr->prossimo=NULL;
delete tempptr;
}
if (jstackstati==NULL)
return FALSE;
return TRUE;
}
void jManagerStati::PopAll(void *Dataptr)
{
while (Pop(Dataptr)==TRUE);
}
BOOL jManagerStati::Process(void *Dataptr)
{
if (jstackstati==NULL)
return FALSE;
jstackstati->Funzione(Dataptr,SCOPOFRAME);
return TRUE;
}
void jManagerStati::Push(void (*Funzione)(void *ptr,long Scopo),void *Dataptr)
{
stato *tempptr;
if (Funzione!=NULL)
{
tempptr=new stato;
tempptr->Funzione=Funzione;
tempptr->prossimo=jstackstati;
jstackstati=tempptr;
tempptr->Funzione(Dataptr,SCOPOINIT);
}
}
Noterete che ci sono tre costanti che non ho scritto in questa trattazione, e queste sono:
SCOPOINIZIO
SCOPOFINE
SCOPOFRAME
E rappresentano lo scopo per il quale la funzione viene chiamata.
Notere infatti che le funzioni vengono chiamate passando SCOPOINIT nella Push, SCOPOFINE nella Pop e SCOPOFRAME nella Process.
Starà a voi, nell’implementazione delle vostre funzioni, il compito di controllare il parametro “Scopo” ed agire di conseguenza.
Mi preme dire che l’articolo è ispirato ad un articolo di Jim Adams, che mostrava questa idea per la gestione degli stati[1].
Alla prossima!
Alessandro Monopoli
Biografia:
[1] Programming Role Playing Games with DirectX, J. Adams.
Re: Piccolo tutorial per la gestione degli stati
Bella Dream!
ma non mi stai rispondendo hai quesiti sulle Shadows http://forumtgmonline.futuregamer.it...on_twisted.gif
comunque sia l'idea della pila non è male...io sinceramente non ci ho mai pensato http://forumtgmonline.futuregamer.it...s/icon_lol.gif
...a quando shaders e affini? http://forumtgmonline.futuregamer.it.../icon_cool.gif
Re: Piccolo tutorial per la gestione degli stati
Re: Piccolo tutorial per la gestione degli stati
OT:
non hai ICQ??
magari mi puoi dare il tuo numero via MP!
IT:
ma dai!!su GameProg hai dato poco http://forumtgmonline.futuregamer.it.../icon_razz.gif
Io voglio l'illuminazione per pixel http://forumtgmonline.futuregamer.it.../icon_cool.gif
Re: Piccolo tutorial per la gestione degli stati
Re: Piccolo tutorial per la gestione degli stati
E' l'autore di "RPG programming with DirectX"? a quale articolo ti riferisci?
PS
Mi sono permesso di ritoccare la veste grafica del post http://forumtgmonline.futuregamer.it...icon_smile.gif
Re: Piccolo tutorial per la gestione degli stati
Sì, è l'autore di tale libro, e proprio su quel libro spiega tale tecnica.
Da qualche parte avevo beccato la stessa spiegazione, ma non mi chiedere il sito http://forumtgmonline.futuregamer.it...on_biggrin.gif Parlo di almeno 5 anni fa.
Re: Piccolo tutorial per la gestione degli stati
Quella la trovi nel PDF del mio workshop sugli shaders all WEBB.it dell'anno scorso http://forumtgmonline.futuregamer.it...on_biggrin.gif
Quella però è proprio quella facile facile, magari trovo il tempo di scrivere qualcosa di più interessante.
ciao!
Re: Piccolo tutorial per la gestione degli stati
Re: Piccolo tutorial per la gestione degli stati
L'importante è portare disordine, vero pascal?
Re: Piccolo tutorial per la gestione degli stati
Citazione:
DreamPainter ha scritto ven, 23 aprile 2004 alle 01:41
Quella la trovi nel PDF del mio workshop sugli shaders all WEBB.it dell'anno scorso
http://forumtgmonline.futuregamer.it...on_biggrin.gif
Quella però è proprio quella facile facile, magari trovo il tempo di scrivere qualcosa di più interessante.
ciao!
Non l'avevo vista!Corro subito!
Spero che scriverai su questo forum qualcosa di più interesante http://forumtgmonline.futuregamer.it...on_biggrin.gif
Re: Piccolo tutorial per la gestione degli stati
[uppino anti-apocafud]*
*ho sentito che vanno 'uppati' i topic più importanti per evitare che vangano cancellati durante il cambiamento del forum pervisto per il 12 Settebmre: entro tale data mandatemi un PM per segnalarmi i Topic che volete salvare, motivando il tutto. grazie!
Questo messaggio si autodistruggerà a passaggio efettuato