API: Guida avanzata all'uso

L'Editor di Script

Per modificare gli script del tuo gioco, clicca sul link "API Scripts" nella pagina dei Dettagli del Gioco per il tuo gioco (nello stesso punto in cui sono situate opzioni come il "Log della Chat" e "Copia/Estendi Gioco"). Ti verranno presentate diverse funzionalità:

  • Una lista di schede nella parte superiore. Il tuo gioco può avere script multipli per una migliore organizzazione. Nota che tutti gli script verranno comunque eseguiti nello stesso contesto, il che significa che non dovresti avere più script che cercano di sovrascrivere gli stessi valori contemporaneamente o potresti ottenere risultati indesiderati.
  • Un editor di codice degli script. Puoi utilizzare questo editor o modificare gli script con un editor esterno a tua scelta e quindi incollarli qui.
  • Una "Console API" situata nella parte inferiore (vedi sotto).

Ogni volta che clicca sul pulsante "Salva script", la sandbox del suo gioco verràriavviata(perdendo tutti i dati in memoria che non sono stati persistiti nell'oggettostatoo negli oggetti Roll20). Questo vale anche se aggiungi un nuovo script, elimini uno script o attivi/disattivi uno script.


La Console API

La Console API è la "finestra" dei tuoi script. Poiché gli script API vengono eseguiti in un sandbox, non hai accesso diretto ad essi mentre sono in esecuzione per visualizzare informazioni sui risultati o sugli errori dello script. La Console API visualizza queste informazioni al di fuori del sandbox in modo che tu possa visualizzarle durante la modifica dei tuoi script. Tutti i comandi dilog()verranno visualizzati qui, così come tutti gli errori riscontrati durante l'esecuzione dei suoi script. Per maggiori informazioni, consultil'articolo sul debug degli script.


Script reattivi: Ascolta eventi, modifica oggetti

Il primo (e il più semplice tipo) di utilizzo di API consiste nel reagire alle modifiche sul tabletop, per poi rispondere con funzionalità aggiuntive agli oggetti modificati. Questo tipo di script è composto da una serie di funzioni che ascoltano gli eventi che avvengono durante il gioco. Successivamente, modificherà gli oggetti passati durante tali eventi, il che cambierà ciò che accade sul tabletop.

Uno script di base che sposta un pezzo di 5 piedi aggiuntivi (assumendo le impostazioni predefinite della pagina) sarebbe:


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

Come puoi vedere, abbiamo creato una semplice funzione on che verrà eseguita ogni volta che viene ascoltato l'evento change:graphic. Alla funzione viene passato l'oggetto grafico, obj. Per apportare una modifica, basta modificare obj utilizzando la funzione set: qualsiasi proprietà che cambiamo verrà rilevata e modificata nel gioco da tavolo.

Devi utilizzaresetegetper impostare e ottenere i valori correnti degli oggetti, altrimenti le modifiche non verranno salvate. (Vedi sotto per un elenco dei tipi di oggetti e delle loro proprietà, nonché un elenco di tutti gli eventi e degli argomenti passati a ciascun evento.)

Nota sulle funzioni di utilità

Naturalmente, l'esempio precedente non è particolarmente utile perché aggiunge sempre 70 pixel alla posizione del token. Ma cosa succede se l'utente ha modificato la scala in modo che 5ft corrisponda a 140 pixel? L'API di Roll20 fornisce diverse funzioni di utilità utili per aiutare in questo (e in altri) scenari comuni. Modifichiamo il nostro esempio precedente per utilizzare la funzionedistanceToPixels, che ci dirà quanti pixel sono "cinque piedi" (o pollici, o metri, o qualsiasi altro tipo di distanza sia stato impostato) sul piano del tavolo.

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

Ora, se la pagina corrente è impostata per utilizzare il dimensionamento predefinito della griglia,distanceToPixels(5);restituirà ancora 70 pixel, ma se la pagina è impostata per avere una scala doppia rispetto a quella normale, restituirà 140.

È sempre una buona idea utilizzare le funzioni di utilità quando sono disponibili per evitare che lo script si rompa se le impostazioni di una pagina o di un token cambiano.


Script proattivi: fai cose senza intervento dell'utente

Oltre a reagire agli eventi dell'utente, puoi anche fare cose automaticamente con l'API che non sono legate a un evento specifico dei giocatori. Ad esempio, facciamo in modo che un token faccia la ronda avanti e indietro sulla mappa.

Nota: sebbene questo tipo di script non dipenda dall'interazione dell'utente, gli script API per il suo gioco verranno comunque eseguiti solo quando almeno una persona è connessa al suo gioco.

on("ready", function() {
   //Aspetta fino a quando l'evento di caricamento è completamente caricato.
   //Ottieni un riferimento al nostro token di pattuglia.
   var patroltoken = findObjs({_type: "graphic", name: "Guardia A"})[0]; //Sappiamo che c'è un token nel gioco chiamato "Guardia A".
   var direction = -1*distanceToPixels(5); //Cammina a sinistra di 70 pixel.
   var stepstaken = 0; //Quanti passi abbiamo fatto nella direzione attuale?
   setInterval(function() {
     if(stepstaken > 3) {
       //Cambia direzione!
       direction = direction * -1; //"inverterà" la direzione in cui stiamo camminando
       stepstaken = 0; //riporta i passi a 0.
     }
     patroltoken.set("left", patroltoken.get("left") + direction); //cammina!
     stepstaken++;
   }, 5000); //fai un'azione ogni 5 secondi
});

Un Trattato sulle Funzioni Asincrone

Una funzione asincrona è una funzione che restituisce subito il controllo allo scope chiamante e svolge qualche compito in background. Ecco un esempio molto semplice e facile da capire che puoi incollare nella scheda degli script API:

on('load', function() {
  log('Parent Scope - Before call to asynchronous function.');

  setTimeout(function() {
    log('Asynchronous Function Scope - Doing the Asynchronous function work.');
  }, 10 /* 10 milliseconds */);

  log('Parent Scope - after call to asynchronous function.');
});

Nel log API, vedrai qualcosa del genere:

"Parent Scope - Before call to asynchronous function."
"Parent Scope - after call to asynchronous function."
"Asynchronous Function Scope - Doing the Asynchronous function work."

Guardando quel codice, pensi "Certo che succederà dopo, gli hai detto di eseguire tra 10 millisecondi, duh?". Ecco un esempio meno ovvio che avrà gli stessi messaggi di log:

on('load', function() {
  log('Parent Scope - Before call to asynchronous function.');

  sendChat('Async Function', 'Valuta questo: [[1d6]]', function(msg) {
    log('Asynchronous Function Scope - Doing the Asynchronous function work.');
  });

  log('Parent Scope - after call to asynchronous function.');

Le funzioni asincrone sono necessarie per evitare che l'API si blocchi tutto il tempo. Se ogni lancio di dado fosse gestito in modo sincrono, l'API sarebbe estremamente lenta e non reattiva. Quasi ogni funzione che vedi che prende una callback è asincrona. (Eccezione per alcune delle funzioni _.map, _.reduce, ecc., queste sono esempi di programmazione funzionale in contrasto con la programmazione procedurale a cui la maggior parte delle persone è abituata.)

Questo articolo ti è stato utile?
Utenti che ritengono sia utile: 30 su 52