CAAD

Comunidad de Aventuras Conversacionales y Relatos Interactivos
Fecha actual 18 Oct 2017 15:57

Todos los horarios son UTC + 1 hora




Nuevo tema Responder al tema  [ 14 mensajes ] 
Autor Mensaje
NotaPublicado: 29 Mar 2014 01:04 
Conectado
Grafista
Grafista
Avatar de Usuario

Registrado: 04 Sep 2008 17:23
Mensajes: 683
Viene de una conversación del hilo [I6] Obtener nombre corto de un objeto:

dddddd escribió:
Quizás sabiendo a más alto nivel la funcionalidad que intentas implentar puedan darte una solución más directa. ¿Qué intentas con eso de devolver el texto "nada"? ¿Quizás dar un valor por defecto a todos los objetos? ¿No ayudaría ahí la herencia?

He programado un par de rutinas y definiciones de gramática para lanzar una acción por defecto al teclear el nombre de un objeto. Ahora estaba intentando meter hipervínculos al relato, de la forma más sencilla posible, para que al pulsar con el ratón sobre el nombre de un objeto, el relato interprete que se ha tecleado su nombre.

De momento, para lanzar una acción por defecto tecleando el nombre de un objeto, utilizo este código:

Spoiler: Mostrar
Código:
[ UnknownVerb word      obj;
   objectloop (obj) {
      if (TestScope(obj, player)) {
         if ((WordInProperty(word, obj, name))
            || (WordInProperty(word, obj, name_f))
            || (WordInProperty(word, obj, name_fp))
            || (WordInProperty(word, obj, name_m))
            || (WordInProperty(word, obj, name_mp))) {
            verb_wordnum = 0;
            return 'no.verb';
         }
      }
   }
   objectloop (obj ofclass Room) {
      if ((WordInProperty(word, obj, name))
         || (WordInProperty(word, obj, name_f))
         || (WordInProperty(word, obj, name_fp))
         || (WordInProperty(word, obj, name_m))
         || (WordInProperty(word, obj, name_mp))) {
         verb_wordnum = 0;
         return 'teleport.verb';
      }
   }

   return false;
];

[ PrintVerb word;
   if (word == 'no.verb') {
      print "hacer algo con";
      return true;
   }
   if (word == 'teleport.verb') {
      print "desplazarte a";
      return true;
   }
   return false;
];

!!------------------------------------------------------------------------------
!! ##DefaultAction
!!------------------------------------------------------------------------------
Verb 'no.verb' * noun -> DefaultAction;

[ DefaultActionSub;
   <<Examine noun>>;
];

!!------------------------------------------------------------------------------
!! ##Teleport
!!------------------------------------------------------------------------------
[ TeleportScope obj adjacent_location;
   switch (scope_stage) {
      1:   return false;
      2:   objectloop (obj in Compass) {
            adjacent_location = real_location.(obj.door_dir);
            if (adjacent_location ~= 0)
               PlaceInScope(adjacent_location);
         }
         return true;
      3:   print_ret (parser) "No puedes llegar hasta ahí desde donde estás en
         estos momentos.";
   }
];

Extend 've' last
   * scope=TeleportScope         -> Teleport
   * 'a//' scope=TeleportScope      -> Teleport
   * 'hacia' scope=TeleportScope   -> Teleport
;

Extend 'entra' last
   * scope=TeleportScope         -> Teleport
   * 'a//' scope=TeleportScope      -> Teleport
   * 'en' scope=TeleportScope      -> Teleport
;

Verb 'teleport.verb'
   * scope=TeleportScope         -> Teleport
;

[ TeleportSub;
   PlayerTo(noun, 2);
];

Y, para hacer lo de los hipervínculos, pretendía usar un código de este tipo:

