Tutorial de Scripting, Adventure Game Studio

14 de noviembre de 2008
Valoración del artículo:
En AGS, toda la interactividad del juego se gestiona a través de scripts. Son un parte esencial del proceso de creación del juego, así que es importante que conozcamos bien sus funciones.
Atención: Contenido exclusivo de DesarrolloMultimedia.es. No reproducir. Copyright.

Lo Básico

Vamos a empezar con algo sencillo, mostrar un mensaje al jugador cuando este haga clic en un hotspot con el puntero Look (mirar). Suponiendo que hayas realizado los tutoriales básicos de AGS, deberías tener un script parecido a este en tu juego:

function hDoor_Look()

{

  Display("Es un puerta muy grande e imponente.");   

}    

Vamos a observar esto en detalle.  "function" le dice a AGS que esto es un bloque de código de script que se ejecutará cuando ocurra un evento. "hDoor_Look" es el nombre de dicho evento. Los paréntesis sin contenido ( ) le dicen a AGS que esta función no contiene ningún parámetro (los explicaremos más adelante). Por ultimo, las llaves { y } definen donde empieza y acaba el bloque de código. Todo lo que escribas entre llaves {  } se ejecutará cuando se active este evento.

Display es el nombre del comando que vamos a ejecutar. Entre los paréntesis introducimos los parámetros que afectan a este comando. Los parámetros son partes de información adicional que el comando necesita para ejecutarse, en este caso, necesita el mensaje que queremos que muestre.

Por último, debemos acabar la línea con punto y coma. Usaremos el punto y coma para decirle a AGS que ese es el fin del comando. Todo lo que añadas después del punto y coma, formará parte de un nuevo comando, y normalmente usarás otra línea.

Es importante añadir que las líneas que comiencen con doble barra invertida // son comentarios, y AGS las ignorará. Estas líneas te permiten añadir comentarios para que te orientes sobre que va a hacer tu script en cada momento. Para ello simplemente comienza la línea con //.

Explicando los Comandos

Cada comando diferente que puedes usar en un script también se denomina función. Todos los comandos disponibles están listados en la parte de Scripting del manual, que también te explica como usar cada uno de ellos.

Queremos mostrar un mensaje al jugador, así que hemos usado la función Display. Si buscamos esta función en el manual, encontramos esta definición:

Display (cadena de texto, ...)

  Muestra un mensaje en pantalla. Se mostrará en el recuadro de mensajes estándar y en el centro de la pantalla. (La descripción continua…)

Lo más importante de esta definición esta en la primera línea. Lo que se muestra entre paréntesis, llamado parameter list, sirve para definir que parámetros asignas a esa función. Un parámetro es información que la función usa para decidir que hacer.
Cada parámetro se lista separado por comas. Puedes usar los siguientes:

  • string name
    Este parámetro es una cadena-string Ej.: un trozo de texto. Esto quiere decir que para este parámetro añades texto entrecomillado. Por ejemplo,  "Mi texto”.
    name es el nombre por el cual el parámetro es referido en la descripción de la función, pero no es relevante para la escritura de tu script.
  • int name
    Este parámetro es un número entero Ej.:.un valor numérico. Esto quiere decir que a este parámetro añades un número, por ejemplo: 65.
  • CHARID
    Este parámetro es el nombre de script del personaje. Tienes que añadir el nombre de script de uno de los personajes del juego.
  • InventoryItem*
    Este parámetro se refiere a un objeto del inventario. Tienes que indicar que objeto quieres usar.
  • ...
    Este parámetro es opcional y puede ser de cualquier tipo. No tienes porque añadir nada en el, pero si lo haces la descripción de la función ye dirá que tipo de valor usar.

Así que ya sabemos que nuestra función Display necesita una cadena (string) y un parámetro opcional. La descripción continua explicándonos que el parámetro opcional se usa para opciones avanzadas como mostrar valores variables, así que podemos ignorarlo por el momento.

Para hacer que el script llame a la función tenemos que escribir su nombre, después los parámetros entre paréntesis y finalmente punto y coma para cerrarla. Esto es muy importante, ya que si no añades el punto y coma, el script no se compilará. También debes tener en cuenta que NO ESCRIBIMOS el tipo de parámetro (“string” o “int”). Así que podemos añadir esta línea a nuestro script:

Display("Es una puerta grande e imponente.");  

