![]() | ![]() | ![]() | Descripción de objetos y lugares |
Describirle al jugador las cosas y los lugares es mucho más simple que intentar comprender sus intenciones a través de sus órdenes. Pese a todo, el asunto de las descripciones ocupará una buena parte de este capítulo, ya que el diseñador de un juego complejo puede necesitar en algunos casos llegar a conocer cada una de las reglas involucradas. (Mientras que nadie querrá conocer todos los detalles del parser.)
Para empezar, la descripción más simple de un objeto es su "nombre corto". Por ejemplo: DocumentatE|
print (un) candil; |
puede imprimir el texto "un viejo candil". Hay cuatro formas similares para imprimir esto:
![]() | Los originales en Inform eran, respectivamente, print (the) obj, print (The) obj, print (a) obj y print (name) obj. Estas formas originales siguen estando disponibles y puedes usarlas si lo prefieres en lugar de las traducidas. Observarás que (the) y (a) se han traducido directamente a (el) y (un), mientras que en los otros dos casos ha sido necesario introducir un signo _. Esto es debido a que (El) habría sido equivalente a (el), ya que Inform no distingue entre mayúsculas y minúsculas (excepto en el caso particularísimo de (the) y (The). Por otro lado tampoco se puede usar (nombre) como traducción de (name) porque nombre ya es una propiedad de los objetos, por eso debemos poner (_nombre_) y evitar los conflictos. |
Estas formas de imprimir pueden mezclarse con otros textos dentro de un solo print, como por ejemplo:
print_ret "El ogro se niega a comer ", (el) uno, "."; |
EJERCICIO 49 |
(Por Gareth Rees) Al referirte a otros personajes a veces puedes
necesitar escribir un pronombre como "él". Define nuevas rutinas
de imprimir de modo que puedas por ejemplo poner print
"Lanzas el libro contra ", (pronombre) obj; y que salga
apropiadamente él o ella. (Solución) |
![]() |
Usando print (el) obj la librería intentará deducir el
género y número del objeto para lo cual usará las siguientes
propiedades:
Una vez determinado el caso, imprimirá el artículo adecuado ("el", "la", "los" o "las" para el caso definido o bien "un", "una", "unos" o "unas" para el caso indefinido). Existen casos especiales en los que, no obstante, el artículo apropiado no coincide con el género del objeto. Por ejemplo "un águila" tiene articulo masculino, mientras que el objeto es femenino ("un águila blanca"). O habrá otros casos en los que querríamos usar un artículo distinto de todos los anteriores, por ejemplo "tu cepillo de dientes", en vez de "un cepillo de dientes". Para manejar estos casos excepcionales, un objeto puede proporcionar sus propios artículos en la propiedad articulos. Esta propiedad se compone de tres cadenas de caracteres entre comillas. La primera cadena es la que debe usarse con print (_El) obj, la segunda es para print (el) obj y la tercera para print (un) obj. Si quieres que alguna de ellas sea nula (es decir, que el nombre nunca lleve artículo delante) debes darle el valor cero. Por ejemplo:
Observa el cero como tercer artículo para el agua. Esto evita que InformatE genere un inventario como: "Llevas un agua potable.", pero no obstante sí puede usar el artículo definido como en "No observas nada especial en el agua potable." |
Si el objeto tiene el atributo propio, será tratado como un nombre propio y nunca recibirá un artículo delante (ni definido ni indefinido). Por tanto se ignorará la propiedad articulos aunque el objeto la proporcionara. Para casos en los que quieras permitir artículos definidos pero no indefinidos (o viceversa) puedes usar la propiedad articulos con alguno de sus valores a cero.
![]() |
Además de los artículos previos, InformatE proporciona dos funciones
más:
|
![]() |
Además de las rutinas para imprimir el artículo InformatE
proporciona rutinas para hacer concordar los adjetivos en género y
número. Esto es necesario para los mensajes genéricos, por ejemplo
si queremos escribir algo como "El objeto está abierto". Pero este
objeto puede ser una caja o un cajón. Cambiar "El objeto" por "La
caja" o "El cajón" es sencillo, basta poner print (_El)
objeto, pero debería ser "abierta" o "abierto"
respectivamente. Para esto se tienen las siguientes funciones:
|
![]() |
Además de todo lo anterior, InformatE proporciona una serie de
funciones para imprimir el verbo "Coger" de forma sensible al
dialecto (cambiándolo por "Tomar" si el dialecto sudamericano está
activado). El programador del juego deberá tener la precaución de no
usar nunca el verbo "coger" directamente en sus mensajes, sino
llamando a estas funciones para que su juego se "jugable" en
países sudamericanos.
|
![]() ![]() |
|
El nombre corto de un objeto es normalmente el texto que se pone entre comillas dobles en la cabecera de su definición. Es difícil cambiar este durante el juego, aunque podría ser necesario en algunos casos (por ejemplo imagina un "líquido rojo" que se convierte en "líquido azul" más adelante debido a una reacción química). Una forma más flexible de dar el nombre corto de un objeto es a través de su propiedad nombre_corto. Para imprimir en nombre de un objeto InformatE hace lo siguiente:
Por ejemplo, el líquido que mencionabamos antes podría tener una propiedad nombre_corto así:
nombre_corto [;
if (self.color<3) print "líquido ";
switch(self.color) {
1: print "rojo";
2: print "azul";
3: print "mejunje espantoso";
}
rtrue;
],
|
En este ejemplo, según el valor de la propiedad color sea 1, 2, ó 3 el nombre corto impreso será "líquido rojo", "líquido azul", o "mejunje espantoso". Utiliza siempre print y no print_ret o su abreviatura "cadena entre comillas" pues de lo contrario se añadiría un retorno de carro detrás del nombre.
![]() | En español lo normal es que la rutina nombre_corto retorne true para impedir que la librería escriba nada más. En inglés no obstante es habitual usar nombre_corto para que escriba un adjetivo y después retorne false para que la librería escriba detrás el nombre, ya que en inglés los adjetivos van siempre delante del nombre. |
![]() |
También puedes hacer que el objeto tenga la propiedad
nombre_corto igual a "líquido rojo" y después
hacer liquido.nombre_corto="líquido azul" cuando deba
cambiar.
Los lugares también pueden tener una propiedad nombre_corto (el nombre corto de un lugar es el que se muestra en negrita al entrar en él, y el que aparece en la barra de estado). Esto es especialmente útil cuando tienes un objeto único en el programa que representa en términos del juego un montón de habitaciones casi idénticas, pero con diferentes nombres (Por ejemplo "Area 1", "Area 2", etc.. hasta "Area 4000"). |
Lo habitual es que para mencionar un objeto en el inventario la librería use un print (un) obj, lo cual daría lugar a inventarios como este:
> i
Llevas:
una hoja de menta
un extraño libro
tu mochila (que está abierta)
un cubo verde
|
Otros objetos sin embargo, deberían llevar descripciones más complicadas en el inventario. Por ejemplo una botella podría indicar cuánto vino le queda. Para esto se usa la propiedad listarse. La forma más fácil de usar esta propiedad es asignarle una cadena de texto, por ejemplo, un "extraño libro" podría tener:
listarse "ese inofensivo libro antiguo", |
Ese texto sería el que se mostraría en la línea de inventario que menciona a ese libro, en vez de "un extraño libro". Más adelante en el juego podría cambiarse de valor la propiedad, por ejemplo:
libro_raro.listarse="ese letal libro antiguo"; |
![]() | Observación: Esa cadena sustituye a lo que la librería habría impreso por defecto. En particular, si el objeto era un recipiente la librería habría especificado si está abierto y tal vez sus contenidos (si son visibles). En cambio, si tiene la propiedad listarse la librería ya no hará nada de esto. En este caso sería mejor que listarse fuera una rutina, capaz de listar por sí misma los contenidos del objeto. Una rutina también es adecuada para añadir mensajes como "(medio vacío)". |
![]() |
Para mencionar cada uno de los objetos del inventario, la librería lo
hace en dos fases:
Una vez impresa la entrada con las reglas anteriores, la librería añade automáticamente texto para enlazar esta entrada con la siguiente. El texto puede ser un simple retorno de carro, o bien una coma (o la conjunción "y"), dependiendo del "estilo de inventario" activo. |
Por ejemplo, he aquí la rutina listarse de la caja de cerillas del
juego "La juguetería":
listarse
[;
if (etapa_inventario==2)
{
switch(self.cantidad){
0: print " (vacía)";
1: print " (queda una cerilla)";
default: print " (quedan ", (numero) self.cantidad, " cerillas)";
}
}
],
|
EJERCICIO 50 |
Supón que quieres hacer que, en el objeto "caja", su línea de
inventario salga con un texto delante (como "una odiosa caja").
Pero no puedes usar una cadena en la propiedad listarse, ni
tampoco retornar true en la etapa 1, ya que quieres que la etapa 2
ocurra normalmente (para que los
contenidos del objeto sean listados). ¿Cómo lograrías esto?(Solución) |
Los mensajes más largos y complicados que imprime la librería
InformatE por iniciativa propia, son las descripciones de las
localidades, las cuales se imprimen cuando se ejecuta la acción
Mirar (por ejemplo, cuando al ejecutar la instrucción <Mirar>, se
dispara una descripción de localidad). Lo que ocurre entonces es: el
nombre corto de la localidad se imprime en una línea (normalmente en
letra negrita), después se imprime la descripción de la localidad, y
finalmente una lista de los objetos que hay en ella, que no estén
ocultos ni sean escenario.
En el capítulo * se han mencionado ya muchas
propiedades relacionadas con esta descripción: inicial,
si_encendido, si_apagado, etc. que sirve para dar descripciones
del aspecto de un objeto cuando está en la misma localidad que el
jugaador; algunas de estas propiedades son sólo aplicables a puertas,
otras a los objetos conmutables, etc. Todas ellas pueden ser rutinas
para imprimir texto, en lugar de meras cadenas. Las reglas concretas
se dan a después.
Pero todo el mecanismo de la librería que usa esas propiedades, puede
ser eliminado y sustituido por otro usando la propiedad
describir. Si un objeto tiene la propiedad describir (que ha de
ser una rutina), entonces esto tiene prioridad sobre cualquier otra
cosa. La rutina es ejecutada y si retorna true, la librería asume
que el objeto ya se ha descrito y no imprime nada más (en particular,
ignorará las propiedades inicial, si_encencido, etc.) Por ejemplo,
describir [;
"^La pirámide de platino captura la luz de forma hermosa.";
],
|
significa que, incluso si la pirámide ha sido movida (es decir, el jugador la ha cogido y la ha soltado de nuevo), seguirá teniendo una línea propia en las descripciones de la localidad (recordemos que, de lo contrario, el objeto iría a parar a la lista de "También puedes ver:..." que se imprime al final de la descripción de localidad)
![]() |
Fíjate en que hemos puesto un ^ al principio de la cadena. La
librería no imprime un retorno de carro antes de llamar a describir,
porque no sabe aún si esa rutina tiene pensado escribir algo o no. Una
rutina describe que retorna true sin haber escrito nada, hace que
el objeto sea invisible, como si llevara el atributo oculto.
|
![]() ![]() |
La acción Los pasos que sigue InformatE para crear la descripción de la localidad son:
|
![]() |
Después de que la descripción se haya impreso por primera vez, su
atributo visitado se pone a true (esto ocurre durante la fase de
"puntuar llegada"). Consultando ese atributo podemos hacer que una
localidad tenga diferente descripción la primera vez.
|
![]() |
La operación de "listar objetos" (como ocurre en las últimas fases
de la descripcíón), es bastante complicada. Algunos objetos son
descritos en una línea o un párrafo para ellos solos, mientras que
otros son agrupados en una lista común, al final. Otros objetos
(aunque están en la localidad) no son mencionados para nada. En
concreto, no se menciona al jugador, ni lo que el jugador lleve
consigo, ni los objetos con el atributo oculto o escenario. Los
demás objetos son recorridos por la librería (empezando por el más
recientemente introducido en la localidad), que va haciendo lo
siguiente:
|
![]() |
Un objeto con los atributos soporte y escenario, no será
mencionado. Pero sin embargo, cualquier cosa sin el atributo
oculto que esté sobre este soporte sí será mencionado. Si se
quiere evitar esto, el soporte debe ser además oculto.
|
![]() |
Los objetos que acaban de ser empujados a la localidad actual, no son
listados dentro de los contenidos de la habitación en este turno,
aunque aparecerán listados en los turnos siguientes si se efectúa de
nuevo una acción Mirar. Pero esto no se debe a ninguna regla
especial sobre las descripciones de habitación, sino porque el
objeto empujado se mueve a la nueva localidad después de hacer la
descripción de la habitación. Esto está pensado para que, si
el jugador empuja un carro durante una distancia larga, no tenga que
leer "Puedes ver un carro." en cada movimiento, lo que sería para
él un tanto sorprendente.
|
![]() |
La librería usa una rutina llamada Local para crear la descripción
de la localidad. Si lo necesitas, puedes usar esta rutina desde tu
programa con el mismo propósito. Mira la sección sobre rutinas de la
librería, pero basta decir que la acción
por defecto ante Mirar es equivalente a ejecutar:
|
![]() |
|
![]() | ![]() | ![]() | Descripción de objetos y lugares |