Desarrollo de Videojuegos


Juegos de Aventuras
Diseñando una aventura conversacional


Artículo realizado por
Spellcaster.
T
raducción y adaptación de
Daniel Cárdenas.





Capítulo 5.
Creando objetos

¡¡En este capítulo nos meteremos de lleno en el alucinante y esencial mundo de los objetos!! Ninguna aventura conversacional sería realista al 100% sin 100000 objetos, pero para Fanglore seremos más modestos, y tan solo tendremos cuatro... Estos serán:

Puedes incluir otros objetos redundantes, sin propósito alguno, excepto el de confundir, o incluso divertir, al jugador... Pondremos en escena dos de estos objetos:
  • Pistola láser: Accesorio de un juego anterior
  • Una extraña llave: ¡No sirve absolutamente para nada!
Lo primero será, claro está, crear los objetos...

Creando objetos

Para crearlos, podemos utilizar el programa OBJGEN.PAS. Es muy parecido al ROOMGEN.PAS que venía con el SQ 1, excepto que en vez de crear localidades, crea objetos.

Bien, veamos qué es lo que necesitamos guardar para cada objeto: su nombre, su posición (podemos mover objetos de una localidad a otra o llevarlo en el inventario) y su descripción. Explicaré la parte de la descripción más adelante. Definiremos un record como este:



        Type TipoObj=Record

                         Nombre:String[80];

                         Pos:Byte;

                         Desc:Array[1..5] Of String[80];

                     End;

Definamos el número de objetos que habrán en el juego:


        Const NumeroObjs=6;

Y, finalmente, definamos el vector (array) que guardará los objetos:


        Var Objetos:Array[1..NumeroObjs] of TipoObj;

Esto, después de haber definido estas estructuras y haber obtenido el fichero OBJ.DAT (con el OBJGEN), tendremos todos los datos en el mismo, con lo cual sólo habrá que leer estos, con una rutina muy similar a LeerDatosLocalizaciones que ya vimos en nuestra segunda entrega:
        Procedure LeerDatosObjetos;

        { Leemos del disco los datos de los objetos }

        Var F:Text;

            A,B:Byte;

            Flag:Boolean;

        Begin

             { Preparamos el fichero de texto para el acceso }

             Assign(F,'Obj.Dat');

             Reset(F);

             { Para cada objeto del juego }

             For A:=1 To NumeroObjs Do

             Begin

                  { Leemos el nombre del objeto }

                  ReadLn(F,Objetos[A].Nombre);

                  { Leemos la posición inicial }

                  ReadLn(F,Objetos[A].Pos);

                  { Limpiamos la descripción del objeto }

                  For B:=1 To 5 Do Objetos[A].Desc[B]:='';

                  { Leemos la descrición }

                  Flag:=True;

                  B:=1;

                  While Flag Do

                  Begin

                       ReadLn(F,Objetos[A].Desc[B]);

                       If (B=5) Or (Objetos[A].Desc[B]='*') Then Flag:=False;

                       Inc(B);

                  End;

             End;

             Close(F);

        End;

Un apunte más... Si el campo POS de un objeto es 0, significará que estamos llevando el objeto, y si es 255, que el objeto está escondido (en el caso de la máscara de gas, ésta sólo aparece si el horno está abierto).

Contemplando los objetos

Un objeto es inútil, a menos que se pueda usar... Y sólo lo puedes usar si se ve, o si sabes que está allí... Así que hay dos clases de objetos que uno puede ver: objetos que llevas y objetos que ruedan por el escenario... Un buen juego tiene diferentes descripciones para cada una de estas dos clases, pero Fanglore se limita a tratarlos de la misma forma, soltando la descripción.

Bien, has de saber que hay un comando básico que es igual en TODAS las aventuras: ¡EXAMINAR!

Al comando examinar le sigue un parámetro, esto es, acepta (y requiere) que teclees otra cosa... Esta cosa es precisamente lo que deseas examinar... Por ejemplo, si quieres examinar la espada, uno teclearía:

EXAMINAR ESPADA

Examinar sería el comando, y la espada el parámetro. Pero date cuenta que uno no sólo puede examinar objetos, sino que puede examinar cualquier cosa del juego... Por ejemplo, el horno en la nevera... Hablaremos de esto en otro momento, en un próximo artículo de esta serie... Es importante decir que sólo puedes examinar objetos que o bien lleves o que estén en la misma localidad... Veamos como quedaría la rutina de EXAMINAR:

         Procedure Examinar(Param:String);

         Var Flag:Boolean;

             A,B:Byte;

         Begin

              Flag:=True;

              { ***************************************************** }

              { Aquí vendría el código para cosas como el horno, etc. }

              { ***************************************************** }

              { Buscamos el objeto en la lista de objetos }

              A:=0;

              Repeat

                   Inc(A);

                   If Objetos[A].Nombre=Param Then Flag:=True;

              Until Flag Or (A>NumeroObjs);

              If Flag Then

              Begin

                   { El objeto existe }

                   { Comprobamos que esté en localidad o bajo tu poder }

                   If (Objetos[A].Pos=0) Or (Objetos[A].Pos=LocalidadActual) Then

                   Begin

                        { El objeto es 'visible'... Sacamos descripción }

                        Writeln;

                        B:=1;

                        TextColor(Yellow);

                        While (B<6) And (Objetos[A].Desc[B]<>'*') Do

                        Begin

                             Writeln(Objetos[A].Desc[B]);

                             Inc(B);

                        End;

                        Writeln;

                   End

                   Else

                   Begin

                        { El objeto existe, pero no está visible }

                        Writeln;

                        TextColor(Yellow);

                        WriteLn('No veo el ',Param,' por aquí...');

                        WriteLn;

                   End;

              End

              Else

              Begin

                   { El parámetro especificado no representa ningún objeto  }

                   { existente...                                           }

                   WriteLn;

                   TextColor(Yellow);

                   WriteLn('Lo siento, pero no sé qué es un ',Param);

                   WriteLn;

              End;

         End;