Esto ya lo habíamos hecho en el tutorial básico, pero después de haberlo examinado en más detalle deberíamos entender mejor como funciona.


Instancias – Instances

El lenguaje de scripting de AGS esta basado en objetos. Esto quiere decir que la mayoría de los comandos operan en algo del juego. No debes confundir basado en objetos (objet-based) con los objetos de estancia (room objets) ya que son cosas completamente diferentes. Hay una instancia de script para cada personaje del juego, cada objeto de la estancia, cada hotspot, etc.

El nombre por el cual accedes a una instancia en el script se asigna en el editor como Script Name. Por ejemplo, suponiendo que el nombre de script de nuestro protagonista es cEgo, su nombre de instancia será  cEgo.

Para aplicar un comando en un elemento, debes escribir su nombre de script seguido de un punto, seguido del nombre del comando. Cuando añades el punto, el editor de script de AGS te mostrará automáticamente una lista con los comandos disponibles:

Función Auto-Complete del Editor de Scripts


Entonces eliges el comando adecuado y le añades los parámetros entre paréntesis como ya hicimos con el comando Display. Por ejemplo:

    

  cEgo.AddInventory(iKey);   

Este comando añadirá la llave al inventario del personaje EGO. Si buscas el comando AddInventory en el manual, versa que contiene dos parámetros, un InventoryItem * y un optional int. El parámetro InventoryItem* sirve para añadir el nombre de script del objeto de inventario, algo que puedes modificar en el editor.
El parámetro optional int indica que puedes añadir otro parámetro pero que este es opcional. En este caso, te permite en que hueco-slot del inventario se colocará el objeto, pero es algo que no necesitamos por ahora.

Así como tenemos instancias individuales para cada personaje como cEgo, también existe una instancia especial llamada player. Esta siempre hará referencia al personaje controlado en ese momento por el jugador, así que si quieres aplicar un comando al personaje controlado por el jugador (esto es especialmente útil en los juegos en los que el jugador puede controlar a diferentes personajes) puedes usar la instancia player para hacerlo.

Secuencias de Comandos

Imagínate que queremos que el jugador reciba un poster rosa cuando mire a un determinado hotspot y que se le muestre un mensaje. Vamos a suponer que ya hemos creado un objeto de inventario para el poster cuyo Nombre de Script es iPoster (busca en el Tutorial Básico como crear Objetos de Inventario), el script nos permite realizar estas funciones de manera sencilla.

Nos debería quedar un script parecido al siguiente;

   

  Display(“Es una puerta grande e imponente");   

  cEgo.AddInventory(iPoster);

Te en cuenta que el sistema de scripts es sensible a las mayúsculas así que si escribes  addinventory(iposter); no funcionará.

Los comandos se ejecutan de arriba abajo, así que si escribes algo así:

  Display("¿Por qué ha hecho eso?");   

  Display("Porque estaba aburrido.");   

Al jugador se le mostrarán los mensajes en el orden en el que los escribiste.

Resumen

Es importante que recuerdes estés puntos:

  • Las cadenas de texto deben ir entrecomilladas.
  • ; para cerrar cada línea de código.
  • Se tienen en cuenta las mayúsculas.
  • Para usar un comando basado en instancias, escribe el Nombre de Script seguido de un punto y seguido del comando.
  • La instancia player corresponda al personaje controlado por el jugador en ese momento.

 Variables

Los scripts en AGS pueden usar variables. Una variable es un área de almacenamiento en la memoria que contiene un valor, que puedes comprobar y cambiar con tu script.

Para declarar una variable, debes escribir el tipo de variable, seguido del nombre de dicha variable y finalizar con un punto y coma. El tipo de la variable puede ser "int", "String" (importante la S mayúscula) o "float", y el nombre puede ser el que quieras, lo usarás para referirte a ella más adelante. Por ejemplo:

  int myCounter;   

El nombre de la variable solo puede contener letras A-Z, a-z y el guión bajo _.

Es necesario que declares una variable antes de poder usarla, para que el compilador pueda encontrar errores y saber que tipo de cosas puede contener esa variable.

Inicialmente, tu variable tendrá un valor 0, aunque de manera opcional podrás asignar el valor inicial con una declaración como esta:

  int myCounter = 5;   

Que hará que la variable contenga el valor 5 desde el inicio.

Variable Scope – Ámbito de la variable

Un desafortunado efecto secundario del intento del script por emular al lenguaje “C” es el ámbito de la variable. En pocas palabras, esto significa que tienes que definir las variables FUERA de cualquier evento, si no lo haces, el valor de tu variable se reseteara continuamente.

Así que para declarar una variable para usarla en uno de los scripts de interacción de una estancia, tienes que situar la definición por encima del cuerpo principal de la función. Algo así:
 

// script de una estancia

int myCounter;

 

(scripts de eventos)

 

function hDoor_Look()

{

  Display("Es una puerta grande e imponente.");    

}    

 

(el resto del script)

Ningún comando puede ser usado fuera de una función (AGS no lo reconocería como tal y no lo ejecutaría). Solo las declaraciones de variables pueden estar fuera de las funciones.

Variables cambiantes

Puedes cambiar el valor de una variable de modo sencillo a través del script, simplemente escribe el nombre de la variable, el símbolo =, el Nuevo valor y finalice con punto y coma:

  myCounter = 10;   

Este fragmento de script definirá el valor de la variable como 10.

También puedes añadir o sustraer al valor de la variable usando los operadores += o -=. Por ejemplo, para añadir 3 al valor de la variable tendríamos que usar el siguiente código:

  myCounter += 3;   

Comprobando variables

Es obvio que necesitamos un modo de saber que valor tiene una variable, sino esta variable seria inútil. Esta operación la realizamos a través de enunciaciones condicionales, también llamadas enunciaciones if.

  if (myCounter == 5)   

  {  

    myCounter = 0;

  }   

Esto significa que si mi variable myCounter contiene el valor 5, se ejecutará el script entre { } (que en este caso dará un valor 0 a la variable). Es obvio que si el valor no es 5, no se ejecutará el script, y se para a la línea siguiente después de }.

