GráficosCómo hacer cosas con Glulx InformEstilos de textoLíneas de estado

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:

[ DibujarLineaEstado; ];

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.


GráficosCómo hacer cosas con Glulx InformEstilos de textoLíneas de estado