Spoiler: Mostrar
Código:
[ HandleGlkEvent ev abortres obj newcmd cmdlen;
   !! Se gestiona el evento glk:
   if (ev-->0 == 8) { ! evtype_Hyperlink   - selection of a hyperlink in a window
      glk_request_hyperlink_event(gg_mainwin);
      obj = ev-->2;
      if (obj tiene nombre) newcmd = obtener nombre del objeto;
      else return 1;
      glk_cancel_line_event(gg_mainwin, 0);
      cmdlen = PrintAnyToArray(abortres + WORDSIZE,
         INPUT_BUFFER_LEN - WORDSIZE, newcmd);
      abortres-->0 = cmdlen;
      return 2;
   }
];

[ link obj;
   #Ifdef TARGET_GLULX;
   if (obj tiene nombre) glk_set_hyperlink(obj);
   else glk_set_hyperlink(0);
   #Endif; ! TARGET_GLULX;
];

De manera que introducir hipervínculos en las descripciones sea escribir algo de este estilo: "Se trata de una terraza trasera con acceso a la ", (link) obj_COCINA, "casa", (link) 0, ", a un pequeño ", (link) obj_TALLER, "taller", (link) 0, " y a la ", (link) obj_PLAYA, "playa", (link) 0, ".";

Dudo que se trate de la mejor forma de hacerlo, pero me parecía la más sencilla. En cualquier caso, aún le falta encontrar la manera adecuada de comprobar si un objeto tiene nombre, y de obtenerlo si es así. Si alguien puede ayudarme con eso, o me indica alguna forma mejor de hacer lo de los hipervínculos, ¡se lo agradeceré!

(Es tarde y estoy cansado, así que lo mismo me he explicado malamente. Si es así, mañana intento hacerlo otra vez).


Arriba
 Perfil  
 
NotaPublicado: 31 Mar 2014 13:24 
Conectado
Grafista
Grafista
Avatar de Usuario

Registrado: 04 Sep 2008 17:23
Mensajes: 683
Gracias a 6ds tengo ya guardado en un array el nombre corto de un objeto, siguiendo el mismo criterio que utiliza la librería Inform por defecto. Ahora me falta una última cosa para hacer funcionar el sistema de hipervínculos:

Código:
[ HandleGlkEvent ev abortres obj newcmd cmdlen;
   !! Se gestiona el evento glk:
   if (ev-->0 == 8) { ! evtype_Hyperlink   - selection of a hyperlink in a window
      glk_request_hyperlink_event(gg_mainwin);
      obj = ev-->2;
      if (obj tiene nombre) newcmd = string con el nombre del objeto;
      else return 1;
      glk_cancel_line_event(gg_mainwin, 0);
      cmdlen = PrintAnyToArray(abortres + WORDSIZE,
         INPUT_BUFFER_LEN - WORDSIZE, newcmd);
      abortres-->0 = cmdlen;
      return 2;
   }
];

Esto funciona guardando en newcmd un string con el nombre corto de un objeto. Es decir, ahora que tengo el nombre guardado en un array, me hacía falta saber cómo pasar ese array a un string (si es que es posible).

Quizá también se puede sortear esa línea y utilizar directamente el array con el nombre en la línea: cmdlen = PrintAnyToArray(abortres + WORDSIZE, INPUT_BUFFER_LEN - WORDSIZE, newcmd);. Pero vamos, no tengo ni idea.

De nuevo, ¡gracias por cualquier pista! (a partir de aquí procuraré intentar hacer cosas que sepa hacer realmente, para no tener que dar la lata cada dos por tres).


Arriba
 Perfil  
 
NotaPublicado: 01 Abr 2014 02:52 
Desconectado
Implementador
Implementador

Registrado: 13 Feb 2005 18:57
Mensajes: 1855
Antes de nada, en HandleGlkEvent te has saltado el parámetro context (aunque no lo vamos a usar, es importante que esté ahí para completar la lista de parámetros pasados a la función, sobre todo si necesitamos definir otras variables).

Makinaimo escribió:
Quizá también se puede sortear esa línea y utilizar directamente el array
Sí, como el nombre que vamos a inyectar no lo tenemos en un cadena, podemos hacer la copia del array. En el caso de cadena el procedimiento es como expones.