Fíjate el uso de dos símbolos ==. En una enunciación "if", SIEMPRE debes usar dos símbolos ==, que compara los dos valores. Si solo usases un = en lugar de comparar el valor 5 con el valor de la variable, lo que haría seria modificar el valor a 5, con lo que obtendrías resultados equivocados.

Se le llama operador a ==, porque realice la operación de comparar dos valores.

Aquí tienes una lista de los operadores básicos disponibles en AGS:

  • ==
    Compara dos valores, y si son iguales, continua.
  • !=
    Compara dos valores, y si NO son iguales, continua.
  • <
    Compara dos valores, y si el valor del a izquierda es menor que el de la derecha, continua.
  • >
    Compara dos valores, y si el valor de la izquierda es mayor que el de la derecha, continua
  • <=
    Continua si el valor de la izquierda es igual o menor que el de la derecha
  • >=
    Continua si el valor de la izquierda es igual o mayor que el de la derecha

Poniendo todo esto en práctica

Ha llegado el momento de hacer algo útil con nuestra variable. Imagina que queremos que el jugador reciba un mensaje distinto cada vez que mire a un hotspot, de modo que la primera vez que lo miré reciba una descripción, la segunda vez recibirá algún detalle más. El código de nuestro script debería quedar así:

  if (myCounter == 0)

  {

    Display("Ves una estantería.");

  }

  if (myCounter == 1)

  {

    Display("Mirando más de cerca, ves un libro titulado Hamlet."); 

  }

  if (myCounter == 2)

  {

    Display("También hay un libro titulado Harry Potter.");

  }

  if (myCounter == 3)

  {

    Display("No hay nada mas de interés en la estantería."); 

  }

  if (myCounter < 3)

  {

    myCounter += 1;

  }

Al inicio myCounter tiene el valor 0, así que la primera vez que se llame al script este ejecutará el primer comando Display, pero no los demás. Entonces, como 0 es menor que 3, aumentará el valor de myCounter en 1, y como 0+1 = 1 la variable pasará a tener el valor 1.
Una vez que el jugador ya haya visto todos los mensajes (myCounter == 3), la variable no podrá aumentar más de valor, por lo que el jugador seguirá recibiendo el mensaje final cada vez que haga clic sobre el hotspot.

Haciendo sencillas las Variables Globales

Puede que haya situaciones en las que quieras que el valor de una variable pueda ser usado por el script de una estancia y el script global. Puedes hacer esto de dos maneras: puedes exportar la variable desde el script global para importarla en la cabecera del script de la estancia, pero esta operación es muy avanzada para este tutorial. Una forma más sencilla es hacer uso de uno de los 300 GlobalInts, que usan la función SetGlobalInt y GetGlobalInt para acceder a ellos. Busca sus descripciones en el manual para obtener más información. 

