Inform e Glulx/Inform e ancora Inform/Gli NPC (o PNG in italiano)

Wikibooks, manuali e libri di testo liberi.
Indice del libro

Gli NPC (o PNG in italiano)[modifica]

Sostanzialmente, i Non Player Characters o Personaggi Non Giocatori (da qui in poi PNG) altro non sono che tutti quei personaggi inclusi nel gioco all’infuori del giocatore stesso (il sacerdote mummificato in Ruins, tanto per fare un esempio, è uno di questi). Osserviamo ora il funzionamento del seguente esempio:

La signora Bindi
di Vincenzo Scarpa e Paolo Lucchesi
Avventura d'esempio per gestire un NPC.

Versione 1 -- Numero di serie 051016
Inform v6.30 -- Libreria 6/11  --  Infit v2.5    S

Corridoio
Sei in un lungo corridoio che prosegue verso nord.

>n
Corridoio
Sei in un lungo corridoio. A ovest c'è una porta aperta.

>o

Soggiorno
Questa è una stanza molto grande. Alla tua sinistra, una finestra dà sulla strada e davanti a te puoi vedere un grosso tavolo in noce circondato ai lati da quattro sedie.

C'è la signora Bindi qui, seduta sul sofà.

Puoi anche vedere un giornale qui.

>esamina la signora Bindi
È molto bella.

>bacia la signora Bindi
Non credi che la signora Bindi sia interessata alle tue attenzioni.

>chiedi alla signora Bindi del giornale
"È il giornale di oggi."

La signora Bindi è il nostro PNG per eccellenza, poiché reagisce ai comandi "sociali" (grazie alla proprietà life che in un oggetto di questo tipo deve essere sempre presente). Ma non è finita:

>z
Il tempo passa.

>z
Il tempo passa.

>z
Il tempo passa.

>z
Il tempo passa.

>z
Il tempo passa.

La signora Bindi si dirige verso est.

>

dopo altri cinque turni, la signora Bindi esce dal soggiorno e si dirige verso est. Proviamo allora a seguirla:

>e

Corridoio

Puoi vedere la signora Bindi qui.

La signora Bindi si dirige verso nord.

>n

Corridoio
Sei in un lungo corridoio. Verso nord puoi vedere una porta aperta che dà sulla cucina.

Puoi vedere la signora Bindi qui.

La signora Bindi si dirige verso nord.

>n

Cucina
Questa è la cucina della signora Bindi, piuttosto stretta ma completa.

La signora Bindi è qui, intenta a fare le pulizie. Non sembra essere molto contenta.

Puoi anche vedere un frigorifero (che è chiuso) e una forchetta qui.

>esamina il frigo
È tutto sporco di sugo di pomodoro.

>chiedi alla signora Bindi del pomodoro
"Dovrei fare più attenzione a quello che faccio. A volte sono così distratta..."

>

In poche parole, dopo dieci turni dall’inizio del gioco la signora Bindi si sposta dal soggiorno in cucina, indipendentemente da quello che il giocatore sta facendo. E questo accade naturalmente anche se quest’ultimo non si trova nel soggiorno:

Soggiorno
Questa è una stanza molto grande. Alla tua sinistra, una finestra dà sulla strada e davanti a te puoi vedere un grosso tavolo in noce circondato ai lati da quattro sedie.

C'è la signora Bindi qui, seduta sul sofà.

Puoi anche vedere un giornale qui.

>prendi il giornale
Preso.

>e

Corridoio

>n

Corridoio
Sei in un lungo corridoio. Verso nord puoi vedere una porta aperta che dà sulla cucina.

>leggi il giornale
Nessuna notizia interessante.

>z
Il tempo passa.

>z
Il tempo passa.

>z
Il tempo passa.

>z
Il tempo passa.

>z
Il tempo passa.

La signora Bindi arriva qui.

>parla alla signora Bindi del giornale
"È il giornale di oggi."

La signora Bindi si dirige verso nord.

>

Interessante, vero? Ma non è ancora finita. Guardate cosa accade se ci troviamo in cucina quando la signora Bindi arriva:

Cucina
Questa è la cucina della signora Bindi, piuttosto stretta ma completa.

Puoi vedere un frigorifero (che è chiuso) e una forchetta qui.

>esamina il frigorifero
Sembra essere piuttosto robusto.