El handler (haciendo uso de la función del otro hilo) quedaría así:
Código:
[ HandleGlkEvent ev context abortres
  i;
  if(ev-->0 == evtype_Hyperlink){
    glk_request_hyperlink_event(gg_mainwin);
    glk_cancel_line_event(gg_mainwin, 0);
    ! ev-->2 es el valor del enlace. Un obj.
    carga_g_nombre(ev-->2);
    for(i=0 : i<=g_nombre-->0 : i++){
      abortres-->i = g_nombre-->i;
    }
    return 2;
  }
];
Nótese que no comprobado que haya un nombre, porque se supone que todos los objetos lo tienen.

De hecho, como todo lo que estamos haciendo funcionará sólo con enlaces a objetos, simplificaría también la función link:
Código:
[ link obj;
  glk_set_hyperlink(obj);
];

También me he ahorrado los #Ifdef porque todo es glulx/glk. Si en tu contexto fuesen necesarios, seguro que los necesitarías en más partes. Quizás sea más importante algún uso de gestalt.


Arriba
 Perfil  
 
NotaPublicado: 01 Abr 2014 12:35 
Desconectado
Implementador
Implementador

Registrado: 13 Feb 2005 18:57
Mensajes: 1855
Makinaimo escribió:
De manera que introducir hipervínculos en las descripciones sea escribir algo de este estilo: "Se trata de una terraza trasera con acceso a la ", (link) obj_COCINA, "casa", (link) 0, ", a un pequeño ", (link) obj_TALLER, "taller", (link) 0, " y a la ", (link) obj_PLAYA, "playa", (link) 0, ".";

Una alternativa, creo que un poco mejor (para gustos...), aunque sólo sea por quitar esos (link) 0.
Código:
[ link
  obj texto;
  glk_set_hyperlink(obj);
  print (string) texto;
  glk_set_hyperlink(0);
];

Código:
description [;
  print "Se trata de una terraza trasera con acceso a la ";
  link(obj_COCINA, "casa");
  print ", a un pequeño "; link(obj_TALLER, "taller");
  print " y a la "; link(obj_PLAYA, "playa");
  print ".";
  rtrue;
]


También he experimentado con crear los enlaces justo con el nombre, en la propia definición de cada objeto (con self). Tiene la ventaja que siempre que se utilice el nombre (por ejemplo, también en la enumeración automática de objetos de una localidad) aparecerá como enlace.

Es un poco más automático pero menos flexible, porque el texto siempre sería el mismo. En el ejemplo, parece que la cocina te interesa describirla como casa, pero en otros casos seguro que no será así. Además, igual tiene consecuencias raras (y hay un momento en que pensé que se crearía un agujero negro, pero parece que carga_g_nombre no explotó en una aparente recursividad). Sería cuestión de experimentar. Si te interesa te pongo un ejemplo.

/me invoca a Sothoth, el experto en estos asuntos.


Arriba
 Perfil  
 
NotaPublicado: 01 Abr 2014 14:50 
Conectado
Grafista
Grafista
Avatar de Usuario

Registrado: 04 Sep 2008 17:23
Mensajes: 683
¡Perfecto!

Si, ya había probado esos link(obj_COCINA, "casa");. Aún no sé si es más incómodo escribir las descripciones así o con los (link) 0. Lo ideal supongo que sería poder añadir etiquetas en el texto. Algo así, quizá:

Código:
print "Se trata de una terraza trasera con acceso a la <a obj='obj_COCINA'>casa</a>, a un pequeño <a obj='obj_TALLER'>taller</a> y a la <a obj='obj_PLAYA'>playa</a>.";

Sé que hay una extensión por ahí: Markup, de Simon Baldwin: "A HTML-like markup extension for Glulx and Z-code, allowing markup of text styles and formatting, inline pictures and hyperlinks (the latter two for Glulx only)", pero no hace exactamente eso, y aún no la he ojeado en condiciones.

