Introducción a GML Parte III

Sentencia If

Evaluación de Corto Circuito

Sentencia Repeat

Sentencia While

Sentencia Do

Sentencia For



La Sentencia "If"


La sentencia "if" nos permite tomar decisiones (ajustar el comportamiento del programa) dependiendo de qué condiciones se cumplen. La sentencia "if" más sencilla tiene la forma:

if (<expresión>) <sentencia>


pero también existe la forma "if... else...":

if (<expresión>) <sentencia> else <sentencia>


En este caso la expresión será evaluada, y si el valor (redondeado) es <=0 (false) la sentencia que sigue a else es ejecutada, de lo contrario (true) la otra sentencia is la que se ejecuta. Se considera como buen hábito poner siempre entre llaves las sentencias del "if" y escribir una sola sentencia por línea, así que el código final tendrá esta forma:

if (<expresión>)
   {
   <sentencia>
   ...
   <sentencia>
   }
else
   {
   <sentencia>
   }


Como ejemplo, considera el siguiente código, el cual moverá las instancias hacia la posición x=200 en la "habitación" del juego:

if (x<200)
   {
   x += 4;
   }
else
   {
   x -= 4;
   }

Evaluación Short-circuit (corto-circuito)

A partir de la versión Early Access de GM:S ha habido un cambio que modifica las evaluaciones de la sentencia “if”. Este cambio introduce la característica conocida como evaluación de corto-circuito. Para comprender la diferencia que este cambio supone, comencemos por hechar un vistazo a cómo se manejaban hasta ahora las sentencias if en GameMaker: Studio:

 

La forma "antigua"

Hasta ahora, cuando queremos evaluar valores generalmente usamos un “if"” así:

var val = irandom(9); if (val < 5)
{
//do one thing...
}
else
{
//do another thing
}

 

Si quisieramos evaluar dos o más valores haríamos algo como esto:

var val1 = irandom(9);
var val2 = irandom(9);
if ((val1 < 5) && (val2 > 4))
{
//do one thing...
}
else
{
//do another thing
}

 

Anteriormente en GameMaker: Studio, ese “if” habría evaluado ambas partes de la condición, revisando el valor de val1 y val2 aun si val1 se hubiera determinado falso. Esto no es óptimo ya que en ocasiones se desean evaluar muchos valores y estos valores podrían provenir de funciones "pesadas" las cuales sería más costoso ejecutar.

Esto provocó que los desarrolladores usaran ifs “anidados”, en donde a cada condición se le daba su propia sentencia “if”, y aunque eso funciona, no es óptimo porque se necesita más tiempo para escribir, su lectura puede ser más confusa y puede que se necesite agregar varios “else” para cubrir cada “if&rdquo anidado. Esta es la razón por la que se ha implementado la evaluación de corto-circuito.

 


La nuevo forma

La evaluación de corto-circuito ayuda a evitar la adición código extra, así como la ejecución de evaluaciones innecesarias. Esto quiere decir que en el momento en que alguna evaluación arroje false, ninguna otra evaluación se probará para esa línea de código ya que no afecta al resultado. Por ejemplo, en nuestro ejemplo anterior, “val2” no será evaluada si "val1" no es menor a 5.

Para algunos, esto puede verse como un cambio menor, pero para los que han trabajado algún tiempo con GameMaker: Studio, es una optimización bienvenida. Ahora es posible colocar evaluaciones de funciones complejas al final de la “cadena” de tal manera que sólo se ejecuten si es absolutaente necesario. Por ejemplo:

var inst = instance_nearest(x, y, object0);
if (instance_exists(inst) && (point_distance(inst.x, inst.y, x, y) > 100))
{
show_debug_message("OBJECT FOUND");
}
else
{
show_debug_message("NO OBJECT!");
}

 

Anteriormente, sin importar qué resultado devolviera la función instance_exists(), la función point_distance() habría sido evaluada... y hubiera dado error si no se hubiera encontrado instancia en la primera condición, ya que ambas condiciones se evaluarían aunque instance_exists() hubiera devuelto false.

Ahora, esto no sucede más, y un valor “false” para instance_exists() romperá (or “corto-circuitará”) la cadena de evaluación, causando que el bloque “else” se ejecute.

 

Activándola o desactivándola