Por supuesto tienes que completar la rutina que llama a esta procedure... Debes ponerlo todo (al igual que el resto de comandos) en Play. La rutina quedaría así:
        If Parsed[1]='EXAMINAR' Then

        Begin

                Valid:=True;

                Examinar(Parsed[2]);

        End;

¿Verdad que es fácil...? Pero aún no hemos acabado... Si te acuerdas de lo que dije a propósito del parseo, sabrás que las entradas se dividen en palabras... Pero resulta que la máscara de gas tiene 2 palabras como nombre (Gas Mask)... Tal como lo tenemos ahora el programa es incapaz de detectar los objetos con varias palabras. ¿Cómo podríamos arreglarlo? Bien, hay que volver a unir las palabras otra vez... Observa:
        If Parsed[1]='EXAMINAR' Then

        Begin

                Valid:=True;

                { Juntamos las palabras otra vez }

                D:=3;

                E:=Parsed[2];

                While Parsed[D]<>'' Do

                Begin

                        E:=E+' '+Parsed[D];

                        Inc(D);

                End;

                Examinar(E);

        End;

En cuanto a la definición de tipos, define E como string y D como un Byte. A pesar de que esto funciona con comandos de sólo un parametro, la cosa falla cuando hay comandos que requieren múltiples parametros... La regla es no utilizar objetos con nombres que llevan espacios...

Aún no hemos acabado la sección... Todavía nos queda ver que objetos hay en la localidad, y que objetos llevas... Pero esto lo dejaré para mañana, ya que ayer sólo dormí 2 horas... Y estoy MUY cansado...

Buenas noches... Zzzzzzzzzzzzzzzzzzzzzzzz..........

Ok... ¡He vuelto! :) Preparado para continuar... Ya... Nuestro problema es saber los objetos con los que podemos interactuar. Es fácil. Cuando entremos en una localidad, haremos que el programa saque una lista de los objetos visibles. Para conseguirlo, añadimos el siguiente código a la rutina de Mirar:

        TextColor(LightCyan);

        Writeln('Objetos visibles:');

        Flag:=False;

        For A:=1 To NumeroObjs Do If Objetos[A].Pos=NumeroLoc Then

        Begin

                Writeln('         ',Objects[A].Nombre);

                Flag:=True;

        End;

        If Flag=False Then Writeln('          Nada');

No olvides definir la variable Flag como un Boolean. Se usa para saber si hay algún objeto en la habitación... Si al salir del bucle For fuera falso, significará que no hay objetos en la localidad, y el programa notificará que no hay ningún objeto...

Para saber qué objetos estás llevando, usamos el segundo comando más conocido en las aventuras solo-texto... ¡El comando de INVENTARIO! Para implementarlo, sólo hace falta chequear todos los objetos del juego. Si su localización (campo POS) es cero, entonces es que lo estás llevando... Codificando:

        Procedure Inventario;

        Var A:Byte;

            Flag:Boolean;

        Begin

                Flag:=False;

                TextColor(LightBlue);

                WriteLn;

                WriteLn('Inventario:');

                For A:=1 To NumeroObjs Do If Objetos[A].Pos=0 Then

                Begin

                        WriteLn('                ',Objetos[A].Nombre);

                        Flag:=True;

                End;

                If Flag=False Then Writeln('                 Nada');

                WriteLn;

        End;

Como ya es habitual, debes añadir unas líneas a la rutina Play, para que llame a esta última:
>        If Parsed[1]='INVENTARIO' Then

        Begin

                Valid:=True;

                Inventario;

        End;

Ahora ya podemos mirar los objetos... Pero nos queda la interacción, que dejaremos para el siguiente capítulo...

Nota del traductor: 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 algun tutorial o cursillo interactivo de Pascal. Si el Pascal no os va, o simplemente conocéis algún otro lenguaje (BASIC, no gracias) no os será nada complicado el pasarlo.

ÚLTIMA REVISIÓN EN FEBRERO DE 1999




DESARROLLO DE VIDEOJUEGOS
a
MACEDONIA Magazine