>apri il frigorifero
Ora hai aperto il frigorifero.

>g

Cucina
Questa è la cucina della signora Bindi, piuttosto stretta ma completa.

Puoi vedere un frigorifero (che è vuoto) e una forchetta qui.

>esamina la forchetta
Una normale forchetta.

>prendi la forchetta
Presa.

>i
Stai portando:
  una forchetta

>z
Il tempo passa.

>z
Il tempo passa.

>z
Il tempo passa.

La signora Bindi arriva qui.

La signora Bindi chiude il frigorifero sporcandolo con le mani imbrattate di sugo di pomodoro.

>g

Cucina
Questa è la cucina della signora Bindi, piuttosto stretta ma completa.

La signora Bindi è qui, intenta a fare le pulizie. Non sembra essere molto contenta.

Puoi anche vedere un frigorifero (che è chiuso) qui.

>esamina il frigorifero
È tutto sporco di sugo di pomodoro.

>

Prima del suo arrivo, il frigorifero in questione è pulito e chiuso. Noi lo apriamo, e quando lei arriva in cucina, lo chiude e lo sporca. Un PNG può quindi modificare anche lo stato di uno o più oggetti che non devono, tra l’altro, trovarsi necessariamente nella stanza in cui esso si trova (grazie all’istruzione objectloop spiegata nel paragrafo 4.10). Senza contare che, tramite l’istruzione move, può addirittura prenderli e spostarli (si potrebbe, per assurdo, far sì che al suo arrivo in cucina, la signora Bindi prendesse - se presente - la forchetta e la mettesse nel frigorifero). A ogni modo, al ventiduesimo turno il nostro PNG esce dalla cucina ritornando nuovamente al soggiorno:

Cucina
Questa è la cucina della signora Bindi, piuttosto stretta ma completa.

La signora Bindi è qui, intenta a fare le pulizie. Non sembra essere molto contenta.

Puoi anche vedere un frigorifero (che è chiuso) e una forchetta qui.

La signora Bindi si dirige verso sud.

>esamina il frigorifero
Sembra essere piuttosto robusto.

>s

Corridoio

>s

Corridoio

>o

Soggiorno
Questa è una stanza molto grande. Alla tua sinistra, una finestra dà sulla strada e davanti a te puoi vedere un grosso tavolo in noce circondato ai lati da quattro sedie.

La signora Bindi è qui, intenta a guardare la televisione.

Puoi anche vedere un giornale qui.

>chiedi alla signora Bindi del frigorifero
È di nuovo pulito ora.

>

Il frigorifero adesso è di nuovo pulito e sono tutti felici e contenti[1].

Diamo ora un’occhiata al codice (molto meno difficile di quello che a prima vista potrebbe forse sembrare):

[ Initialise;
    location = Corridoio_sud;
    move Bindi to Soggiorno;
    Startdaemon (Timerdaemon); 
];

All’inizio, diamo la locazione di partenza del gioco, la posizione iniziale del nostro PNG e facciamo partire il daemon Timerdaemon:

Object Timerdaemon
    with tm 0,
         daemon [;   
           switch (++self.tm) {
              10: Bindi.path = 1; Startdaemon(Bindi);
              22: Bindi.path = 2; Startdaemon(Bindi);
              38: StopDaemon(self); deadflag = 3; 
           }
        ];

quest’ultimo, conta i turni ed esegue certe azioni in turni ben precisi. In particolare, al decimo turno attiva il daemon della signora Bindi sul primo percorso (alla decima mossa cioè del giocatore, la signora Bindi si dirige dal salotto alla cucina), mentre al ventiduesimo turno essa si dirige dalla cucina nuovamente al soggiorno. Al trentottesimo turno, poi, viene fermato il gioco. Per quanto riguarda invece la signora Bindi:

