Diseñando una aventura conversacional - Parte 6

Por Spellcaster

Traducido por DCG

Interaccionando con los objetos

Un objeto resulta del todo inútil a menos que se pueda interactuar con él... Existen tres formas habituales de interactuar con los objetos: Coger, Dejar y Usar. Empecemos con las más fáciles: Coger y Dejar.

Para coger un objeto, todo lo que tiene que hacer el programa es asignar al campo POS del objeto un cero (tras verificar que el objeto exista, que esté en la localidad actual, y que aún no esté en el inventario).

Para dejar un objeto, únicamente es necesario comprobar que se tiene el objeto y poner en el campo POS el número de la localidad donde el jugador está... Programando queda:

        Procedure Coger(O:String);
        Var A:Byte;
            Flag:Boolean;
        Begin
            Flag:=False;
            A:=0;
            Repeat
                Inc(A);
                If O=Objetos[A].Nombre  Then Flag:=True;
            Until (A>NumeroObjs) Or (Flag=True);
            If Flag=True Then
                Begin
                    { El objeto existe }
                    If Objetos[A].Pos=LocalidadActual Then
                    Begin
                        { El objeto está en la localidad actual }
                        { Cogemos el objeto }
                        Objetos[A].Pos:=0;
                        TextColor(LightCyan);
                        WriteLn;
                        WriteLn('Coges el ',O);
                        WriteLn;
                    End
                    Else
                    Begin
                        If Objetos[A].Pos=0 Then
                        Begin
                            { El objeto ya está en posesión }
                            { del jugador...                }
                            TextColor(LightCyan);
                            WriteLn;
                            WriteLn('Ya tienes el ',O);
                            WriteLn;
                         End
                         Else
                         Begin
                             WriteLn('No ves el',O);
                             WriteLn;
                         End;
                     End;   
                 End
                 Else
                 Begin
                     { el objeto no existe }
                     WriteLn;
                     TextColor(LightRed);
                     Writeln('¿ De qué estás hablando ?');
                     Writeln;
                End;
            End;

Como siempre debes poner una llamada a esta rutina en Play... Este comando tiene el mismo problema que examinar, así que debemos hacer lo mismo que hicimos en ese caso: juntar el array parsed en un string que tenga el nombre del objeto:

        If Parsed[1]='COGER' Then
        Begin
            Valid:=True;
            { Juntamos palabras }
            D:=3;
            E:=Parsed[2];
            While Parsed[D]<>'' Do
            Begin
                E:=E+' '+Parsed[D];
                Inc(D);
            End;
            Coger(E);
        End;

La rutina de dejar es parecida, aunque un poco más sencilla:

        Procedure Dejar(O:String);
        Var A:Byte;
            Flag:Boolean;
        Begin
            Flag:=False;
            A:=0;
            Repeat
                Inc(A);
                If (O=Upper(Objetos[A].Nombre)) And
                   (Objetos[A].Pos=0) Then Flag:=True;
            Until (A>NumeroObjs) Or (Flag=True);
            If Flag=True Then
            Begin
                { El jugador tiene el objeto }
                Objetos[A].Pos:=LocalidadActual;
                TextColor(LightCyan);
                WriteLn;
                WriteLn('Dejas el ',O);
                WriteLn;
                End
                Else
                Begin
                    { El objeto no existe o no lo tiene el jugador... }
                    TextColor(LightRed);
                    WriteLn;
                    WriteLn('No tienes el ',O);
                    WriteLn;
                End;
            End;
De nuevo añade el código siguiente a Play... Ya sabes para que sirve:
        If Parsed[1]='DEJAR' Then
        Begin
            Valid:=True;
            { De nuevo juntamos la palabra }
            D:=3;
            E:=Parsed[2];
            While Parsed[D]<>'' Do
            Begin
                E:=E+' '+Parsed[D];
                Inc(D);
            End;
            Dejar(E);
        End;
Ya tenemos Coger y Dejar listos... Ahora, vayamos a la tercera clase de comandos de manipulación de objetos: los comandos de usar. Hay muchos, y tienen en común algo: Manipulan el objeto. Por ejemplo... Puedes usar la Máscara de Gas tecleando USAR MÁSCARA... Pero hagámoslo más complicado, ya que con USAR MÁSCARA también nos podrímos referir a romperla... :))) Es más difícil de esta manera puesto que el jugador conoce lo que ha de hacer... Los comandos de usar no son más que líneas y más líneas de IFs, porque cada objeto tiene efectos diferentes. Algunas órdenes requieren más de un parárametro. Por ejemplo, para usar de la espada debes teclear USAR ESPADA EN MONSTRUO...

