Líneas de estado
Uno de los usos más comunes del ensamblador-Z dentro de un juego
Inform es el de crear líneas de estado personalizadas. Éstas no
funcionarán con Inform Glulx, puesto que no reconoce el
ensamblador-Z. En su lugar, tendrás que usar las llamadas a Glk
equivalentes - que no son opcodes, sino más bien rutinas como
cualquier otra.
La línea de estado es una tradición tan arraigada dentro de las ACs
(sobre todo inglesas) que cuesta realmente un poco deshacerse de
ella. Un juego Inform estándar reservará una parte de la pantalla para
mostrar el nombre de la localidad en la que se halla el jugador, la
puntuación actual, y el número de movimientos realizados. Para cambiar
esto, el programador debe insertar la línea "Replace DibujarLineaEstado;
"
al comienzo del programa (también vale si lo pones justo después de
las constantes, en realidad, es suficiente que aparezca antes del
primer Include
). Después, el programador debe proporcionar una
rutina DibujarLineaEstado
alternativa. Pero aquí es donde las cosas
divergen un poco.
En Inform estándar, el comando para crear la ventana de la línea de
estado (@split_line
) se hacía dentro de la rutina
DibujarLineaEstado
de la librería. Si quieres reemplazar ésta,
tienes que poner el comando @split_window
en la tuya. Si quieres
eliminar la línea de estado, todo lo que necesitarás hacer es
reemplazar DibujarLineaEstado
por una rutina vacía, como esta:
Esto ya no es suficiente en Glulx Inform. En la sección Glulx de
InformATE biplataforma, la ventana para la línea de estado es creada
en la rutina GGInitialise
, no en DibujarLineaEstado
. Esto
significa que si te limitas a usar una DibujarLineaEstado
vacía, la
línea de estado saldrá vacía, pero aún estará ahi, burlándose de
tí. De modo que lo que tienes que hacer es interceptar el comando que
crea la ventana de estado, mediante una programación de la rutina
InitGlkWindow
como la siguiente:
[ InitGlkWindow winrock;
switch (winrock) {
GG_STATUSWIN_ROCK: rtrue;
}
rfalse; ! si olvidas esta línea el programa no funcionará
];
|
Si quieres mantener la línea de estado, pero configurar a tu gusto la
información que se muestra en ella, he aqui algunos consejos. Lo
primero, si quieres reservar más de una línea para la ventana de
estado, debes hacerlo en InitGlkWindow
, como aqui:
[ InitGlkWindow winrock;
switch (winrock) {
GG_STATUSWIN_ROCK:
gg_statuswin_size = 2; ! el número de líneas que desees
}
rfalse; ! si olvidas esta línea el programa no funcionará
];
|
Después, al escribir tu propia DibujarLineaEstado
, debes comenzar
con el código siguiente:
! Si no hay ventana de estado, no hay que redibujarla
if (gg_statuswin == 0)
return; ! Si no hay localización, tampoco
if (localizacion == nothing || parent(jugador) == nothing)
return;
|
La primera línea después de eso, debe ser
glk_set_window(gg_statuswin);
para cambiar a la ventana en la cual
estás a punto de imprimir información de estado, y la última línea
debe ser glk_set_window(gg_mainwin);
para asegurarte de que el
programa continuará imprimiendo el texto del juego en el lugar
correcto. En el medio, puedes imprimir cualquier cosa, si bien el
procedimiento para ello es ligeramente diferente al usado en una
ventana de tipo buffer de texto.
Recuerda que una ventana tipo rejilla de texto es una especie de
tablero de Scrabble: aunque no se ven las líneas separando las
casillas, la ventana consiste en una rejilla de casillas, cada una de
las cuales puede contener un carácter - letra, número o
puntuación. Cada casilla tiene un par de coordenadas asociadas, una
coordenada X y una coordenada Y. La coordenada X es cuántas casillas
hay antes de ella contando desde el borde izquierdo; la coordenada X
de la primera casilla (junto al borde izquierdo) es 0. La coordenada Y
es cuántas casillas hay por encima de la casilla actual, hasta el
borde superior; la coordenada Y de las casillas superiores es 0. (Esto
es diferente al Inform estándar, en el que la esquina superior
izquierda no era (0,0), sino (1,1)). Para seleccionar el lugar donde
quieres comenzar a escribir, usa la orden glk_window_move_cursor()
,
que necesita tres argumentos: el nombre de la ventana donde
imprimirás, la coordenada X de la casilla en la que quieres que
comience a imprimir, y la coordenada Y de esa casilla. Cuando
imprimas, el cursor irá avanzando automáticamente hacia la derecha
para cada letra del texto impreso - no necesitas moverlo para
imprimir la siguiente letra de una palabra. Así que el código
siguiente:
glk_window_move_cursor(gg_statuswin, 3, 0);
print "Hora: ";
|
colocará la letra "H" en la posición (3,0), la "o" en (4,0), "r"
en (5,0), "a" en (6,0), dos puntos en (7,0) y un espacio en (8,0),
dejando el cursor en (9,0). Presumiblemente después iría el código
para imprimir la hora.
Una cosa a tener en cuenta es que no todo el mundo que juegue tu juego
tendrá la misma cantidad de espacio de pantalla reservado para Glulxe:
la línea de estado puede tener espacio para 120 letras en el ordenador
de una persona, y 40 en el de otra. O alguien puede cambiar de tamaño
la ventana Glulxe, y el ancho cambiar de 120 a 40 en mitad del
juego. Puedes programar la rutina DibujarLineaEstado
para que tenga
esto en cuenta (como de hecho se hace en la DibujarLineaEstado
que
viene con InformATE). Simplemente añade variables llamadas ancho
y
alto
en la declaración de DibujarLineaEstado
, e inserta el
siguiente fragmento de código en tu rutina:
glk_window_get_size(gg_statuswin, gg_arguments, gg_arguments+4);
ancho = gg_arguments-->0;
alto = gg_arguments-->1;
|
Y después puedes hacer los ajustes que estimes oportuno. Digamos que
estás haciendo un juego llamado Tritura, Machaca y Pisotea y quieres
poner un indicador de hambre en la línea de estado, comenzando en la
columna 40, que debe mostrar una de las palabras "HARTO", "SATISFECHO",
"HAMBRIENTO", "FAMELICO". Esto podría llevarte hasta la columna
50. Puede que algunos jugadores estén jugando con menos de 50
columnas, y en ese caso prefieres que no se muestre este indicador
(porque lo que desde luego no quieres es que aparezca incompleto, a
mitad de una palabra). Usarías un código como el siguiente:
if (ancho > 50) { ! Nos aseguramos de tener sitio
glk_window_move_cursor(gg_statuswin, 40, 0);
switch (gojira.hambre) {
0: print "HARTO";
1: print "SATISFECHO";
2: print "HAMBRIENTO";
3: print "FAMELICO";
}
}
|
Observa que las cuatro palabras anteriores tienen diferentes
longitudes. Si intentas sobreescribir "SATISFECHO" con "HARTO",
obtendrás "HARTOFECHO", a menos que, o bien rellenes con espacios a
la derecha cada palabra, o pongas un glk_window_clear(gg_statuswin);
justo después de tu llamada a glk_set_window(gg_statuswin);
. La
librería InformATE usa este segundo método.
Se pueden hacer acomodos más inteligentes que simplemente el no
mostrar los elementos que no caben - podíamos haber puesto algún
código elaborado para abreviar las cosas a medida que la línea de
estado es más pequeña, por ejemplo. Lo bueno es que, ya que
DibujarLineaEstado
es llamada en cada turno, no necesitas andar
tocando HandleGlkEvent
para manejar los cambios de tamaño, como es
necesario hacer con los gráficos. Más sobre esto en las secciones
siguientes.