Object Bindi "signora Bindi"
  with name 'signora' 'bindi' 'Bindi', 
       article "la",        
       describe [;
          switch (location) { 
            Soggiorno: if (self.path < 2) "^C'@`e la signora Bindi qui, 
                          seduta sul sof@`a.";
                       "^La signora Bindi @`e qui, intenta a guardare la 
                        televisione.";
            Cucina: "^La signora Bindi @`e qui, intenta a fare le
                     pulizie. Non sembra essere molto contenta.";
          }
       ],
       description "@`E molto bella.",
       life [;
         Attack, ThrowAt: "Non oseresti mai far del male ad una povera 
               signora indifesa.";
         Kiss: "Non credi che la signora Bindi sia interessata alle tue 
               attenzioni.";
         Show: "~@`E ", (a) noun, "~, dice la signora Bindi.";
         Give: "~No, grazie, ", (the) noun, " non mi serve.~";
         Ask, Tell: switch(second) {
                 'forchetta': "~@`E l'unica rimasta di tutto il servito.~";
                 'giornale': "~@`E il giornale di oggi.~";
                 'frigo', 'frigorifero', 'sugo', 'pomodoro': 
                         if ((TimerDaemon.tm >=12) && (self.path < 2))
                            "~Dovrei fare pi@`u attenzione a quello che 
                             faccio. A volte sono cos@`i distratta...~";
                         if (self.path >= 2) "~@`E di nuovo pulito ora.~";
              }
              "~Non ne so niente, mi spiace.~";
       ],
       path 0, 
       daemon [;                
          switch (self.path) {
                   1: switch(parent(self)) {
                      Soggiorno: percorso_npc(self, e_obj); rtrue;
                      Corridoio_nord: percorso_npc(self, n_obj); rtrue;
                      Corridoio_cucina: percorso_npc(self, n_obj);
                   ! se il giocatore è in cucina e il frigorifero è aperto...
                   if ((player in Cucina) && (frigorifero has open)) 
                   print "^La signora Bindi chiude il frigorifero 
                           sporcandolo con le mani imbrattate di sugo di 
                           pomodoro.^";
                   ! se il giocatore è in cucina e il frigorifero è chiuso...
                   if ((player in Cucina) && (frigorifero hasnt open)) 
                   print "^La signora Bindi apre il frigorifero 
                          (sporcandolo con le mani imbrattate di sugo di 
                          pomodoro) e, dopo un attimo di esitazione, lo 
                          richiude .^";
                         give frigorifero ~open; 
                         StopDaemon(self); rtrue;
                      }
                   2: switch(parent(self)) {
                      Cucina: percorso_npc(self, s_obj); rtrue;
                      Corridoio_cucina: percorso_npc(self, s_obj); rtrue;
                      Corridoio_nord: percorso_npc(self, w_obj);
                      StopDaemon(self); rtrue;
                      }
                   }
       ],
  has female animate;

la proprietà describe permette a Inform di stampare a video delle frasi personalizzate a seconda di dove il nostro PNG si trova. La proprietà life, come abbiamo già detto, stabilisce come esso reagisce ai comandi sociali; in particolare, occorre notare le diverse risposte che esso dà quando il giocatore gli chiede delle informazioni inerenti al frigorifero: se, infatti, la signora Bindi non è ancora uscita dalla cucina viene stampato a video il messaggio ""Dovrei fare più attenzione a quello che faccio. A volte sono così distratta..."", mentre se è invece uscita viene stampato a video il messaggio ""È di nuovo pulito ora."". La proprietà daemon gestisce invece il movimento del PNG dove, a seconda del valore della variabile path e della locazione in cui esso si trova, viene chiamata la funzione percorso_npc alla quale occorre passare come parametri l’oggetto stesso (self) e la direzione verso la quale il PNG deve dirigersi. Per quanto riguarda, infine, il frigorifero:

Object -> frigorifero "frigorifero"
  with name 'frigorifero' 'frigo',
       description [;
      ! Se la signora Bindi non è ancora in cucina o se ne è già
      ! andata...
      if ((TimerDaemon.tm < 12) || (Bindi.path >=2)) print "Sembra essere 
           piuttosto robusto.^";
      ! Se la signora Bindi si trova in cucina...
      if ((TimerDaemon.tm >=12) && (Bindi.path < 2)) print "@`E tutto 
           sporco di sugo di pomodoro.^";
       ],
   has static container ~open openable;

quando questo oggetto viene esaminato, Inform stampa a video messaggi diversi a seconda che la signora Bindi si trovi o meno in cucina[2].

Note[modifica]

  1. La creazione di movimenti relativamente sofisticati per i personaggi non giocatori può essere semplificata con l’utilizzo della libreria MoveClass.h. Ulteriori informazioni sul suo utilizzo potete trovarle nel prossimo paragrafo.
  2. Cliccate qui per scaricare il listato di questo esercizio (il file 5.08.inf).