Started by: metamorphium
Translation by: HelLRaiseR
Date: 21. 8. 2005 / 25.3.2009
Prerequisitos: WME development kit instalado
Bienvenido a mi primer tutorial. Está focalizado en el trabajo con variables y objetos en el lenguaje de script de WME. Debido a que este tema es teórico, comenzaré con algo de teoría para aegurarme que no te pierdes por el camino.
Primero vamos a establecer varias cosas obvias. Vamos a pensar en una variable como en un contenedor utilizado para almacenar cierta información. La información que se almacene en el depende exclusivamente de ti. El lenguaje de script de WME es muy permisivo, permitiendo crear variables globales en las que puedes almacenar lo que quieras (esto, en términos informáticos, se realiza de forma dinámica). Vamos a echarle un vistazo. Con el Project Manager crea un nuevo proyecto. El mo se ha llamado ObjectsTutorial.
Como puedes ver en Scenes hay una nueva escena llamada Room. Ejecuta el proyecto con F5 y podrás ver una pantalla verde con Molly en el centro. Pulsa Alt+F4 para salir y vamos a trabajar. Ve a la carpeta de tu proyecto y abre el fichero scene_init.script localizado en data/scenes/Room/scr/scene_init.script.
Una variable se declara utilizando la palabra clave var o global, que determina el ámbito en el que dicha variable es válida. Veremos esto mas tarde.
Por ahora vamos a ignorar lo que hay en este fichero. Añade la siguiente línea de código inmediatamente después de la línea#include "base.inc":
var mi_variable; //Primera variable local creada
Este tipo de variable simple se puede alimentar con lo que quieras en tu script, podemos probarlo fácilmente. A partir de ahora añade todos los ejemplos que vienen a continuación en tu archivo scene_init.script. Este cada vez crecerá más y se convertirá en una buena referencia en caso de que olvides algo más tarde.
mi_variable = 1; // Primero asignamos un número a nuestra variable mi_variable = my_variable * 500; // Realizamos una operación numérica en ella Game.Msg(mi_variable); // Mostramos el valor (un número) que contiene nuestra variable mi_variable = "Hola a todos"; // Ahora asignamos una cadena de texto a nuestra variable Game.Msg(mi_variable); // Mostramos el valor (una cadena de texto) que contiene nuestra variable
TRADUCCION EN PROGRESO POR HELLRAISER
If you run your test now you will see that it works and that a variable can hold whatever type you assign it. Additionally, you can change what type of value is stored in your variable at any time. Since most of you already knew this part I am moving to something more interesting: Arrays.
Basically, an Array is a field of variables which can help us in access automation. We will again use our nice variable to do that job for you so let's look at the quick (non object) way how to create simple array:
// Each variable in array is indexed by number and it starts from 0. //This you must remember otherwise other coders will hate you. my_variable[0] = "Today is Wednesday"; my_variable[1] = "Tomorrow is Wednesday as well"; my_variable[2] = "Everyday is Wednesday";
Now we can print these texts either using the Game.Msg(my_variable[0]); etc. or we can use more elegant way through the loop:
for (var a = 0; a < 3 ; a = a+1) { Game.Msg(my_variable[a]); //variable a will get the value of numbers from 0 //to 2 thanks to **for** loop construct }
Again you can test it by running WME project and when you get back, we will move to some more complicated things.
…™
Ok. I presume that you're back and know how all these necessary things works so we will now start with something more interesting. I was speaking at the begining about using keyword var and global. This is one of the key things to understand for successful scripting. Basically by using these keywords, you declare the scope in which the variable is unique. The local variable is valid in one script file → the one you defined it in. The global variable is valid for the whole game. So if you want your game to remember what was going even after script ended, you should use global variable. We will again look at it using example.
Open your script called game.script located in data/scripts and just below the include lines enter the following:
global my_global = "Hi, I am your global variable!";
Now go back to your scene_init.script and append the following:
global my_global; Game.Msg(my_global);
!!This is important!! If you use global variables they MUST be declared using the global keyword in every script you are using them. Otherwise it won't work and you will end up with script compiler errors. I will present my own solution to keeping this easy later.
So just for the record - we created global variable in game.script and set some value into it. Than we printed the value on screen in scene_init.script file. Using globals is the only way how to achieve this. On the other hand the global variable name must be unique for the whole game. If you use var you can have variable called for example test in every single file. Don't do that
if you have global variable of this name. I was debugging a few WME projects and this bug was present there: global variable overridden by some local variable of the same name. Try to keep your code clean as much as possible and chances that your project will be finished will rapidly grow.
Ok. I promised you, that I will say you my way how I keep globals organized in my project. It's some sort of love or hate thing so either it can help you or you'll never use it. It's entirely up to you. So here goes: In the folder data/scripts you will find file
called base.inc. This file is included into every single script file of your game. What I am doing myself is creating bunch of well named inc files and put all globals there. Then I (again using the include command) put these files into base.inc and I am sure I won't run into problems with searching for variables later on. So let's adjust our simple global variable to this new scheme.
In data/scripts create a new file called for example test.inc put only one line there:
global my_global; //Never ever initialize this in the included file. it will //result in your variable resetting with each single script load and it will //cause you a headache.
Now in the base.inc file add line which will read
#include "scripts\test.inc"
In game.script, remove the keyword global from the line which reads global my_global = "Hi, I am your global variable!";
. Next, remove the line which reads global my_global;
from scene_init.script, otherwise your game will crash on script compiler error (It will cause double definition).
And that concludes my way of dealing with globals which lets me easily keep things well organized and traceable. Also I can never override my variable since if I try to define it in some script it gets me script compiler error since the original variable has been already included.
But … we are not done yet. We will move onto the really great field of WME variables - objects. Let's start with a simple example as we are used to: Imagine you have a scene with a nice butterfly. This butterfly has some X and Y position on the screen, some name and for example flag which indicates if it's visible or not. Using the traditional way, we should create 4 separate variables we would have need to keep track of. Not with WME! We can use object for it. So let's look at our first simple object.
Go back to scene_init.script and better start some more appending:
var butterfly; // we know this already //now the fun begins: butterfly.X = 100; butterfly.Y = 200; butterfly.Name = "beautiful butterfly"; butterfly.Active = false;
If we try our favorite Game.Msg(butterfly);
It will write on the screen word "[object]". This is a sign that our endeavor was successful and that we have our neat object done. If we need to access the values we simply print them using
Game.Msg(butterfly.X); Game.Msg(butterfly.Y); Game.Msg(butterfly.Name); Game.Msg(butterfly.Active);
Just note that booleans True / False are in Game.Msg() interpreted as yes / no, but you can still ask about them using traditional if ( butterfly.Active ) or if (! butterfly.Active ) constructs.
Trust me that this object organization will help you with better orientation when you will try hard to read five months old scripts and find some particularly nasty bugs in them.
Last thing and the most advanced at the same time is the full object as you can use it. WME doesn't support calling functions from one script in another. But it supports calling object functions. These functions are called methods and are parts of some script file. We will now put our butterfly example on way higher level.
First of all create in the scr folder of your room scene file called butterfly.script into this file write the following:
method HelloButterfly() { Game.Msg(this.Name); }
Then get back to your scene_init.script and change the var butterfly;
to
var butterfly = new Object("scenes/Room/scr/butterfly.script");
This will cause all methods declared in butterfly.script file to be associated with our variable (now object) and finally we can test the brand new functionality by appending after our butterfly block the following:
butterfly.HelloButterfly();
Upon running our tutorial project we will see that objects are a real fun to work with and sooner or later you will learn to love them. They help to keep your project tidy and if you learn to use them properly, you will save yourself lots of stress. I hope that you liked this tutorial aimed at beginners and that it helped you at least a bit with understanding the very basics of WME script.