Funciones que nos devuelven un valor

Cuando leas las descripciones de las funciones en el manual, te encontrara con algunas, que devuelven un valor. Por ejemplo:

IsGamePaused ()

  Devuelve 1 si el juego esta pausado, o 0 en el caso contrario. 

Por ejemplo:

  // Para definir el valor de nuestra variable con el valor devuelto 

  myCounter = IsGamePaused(); 

 

(O)

 

  // Comprobar directamente el valor devuelto

  if (IsGamePaused() == 0)

  {

    myCounter += 5;

  }

Asegúrate de no olvidar los paréntesis ().

Atajos comunes

El sistema de scripts tiene algunos atajos muy útiles para funciones que usaras regularmente.

En primer lugar, los operadores ++ y – aumentaran o disminuirán el valor de la variable en 1. La última parte de nuestro script también podría ser así:

  if (myCounter < 3)  

  {    

    myCounter++;

  }

Las llaves { } solo son necesarias en el caso de que usemos dos o más comandos dentro de ellas. Como solo estamos usando un solo comando en nuestro script, "my_counter++;”, podríamos prescindir de las llaves { }:

  if (myCounter < 3)     

    myCounter++;

Sin embargo, esto nos puede llevar a cometer errores en nuestro script muy difíciles de detectar. Yo recomendaría usar siempre las llaves por seguridad.

Por último, si quieres comprobar si un valor es 0 o no, puedes usar lo siguiente:

  if (myCounter)     

    Display("el contador no es cero");   

Es equivalente a:

  if (myCounter != 0)     

    Display("el contador no es cero");   


Resumen

Hemos tratado los aspectos básicos del scripting en AGS, así que con un poco de suerte deberías ser capaz de escribir tus propios scripts a partir de ahora. Hay muchas más funciones avanzadas en el sistema de scripts, pero esto debería ser suficiente para empezar.

Comentarios

Los comentarios de los visitantes son para ampliar la
información del artículo. Cualquiera puede participar.

Añadir un comentario al artículo Publicar un comentario del artículo

Mostrando 2 comentarios revisados

 No entiendo las variables
04/8/11 

Comentario de Edgar:

Entiendo la mecanica, pero intento seguir al pide de la letra tus instrucciones y no consigo nada...¡¡por favor!! podrías mandarme una explicación poniendo un ejemplo supuesto, paso a paso? Describir una variable que copiandola y pegandola funcionara, para entender mejor las puntualizaciones y así poder yo investigarlo mas a fondo y crear las mias propias!. Gracias


 Mal, asi....
06/7/12 

Comentario de Chuno:

Veo muy bien el tema, estoy trasteando el programa, y veo una falla terrible. No se le puede decir dirtectamente que hacer. Por ejemplo: un botón que pulses y sea: coger la llave y guardarla en el inventario. En las versiones anteriores del programa se podia ahcer tal cual. En este solo se puede hacer con scripts. Me parece fatal, ya que de esa forma mucha gente que sabe hacer el resto de cosas se queda con cara de idiota cuando llega el momento de programar, al igual que hay programadores que se quedan con cara de idiota cuando hay que dibujar o grabar. Es decir, ya que el propio programa va perdiendo funciones útiles según lo actualizan, debería haber en algún lado scripts genéricos, de manera que solo alla que cortar y pegar. Ya que si no te pasa como a mi, tengo las ideas, tengo la capacidad para hacer, los fondos, los personajes, la música e incluso grabar voces originales, los videos de introduccion, todo! yo solo.... y sin embargo todo se queda en nada por culpa de que has de saber programar. Es imposible tener talento en todo en esta vida, de forma que al final los proyectos de la gente con este programa se quedan en cosas que ya eran mediocres hace 20 años.


Comentarios sin revisar
Entre los comentarios no revisados puede haber algunos
interesantes que se hayan enviado recientemente.


Se han encontrado 2 comentarios sin revisar




El autor
Rubén Lapuerta
Colaborador Desarrollo Multimedia
http://www.desarrollomultimedia.es
Manuales

Donaciones
Si piensas que te hemos ayudado y merecemos tu apoyo económico...