Como esta es una característica nueva y no se puede estar seguro de su impacto en estos momentos, hay una opción en los Ajustes Globales del Juago para activar/desactivar la evaluación de corto-circuito.

 Pestaña General.png

Si se está importando archivos GameMaker de versiones anteriores (gmk, gm81 etc...), la característica será desactivada, mientras que proyectos nuevos en GameMaker: Studio la tendrán activada por defecto. Incluso los juegos de versiones antiguas no deberían verse afectados por las evaluaciones de corto circuito, hasta podrían resultar beneficiados.





La Sentencia Repeat


La sentencia "repeat" tiene la siguiente forma

repeat (<expresión>) <sentencia>


La sentencia se repite el número de veces que se indique como valor de la expresión, redondeando el número. Por ejemplo, el siguiente programa crea cinco pelotas en posiciones aleatorias.

{
repeat (5) instance_create(random(400), random(400), obj_ball);
}


Esto puede resultar sumamente útil para no tener que reescribir el mismo código varias veces, o para utilizar arreglos, o para contar el número de operaciones ejecutadas, etc... Por ejemplo:

{
var i, total;
i = 0;
total = 0;
repeat (10)
   {
   total += array[i];
   i += 1
   }
draw_text(32, 32, total);
}






La sentencia "While"


Una sentencia "while" sigue la estructura:

while (<expresión>) <sentencia>


Mientras que la expresión es verdadera, la sentencia (la cual puede ser también un bloque de código) es ejecutada. ¡Usa con cuidado con tus bucles "while"! Puedes crear fácilmente bucles infinitos, provocando un cuelgue en el juego, el cual no reaccionará más a la entrada de usuario. Se muestra una forma típica de usar "while":

{
while (!place_free(x, y))
   {
   x = random(room_width);
   y = random(room_height);
   }
}


Esto colocará el objeto en una posición libre (casi equivale a mover el objeto a una posición aleatoria)




La sentencia "Do"


Un "do" es en realidad una sentencia "do... until" (hazlo... hasta que) ya que no puedes tener uno sin el otro. Tiene la siguiente forma:

do <sentencia> until (<expresión>)


La sentencia (la cual puede ser un bloque de código) se ejecuta siempre una vez y se continuará ejecutando hasta que la expresión sea cierta. Debes tener cuidado con este tipo de ciclos, ya que es muy fácil que se queden repitiendo la operación para siempre, por lo que el juego dejará de responder y no procesará más las acciones del usuario. Enseguida se encuentra un ejemplo de cómo utilizar la sentencia "do... until":

{
do
   {
   x = random(room_width);
   y = random(room_height);
   }
until (place_free(x, y)); }


El programa anterior tratará de colocar al objeto en una posición que se encuentra vacía (esto realiza lo mismo que la función para mover un objeto a una posición aleatoria).




La sentencia For

Una sentencia "for" tiene la forma:

for (<statement1> ; <expression> ;<statement2>) <statement3>


Y así es como funciona - Se ejecuta la primer sentencia statement1, luego se evalúa la expresión y, si es cierta (true), la sentencia statement3 se ejecuta. Luego la sentencia statement2 se ejecuta y se vuelve a evaluar la expresión. Este ciclo continuará hasta que la expresión devuelva un valor falso (false).

Si lo anterior te suena complicado, lo puedes interpretar así:

Este ciclo resulta muy útil para realizar tareas repetitivas que involucren múltiples líneas de código; comúnmente se usa como contador para evaluar arreglos, o dibujar cosas. El siguiente ejemplo ilustra un ejemplo típico de este tipo de sentencia:

{
var i;
for (i = 0; i < 10; i += 1)
   {
   draw_text(32, 32 + (i * 32), string(i) + ". "+ string(scr[i]));
   }
}


El código anterior inicia un ciclo que comienza en 0 y continúa hasta 9, dentro de lciclo se usa el valor de "i" para dibujar en pantalla (en forma de lista) los valores almacenados en un arreglo. Nótese como la variable del ciclo "i" no sólo se usa para avanzar por el arreglo, sino que también para indicarle a GameMaker:Studio la posición vertical (en la habitación) donde dibujar los valores. Esta flexibilidad es una de las principales razones por la que los ciclos "for" son tan importantes para la programación.