![]() | ![]() | ![]() | Iniciar, mover, cambiar y matar al jugador |
La única cosa realmente obligatoria que debe hacer la rutina Inicializar es poner en localizacion el lugar en que debe comenzar el juego. Éste lugar normalmente es una habitación (y puede estar a oscuras) pero también podría ser un objeto dentro de una habitación, como una silla o una cama. Si quieres que el jugador comience con algunos objetos en su inventario, debes moverlos también en la rutina Inicializar.
Los juegos que comiencen mostrando gran cantidad de texto (a modo de presentación o "introducción") harían bien en ofrecer al jugador la posibilidad de recuperar una partida guardada antes de empezar con la introducción (para que este pueda saltársela si ya la había visto). Pueden hacerlo si ponen lo siguiente en la rutina Inicializar:
print "¿Quieres recuperar un juego previo? >"; if (SiONo()) <Restaurar>; |
Si quieres que la línea de estado no sea visible durante la fase de introducción, mira la sección sobre el lenguaje ensamblador. La rutina Inicializar normalmente retornará 0 ó 1, y la librería ignora este valor. Pero si retorna 2, entonces la librería no imprimirá el "anuncio" del juego (esto es, el título, autor y copyright). Esto puede ser útil para juegos que no muestran el "anuncio" hasta más adelante en el juego (puedes mostrarlo cuando quieras llamando a la función Anuncio).
Veamos, por ejemplo, la rutina Inicializar del juego Ruinas:
[ Inicializar;
Portada();
localizacion=Bosque;
move racion_de_comida to jugador;
move lampara to jugador;
move diccionario to jugador;
laoscuridad.descripcion = "La oscuridad de los siglos pesa sobre ti,
y la sientes claustrofóbica";
"^^^^^Tras días de búsqueda, de sed, de penoso avance a través
de la maleza del bosque, al fin tu paciencia se ve recompensada.
¡Has descubierto algo!^";
];
|
La función Portada será programada más adelante como otra parte del juego. Ruinas es un juego demasiado corto como para merecer una portada, pero no importa. La variable localizacion necesita un poco más de explicación. Normalmente contiene la habitación en la que se halla el jugador (si hay luz bastante para verla), o el valor especial laoscuridad (si no hay luz). En este último caso, pero sólo en este caso, la variable localizacion_real contiene el verdadero lugar en el que se halla el jugador, por si necesitaras conocerlo. Ni localizacion ni localizacion_real tienen que coincidir necesariamente con el objeto padre del jugador (aunque suele ser así). Por ejemplo, si el jugador está en un jeep dentro de un garaje a oscuras, localizacion valdría laoscuridad, localizacion_real sería el Garaje, y en cambio parent(jugador) sería el jeep.
Debido a estas complejidades, el programador no debe intentar mover el jugador "a mano" (mediante algo como move jugador to habitacion). Si es necesario teletransportar "mágicamente" al jugador a otro lugar, deberá usarse la función JugadorA(lugar) (esta función se ocupa también de imprimir la descripción del lugar automáticamente, si hay luz suficiente para ver). También puede usarse JugadorA para mover al jugador a un objeto dentro de una habitación (un vehículo o un recipiente, por ejemplo).
![]() |
Si usamos la forma JugadorA(lugar,1), el jugador será
teleportado a ese lugar, pero no se imprimirá la descripción del
nuevo lugar.
Si usamos la forma JugadorA(lugar,2) la descripción que se mostrará tendrá en cuenta si el jugador ya ha estado allí, para mostrar una descripción más breve (sólo el título) si ya había estado (lo mismo que cuando entra caminando a un lugar). Durante el proceso que llamaremos "puntuar la llegada" la librería comprueba si la habitación en la que acaba de entrar el jugador es visitada por primera vez. De ser así, le activará el atributo visitado y si la habitación tiene el atributo valepuntos aumentará convenientemente la puntuación del jugador. Cuando tiene lugar la acción Mirar, o bien cuando ha sido llamada la función JugadorA(lugar,1), la librería, además de "puntuar la llegada", realizará lo que llamaremos "anotar la llegada". Esto consiste en comprobar si la variable localizacion ha cambiado desde la última vez (es decir, el jugador se ha movido a otra habitación, o bien se ha quedado a oscuras si no lo estaba, o bien ha obtenido luz si estaba a oscuras). Si se encuentra que localizacion ha cambiado, se llevarán a cabo las siguientes acciones:
|
El comportamiento del jugador puede cambiarse fácilmente, ya que el objeto jugador puede tener una rutina ordenes como cualquier otro personaje del juego. Para cambiar la rutina ordenes del jugador basta hacer algo como:
jugador.ordenes=MiReglaNueva; |
donde MiReglaNueva será una nueva rutina ordenes. Observar que esta nueva regla se aplicará a cualquier acción que intente el jugador, y también a todos los comandos que el jugador de a otros personajes. La variable actor contendrá el personaje que está recibiendo la orden (normalmente será el propio jugador) y las variables accion, uno y otro se inicializan en la forma usual. Por ejemplo, si un cañón se dispara cerca del jugador podría ocasionarle una sordera momentánea (el verbo "escucha" dejaría de funcionar), lo cual puede lograrse con una rutina como esta:
[ MiReglaNueva; if (actor~=jugador) rfalse; Escuchar: "No oyes muy bien todavía debido a ese cañonazo."; ]; |
El if que hay al principio garantiza que el sordo es el jugador, y no otro personaje, de modo que un comando como "Helena, escucha", aún seguirá funcionando.
EJERCICIO 42 |
Podría haberse logrado un efecto parecido usando la rutina
reaccionar_antes del jugador, pero hay ocasiones en las
que esta rutina no sería lo mejor. ¿Puedes imaginar en cuáles? (Solución) |
EJERCICIO 43 |
Escribir otra MiReglaNueva que impida al jugador hablar
mientras lleva puesta una máscara de gas (por tanto también le
impedirá dar órdenes a otros personajes). Este efecto aparece en el
juego "Curses" (Solución) |
![]() |
De hecho se puede hacer un truco mucho más potente: el jugador puede
convertirse en otro personaje diferente durante el juego,
permitiendo al jugador "auténtico" (el de carne y hueso que está
ante el teclado) actuar a través de otro personaje (piensa en juegos
multi-personaje como Maniac Mansion). Llamando a la rutina
CambiarJugador(objeto) el jugador será transformado en
objeto. No es necesario darle al objeto nombres como 'yo'
o 'mi' en la propiedad nombres (el parser entiende 'mi' y
'me' como formas de referirse al jugador actual, sea este el objeto
que sea). Sin embargo tiene que tener una propiedad llamada
numero, no importa qué valor se le de (la librería usa esta
propiedad para sus cálculos). También se le puede dar la propiedad
capacidad (para indicar el máximo número de objetos que
puede transportar).
CambiarJugador no imprime nada especial, así que probablemente debas poner detrás un comando <<Mirar>>. CambiarJugador tiene muchas aplicaciones posibles. El jugador que ande trasteando con la máquina de transmitir mentes del doctor Frankenstein puede encontrarse súbitamente convertido en el monstruo atado a la mesa. Un jugador que ha bebido demasiado vino puede ser convertido en un objeto jugador_borracho, al que se apliquen diferentes reglas. El jugador puede ser transformado en animal mediante algún conjuro (como en el juego "Spellbreaker"). Más ambicioso: un juego puede tener un almacén de doce o más personajes principales y el foco puede ir cambiando de uno a otro. Por ejemplo el jugador podría tener un equipo de exploradores para recorrer un laberinto y tecleando el nombre de cada miembro puede cambiar el foco entre ellos. En este caso puede ser necesario que la función MasAlla cambie el foco a un miembro vivo de la expedición cuando muere el que tiene el foco. Si usamos la forma CambiarJugador(otro, 1) (es decir, un 1 como segundo parámetro), entonces el título de las habitaciones incluirá entre paréntesis el nombre del personaje que está siendo controlado, por ejemplo: "En el calabozo (como Manolo)". |
![]() ![]() |
Cuando el jugador cambia a otro personaje que a su vez tiene una
rutina ordenes, la cosa empieza a complicarse (ya que la
orden puede provenir del jugador "real" tras el teclado, o del
objeto jugador, y la reacción puede ser diferente en cada
caso). Resultará útil ordenar las cosas en la forma siguiente
(imaginemos que lo siguiente pertenece al objeto MANOLO, y que el
jugador puede "convertirse" en manolo durante el juego):
|
![]() |
|
![]() |
|
El jugador estará vivo mientras la variable banderafin sea cero. Si se da a esta variable el valor 1, el jugador muere. Si se le da el valor 2, el juego termina con la victoria. Valores por encima de 2 significan formas más exóticas de morir, y en este caso la librería llama a la función MensajeMuerte (que debe ser escrita por el programador) para que imprima el mensaje adecuado (se supone que esta rutina consultará la variable banderamuerte e imprimirá un mensaje diferente según el valor que allí encuentre.
Algunos juegos permiten la reencarnación (o más propiamente dicho la resurrección). Tú también puedes permitirlo programando una rutina llamada MasAlla. Esta rutina es llamada cuando el jugador muere, pero antes de que se muestre el mensaje "Estás muerto". Dentro de esta rutina puedes hacer lo que quieras, incluyendo el volver a poner a 0 la variable banderafin, lo cual causará que el juego prosiga normalmente, en vez de terminar. No obstante ten presente que una función MasAlla suele ser difícil de escribir, ya que debe poner el juego en una situación que sea consistente con lo que ha ocurrido (el jugador ha muerto y resucitado. ¿Qué pasa con sus pertenencias? ¿Qué pasa con el objeto o habitación que le causó la muerte?)
![]() | ![]() | ![]() | Iniciar, mover, cambiar y matar al jugador |