En cualquier caso, muchas gracias!


Arriba
 Perfil  
 
NotaPublicado: 03 Abr 2014 15:22 
Conectado
Grafista
Grafista
Avatar de Usuario

Registrado: 04 Sep 2008 17:23
Mensajes: 683
De momento, el código es chapucero como él solo, pero parece que todo funciona razonablemente bien. He colgado una prueba para arrancarla con Quixe.

Editado para corregir una errata!


Última edición por Makinaimo el 03 Abr 2014 16:23, editado 1 vez en total

Arriba
 Perfil  
 
NotaPublicado: 03 Abr 2014 16:07 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Queda muy bien.
Una pregunta... se podrían desactivar los hipervínculos con los que no se pueden interactuar en un momento. Así te ahorras el mensajes de:

Código:
>
[Te has referido a algo con lo que no se puede interactuar en este momento.]


Creo que puede llegar a confundir, cuando esté toda la pantalla llena de texto, tantos hipervínculos visibles.

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 03 Abr 2014 16:33 
Conectado
Grafista
Grafista
Avatar de Usuario

Registrado: 04 Sep 2008 17:23
Mensajes: 683
edlobez escribió:
Una pregunta... se podrían desactivar los hipervínculos con los que no se pueden interactuar en un momento.

Pues es un tema en el que ando un poco pez, como ya he demostrado, pero creo que no puede hacerse eso (tal vez usando Vorple o algo así, pero son librerías que funcionan sólo para relatos interactivos online, y el mio lo planeo distribuir como un archivo descargable).


Arriba
 Perfil  
 
NotaPublicado: 03 Abr 2014 16:57 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Y pienso, no sé, como quedaría un limpiar la pantalla después de cada cambio de habitación. Así sólo tienes presente en cada momento en pantalla los objetos-descripciones que te interesa.Así el jugador no puede picar en un hipervínculo de una estancia ya pasada.
Creo que el personal siempre prefiere el scrooll de pantalla para poder recapitular, aunque a mi personalmente prefiero una pantalla limpia para cada estancia.

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 03 Abr 2014 23:21 
Conectado
Grafista
Grafista
Avatar de Usuario

Registrado: 04 Sep 2008 17:23
Mensajes: 683
Es cierto que podría quedar bien haciendo un limpiado de pantalla. Pero soy de los que prefieren poder desplazarse por todo el texto. :)

Lo que voy a hacer es dejar la funcionalidad de los enlaces, pero evitar que se impriman con un estilo diferente por defecto (aunque el usuario pueda activar el resaltado de los enlaces si quiere). La idea era facilitar lo máximo posible la interacción con el relato por parte del usuario, aunque sea alguien como mi madre al que le cuesta escribir con un teclado (la aventurilla esta que estoy preparando se va a poder terminar sin teclear nada), pero aún así mantener los convencionalismos que sigo siempre y no tener que modificar nada por culpa de los enlaces. Además, si finalmente se pueden llegar a lanzar aventuras para Glulx en android, y se pueden usar hipervínculos, creo que es mucho más cómodo andar pulsando palabras que tener que teclear en la pantalla del móvil (aunque te arriesgues a encontrarte con unos cuantos "[Te has referido a algo con lo que no se puede interactuar en este momento.]").


Arriba
 Perfil  
 
NotaPublicado: 04 Abr 2014 05:14 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
me cito a mi mismo...

edlobez escribió:
..., aunque a mi personalmente prefiero una pantalla limpia para cada estancia.


En una auto-reflexión que he tenido en esta noche creativo-aventurera, la verdad es que mientras la historia sea entretenida y esté bien escrita, me suele dar igual el estilo que tenga.

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 04 Abr 2014 07:58 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5272
Ubicación: Coruña
Esto es un offtopic pero a mí no me gusta nada, pero nada, que me borren la pantalla. Igual que en un libro puedo repasar algo del párrafo anterior o de dos páginas más atrás (y a veces lo hago), en una aventura me gusta poder hacer lo mismo, tal vez incluso con más razón dado que hay que tomar decisiones.

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 10 Abr 2014 17:27 
Conectado
Grafista
Grafista
Avatar de Usuario