En FangLore tendremos dos comandos de este tipo... La orden USAR y la de VESTIR. Vestir será usada para la máscara de gas... El comando usar será para los otros. La teoría es simple... Según el objeto que se elija, debes hacer un bloque de instrucciones que defina lo que ocurra. Por ejemplo, cuando usas la pala en la localidad 20, la puerta a FangLore se abre... Código para la orden VESTIR... Es tan breve y simple que la incluiremos en la rutina Play.

        If Parsed[1]='VESTIR' Then
           Begin
               { Juntamos palabras }
               D:=3;
               E:=Parsed[2];
               While Parsed[D]<>'' Do
               Begin
                   E:=E+' '+Parsed[D];
                   Inc(D);
               End;
               If E='MASCARA GAS' Then
               Begin
                   Valid:=True;
                   { Comprueba que tenga la máscara de gas        }
                   { Sabemos que la máscara es el objeto número 2 }
                   If Objetos[2].Pos=0 Then
                   Begin
                       Mascara:=True;
                       TextColor(LightCyan);
                       WriteLn;
                       WriteLn('Te pones la máscara de gas...');
                       WriteLn;
                   End
                   Else
                   Begin
                       TextColor(LightRed);
                       WriteLn;
                       WriteLn('No tienes la máscara de gas.');
                       WriteLn;
                   End;
               End;
           End;
La variable Mascara es una variable global de tipo Boolean. Debería ser inicializada a False en la rutina Init. Cuando sea verdadera, vendrá a significar que se está usando. Veremos después como puede ser usada...

Ahora veamos la orden USAR... Existen dos posibilidades:

El parser debería eliminar la preposición EN... Házlo en la rutina EliminarArtículos (ver detalles en los primeros artículos del curso).

Implementemos la rutina de USAR:

           Procedure Usar(Arg:TipoParsed);
           Var A:Byte;
               Flag:Boolean;
           Begin
               Flag:=False;
               A:=0;
               Repeat
                   Inc(A);
                   If (Arg[2]=Upper(Objetos[A].Nombre)) And
                      (Objetos[A].Pos=0) Then Flag:=True;
               Until (A>NumeroObjs) Or (Flag=True);
               If Flag=True Then
               Begin
                   { El objeto es 'usable' }
                   Flag:=False;
                   { Miramos si el jugador quiere usar la pala }
                   If Arg[2]='PALA' Then
                   Begin
                       Flag:=True;
                       { Comprobamos si es usada con la puerta }
                       If Arg[3]='PUERTA' Then
                       Begin
                           { Miramos si el jugador está en             }
                           { la localidad apropiada...                 }
                           If LocalidadActual=20 Then
                           Begin
                               { El jugador está en el sition correcto }
                               { Abrimos pasaje entre el jardín        }
                               { y la mansión...                       }
                               Rooms[20].Norte:=15;
                               TextColor(LightCyan);
                               WriteLn;
                               WriteLn('Echas la puerta abajo...');
                               WriteLn;
                           End
                           Else
                               Begin
                                   { El jugador está en algún otro lugar }
                                   TextColor(LightRed);
                                   WriteLn;
                                   WriteLn('No veo ninguna puerta...');
                                   WriteLn;
                              End;
                          End
                          Else
                          Begin
                              { El jugador no usó la pala con la puerta... }
                              TextColor(LightRed);
                              WriteLn;
                              WriteLn('¿ Uso eso con qué ?!');
                              WriteLn;
                          End;
                      End;
                      If Arg[2]='ESPADA' Then
                      Begin
                          Flag:=True;
                          { En un futuro artículo incluiré          }
                          { código, cuando hablemos de monstruos... }
                      End;
                  End;
                  If Flag=False Then
                  Begin
                      { No fueron usados objetos 'legales' }
                      TextColor(LightRed);
                      WriteLn;
                      WriteLn('No puedo usar eso...');
                      WriteLn;
                 End;
           End;
Debemos pasar el array parsed entero como un parámetro a la rutina, porque objetos como la pala y la espada necesitan otros objetos para funcionar... Recuerda que no estás limitado a USAR objetos... Puedes usar, por ejemplo, una palanca... Éste no es un objeto porque no lo puedes llevar contigo, pero lo puedes usar... El código cambiaría ligeramente... En el caso de FangLore únicamente tendremos objetos... :)

Fíjate también que en el caso de USAR, no podemos usar el truco que empleamos con Examinar, Coger, Dejar y Vestir, aquello de juntar el array parsed para formar el nombre de objetos con más de una palabra (MÁSCARA DE GAS)... Así que es bueno usar una única palabra como nombre de objetos, sino un montón de manipulaciones se hacen necesarias... En el caso de FangLore no hay problemas de este tipo, pero en otros podrían haberlos...

Una vez más añade el código siguiente a Play:

        If Parsed[1]='USAR' Then
        Begin
            Valid:=True;
            Usar(Parsed);
        End;
Con esto acabamos el artículo... En el siguiente hablaremos de monstruos y habitaciones especiales... ¡¡ No te lo pierdas !! :))


Nota de Spanish Quest: En los primeros números de 'The Mag' se realizó un cursillo de Pascal la mar de majo. Como comprenderéis no es cuestión de que lo reproduzcamos aquí, después de todo esto es una revista sobre aventuras, y no de programación. A los que no conozcáis Pascal y sepáis inglés os remito directamente a 'The Mag'. A los demás buscaos un buen tutorial en castellano, que seguro que los habrá perdidos en algún rincón de la red o miraros alguno de esos CD-ROMS que regalan las revistas, que puede que venga algún tutorial o cursillo interactivo de Pascal. Si el Pascal no os va, o simplemente conocéis algún otro lenguaje no os será nada complicado el pasarlo.


[Volver]