API: Guía de Uso Avanzado

El Editor de Guion

Para editar tus guiones de juego, haz clic en el enlace "Scripts de API" en la página Detalles del juego de tu juego (el mismo lugar donde se encuentran opciones como "Registro de chat" y "Copiar/Extender juego"). Se te presentarán varias características:

  • Una lista de pestañas en la parte superior. Tu juego puede tener varios guiones para facilitar la organización. Ten en cuenta que todos los guiones se ejecutarán en el mismo contexto, lo que significa que no debes tener varios guiones tratando de sobrescribir los mismos valores al mismo tiempo o podrías obtener resultados no deseados.
  • Un editor de código de guion. Puedes usar este editor o editar tus guiones en un editor externo de tu elección y luego pegarlos aquí.
  • Una "Consola de API" ubicada en la parte inferior (ver más abajo).

Cada vez que haga clic en el botón "Guardar scripts", la caja de arena de su juego sereiniciará(perdiendo cualquier dato en memoria que no haya sido persistido en el objetode estadoo en objetos Roll20). Esto también se aplica si agregas un nuevo guion, eliminas un guion o activas/desactivas un guion.


La Consola de la API

La Consola de la API es la "ventana" hacia tus scripts. Ya que los scripts de la API se ejecutan en un sandbox, no tienes acceso directo a ellos mientras se están ejecutando para visualizar información sobre los resultados o errores del script. La Consola de la API muestra esta información fuera del sandbox para que puedas verla mientras editas tus scripts. Todos los comandoslog()se mostrarán aquí, así como cualquier error que se encuentre durante la ejecución de sus scripts. Para más información, consulteel artículo sobre depuración de scripts.


Scripts Reactivos: Escuchar eventos, modificar objetos

El primer (y más simple) tipo de uso de API es reaccionar a cambios en el tablero, y luego responder con funcionalidad adicional a los objetos cambiados. Este tipo de script está compuesto por una serie de funciones que escuchan eventos que ocurren durante el juego. Luego modificará los objetos que se pasan durante esos eventos, lo que cambiará lo que sucede en el tablero.

Un script básico que mueve una pieza 5 pies adicionales (suponiendo la configuración de página predeterminada) sería:


        on("change:graphic", function(obj) {
  obj.set({
    left: obj.get("left") + 70    
  });
});

Como puedes ver, creamos una función simple usando on que se ejecutará cada vez que se escuche el evento change:graphic. La función recibe el objeto gráfico, obj. Para hacer un cambio, simplemente modificamos obj usando la función set; cualquier propiedad que cambiemos se detectará y cambiará en el tablero de juego.

Debes usarsetygetpara establecer y obtener los valores actuales de los objetos, de lo contrario tus cambios no se guardarán. (Consulta a continuación una lista de los tipos de objetos y sus propiedades, así como una lista de todos los eventos y los argumentos que se pasan a cada evento).

Nota sobre las funciones de utilidad

Por supuesto, el ejemplo anterior no es muy útil porque siempre agrega 70 píxeles a la ubicación del token. Pero, ¿qué sucede si el usuario ha cambiado su escala para que 5 pies sean 140 píxeles? La API de Roll20 proporciona varias funciones de utilidad prácticas para ayudar con esto (y otros) escenarios comunes. Modifiquemos nuestro ejemplo anterior para utilizar la funcióndistanceToPixelsfunction, que nos dirá cuántos píxeles hay "cinco pies" (o pulgadas, o metros, o cualquier otro tipo de distancia que se haya establecido) sobre el tablero.

on("change:graphic", function(obj) {    
  obj.set({        
    left: obj.get("left") + distanceToPixels(5);    
  });
});

Ahora bien, si la página actual está configurada para utilizar el tamaño de cuadrícula por defecto,distanceToPixels(5);seguirá devolviendo 70 píxeles, pero si la página está configurada para tener una escala dos veces mayor que la normal, devolvería 140.

Siempre es una buena idea utilizar funciones de utilidad cuando estén disponibles para ayudar a evitar que su script se rompa si cambian la configuración de una página o un token.


Scripts proactivos: hacer cosas sin intervención del usuario

Además de reaccionar a eventos del usuario, también puedes hacer cosas automáticamente con la API que no están vinculadas a un evento específico de los jugadores. Por ejemplo, vamos a tener un token que patrulla de un lado a otro en el mapa.

Nota: Aunque este tipo de script no depende de la interacción del usuario, los scripts de la API de su juego seguirán ejecutándose únicamente cuando al menos una persona esté conectada a su juego.

on("ready", function() {
   //Espera hasta que el evento de listo se ejecute para saber que el juego está completamente cargado.
   //Obtener una referencia a nuestro token de patrulla.
   var patroltoken = findObjs({_type: "graphic", name: "Guardia A"})[0]; //Sabemos que hay un token en el juego llamado "Guardia A".
   var direccion = -1*distanceToPixels(5); //Caminar hacia la izquierda 70 píxeles.
   var stepstaken = 0; //¿Cuántos pasos hemos dado en la dirección actual?
   setInterval(function() {
     if(stepstaken > 3) {
       //¡Cambia de dirección!
       direccion = direccion * -1; //cambiará la dirección en la que caminamos
       stepstaken = 0; //restablecer los pasos a 0.
     }
     patroltoken.set("left", patroltoken.get("left") + direccion); //¡Caminar!
     stepstaken++;
   }, 5000); //realizar una acción cada 5 segundos
});

Un tratado sobre funciones asíncronas

Una función asíncrona es aquella que devuelve el hilo de control al ámbito de llamado de inmediato y realiza alguna tarea en segundo plano. Aquí tienes un ejemplo muy simple y fácil de entender que puedes pegar en una pestaña de scripts de API:

on('load',function(){
  log('Parent Scope - Antes de llamar a la función asincrónica.');

  setTimeout(function(){
    log('Scope de la Función Asincrónica - Realizando el trabajo de la función asincrónica.');
  },10 /* 10 milisegundos */);

  log('Scope Padre - después de llamar a la función asincrónica.');
});

En el registro de API, verás algo como esto:

"Scope Padre - Antes de llamar a la función asincrónica."
"Scope Padre - después de llamar a la función asincrónica."
"Scope de la Función Asincrónica - Realizando el trabajo de la función asincrónica."

Al ver ese código, piensas "Por supuesto que ocurrirá más tarde, le dijiste que se ejecutara en 10 milisegundos, ¿no?". Aquí tienes un ejemplo menos obvio que tendrá los mismos mensajes en el registro:

on('load',function(){
  log('Scope Padre - Antes de llamar a la función asincrónica.');

  sendChat('Función Asincrónica','Evaluar esto: [[1d6]]',function(msg){
    log('Scope de la Función Asincrónica - Realizando el trabajo de la función asincrónica.');
  });

  log('Scope Padre - después de llamar a la función asincrónica.');

Las funciones asíncronas son necesarias para evitar que la API se bloquee todo el tiempo. Si cada lanzamiento de dados se manejara de forma síncrona, la API sería muy lenta y no respondería adecuadamente. Casi cualquier función que veas que utiliza un callback es asíncrona. (Excepción para algunas de las funciones _.map, _.reduce, etc, estas son ejemplos de programación funcional en contraste con la programación procedural a la que la mayoría de la gente está acostumbrada.)

¿Fue útil este artículo?
Usuarios a los que les pareció útil: 30 de 52