Registrado: 04 Sep 2008 17:23
Mensajes: 683
dddddd escribió:
Una alternativa, creo que un poco mejor (para gustos...), aunque sólo sea por quitar esos (link) 0.

Hola otra vez. Ayer noche estuve echando un ojo a Perl y me he preparado un pequeño script para preprocesar el texto antes de compilar el relato, de manera que se puedan usar etiquetas en las descripciones para imprimir texto en cursiva (mediante '*'), negrita ('**'), y definir los hipervínculos como '[nombre_del_objeto(, texto alternativo)]' -- lo que hay entre paréntesis es opcional, si no se incluye nada, lo que se imprime es el nombre corto del objeto.

De esta forma, las descripciones pueden escribirse con este aspecto:
Código:
print "Se trata de una terraza trasera con acceso a la [obj_COCINA, casa], a un pequeño [obj_TALLER:taller] y a la [obj_PLAYA:     playa]. Hay una [obj_muebles, mesa] y algunas [obj_muebles, sillas de exterior], [obj_aroBaloncesto] y [obj_caballete] para *lienzos* (lienzos se imprimirá en itálica), a un lado.^"; rtrue;

Y, el script es este. Hasta ayer no tenía ni idea de Perl, así que la idea que pueda tener ahora mismo es la justa... si alguien sabe cómo se puede mejorar, cualquier comentario será bienvenido.
Spoiler: script Perl
Código:
#!/usr/bin/perl

if ($#ARGV != 1) {
   print "Se deben especificar los archivos de entrada y salida del script.";
   print "\n\n";
   exit 4;
}

$input_file = $ARGV[0];
$output_file = $ARGV[1];

# Se abre el archivo de entrada:
open (FILE, "<$input_file")
   or die "No se pudo abrir el archivo de entrada $input_file: $!\n";
@lines = <FILE>;
close FILE;

# Se abre el archivo de salida:
open (STDOUT, ">$output_file")
   or die "No se pudo abrir el archivo de salida $output_file: $!\n";

for (@lines) {

   # Se hacen las sustituciones (¡el orden importa!):
   s/\*{2,}(.*?)\*{2,}/", (strong) "\1", "/g;
   s/\*(.*?)\*/", (emph) "\1", "/g;
   s/\[(.+?)(\:\s*|\,\s*)(.+?)\]/";\nlink(\1, "\3");\nprint "/g;
   s/\[(.+?)\]/";\nlink(\1);\nprint "/g;

   print;
}

# Cierra el archivo de salida:
close STDOUT;


Arriba
 Perfil  
 
NotaPublicado: 11 Abr 2014 06:22 
Desconectado
Semimomio
Semimomio
Avatar de Usuario

Registrado: 24 Ago 2007 00:41
Mensajes: 2021
Ubicación: Chile
Me van a perdonar que me meta en lo que no me llaman... Pero todo esto no es más que sobreingeniería. :roll: :mrgreen:

_________________
Eliuk Blau
eliukblau (AT) gmail.com
http://www.caad.es/eliukblau/


Arriba
 Perfil  
 
Mostrar mensajes previos:  Ordenar por  
Nuevo tema Responder al tema  [ 14 mensajes ] 

Todos los horarios son UTC + 1 hora


¿Quién está conectado?

Usuarios navegando por este Foro: Makinaimo, weirdzod y 3 invitados


No puede abrir nuevos temas en este Foro
No puede responder a temas en este Foro
No puede editar sus mensajes en este Foro
No puede borrar sus mensajes en este Foro

Buscar:
Saltar a:  
Desarrollado por phpBB® Forum Software © phpBB Group
Traducción al español por Huan Manwë para phpBB-Es.COM