Variables de posición incorporadas por defecto en cada instancia .
- x
- y
- xprevious
- yprevious
- xstart
- ystart
Propiedades de movimiento incorporadas en cada instancia. Es posible leer o ajustar su valor para modificar diversos comportamientos relativos al movimiento.- direction
- friction
- gravity
- gravity_direction
- hspeed
- speed
- vspeed
En muchas ocasiones, es deseable que los oponentes, NPC's, enemigos, etc., interactúen con el jugador y que muestren cierta inteligencia al moverse por la escena, por ejemplo, que eviten obstáculos, planifiquen rutas y que en general, no choquen contra cada objeto/instancia que encuentren a su paso. Para ayudar en la implementación de éstas estrategias, GameMaker:Studio ofrece una serie de funciones que facilitan la planeación de movimiento.
Las funciones mp_ abarcan la planeación de movimiento en GameMaker:Studio. Están divididas en tres grupos:
Este tipo de función trata de de calcular una ruta libre de colisión para la instancia. Una vez que la ruta ha sido calculada, se le asigna a a la instancia para que se mueva hacia su destino. El cálculo tomará cierto tiempo, pero la ejecución posterior de la ruta será rápida. Esto es válido en tanto que la situación no haya cambiado. Por ejemplo, si los obstáculos cambian de posición, lo más probable es que debamos recalcular de nuevo la ruta. Se debe tener en consideración que estas funciones pueden fallar, en tal caso, no se habrá encontrado ninguna ruta para la instancia.
Se trata de funciones de evasión básica, adecuadas para IA simples. Trabajan de manera que la instancia avance hacia una posición de destino, procurando ir en línea recta si es posible, pero cambiando de dirección en caso de ser necesario. Estas funciones deberían usarse en el evento step de la instancia
El tipo final de funciones usa un mecanismo más complejo cuyo enfoque se basa en el uso de una cuadrícula (grid). Este enfoque también se conoce como algoritmo A*. En general, es un método con una tasa de éxito mayor al encontrar la ruta más corta (aunque aun así puede fallar), pero requiere mayor trabajo por parte del programador para ser configurado
La idea general es la siguiente: Antes que nada, debemos crear una cuadrícula que cubra la habitación (room) entera (o la zona relevante, en todo caso). Depende de nosotros usar una cuadrícula "fina" (densa), lo que hace el proceso más lento o una rejilla ancha, aunque en cualquier caso, la cuadrícula debe basarse en la resolución de la habitación , para que la ruta resulte lo más exacta posible. Por ejemplo, si se tiene una room de 400x200 pixels, se puede escoger una resolución de rejilla de 40, o 20, o 10... sependiendo de la precisión que se necesite y de cuánta cantidad de procesamiento se le demande al equipo para generar la ruta.
A continuación, se debe determinar qué celdas de la cuadrícula se traslapan con objetos que se pretende evitar (basándonos ya sea en su caja de colisión o un sprite preciso) y marcar esas celdas como prohibidas, aun cuando el o los obstáculos ocupen sólo una porción de ellas (traslape parcial).
Por último, especificamos una posición inicial y una posición de destino, cuidando que ambas ocupen celdas libres. La función entonces calculará la ruta más corta entre ambas posiciones. La ruta (path) correrá por el centro de todas las celdas, y si las celdas son lo suficientemente grandes como para que la instancia, colocada en su centro, quede totalmente dentro de ellas, el resultado será exitoso (en la mayoría de los casos). A continuación el path se debe asignar a la instancia mediante las funciones path_, de manera que la instancia comience a moverse. Se debe recalcar la importancia del tamaño de las celdas en este proceso, pues deben tener un tamaño suficiente como para que el objeto en movimiento, colocado con su origen en el centro de una celda, quede por completo dentro de ella. (Hay que ser cuidadoso con la posición del origen del objeto. Ten en cuenta que es posible desplazar el path si el origen del sprite no está en su centro). Por otro lado, entre más pequeñas sean las celdas, será posible determinar más rutas. Si las celdas se agrandan demasiado, el espacio entre obstáculos puede quedar bloqueado, debido a que cada celda podría intersectar un obstáculo.
- mp_grid_create
- mp_grid_destroy
- mp_grid_path
- mp_grid_add_cell
- mp_grid_add_instances
- mp_grid_add_rectangle
- mp_grid_get_cell * agregada en GMS v1.4
- mp_grid_clear_all
- mp_grid_clear_cell
- mp_grid_clear_rectangle
- mp_grid_to_ds_grid * agregada en GMS v1.4
- mp_grid_draw
El enfoque basado en una cuadrícula es bastante poderoso (y es usado en muchos juegos profesionales), pero requiere de una planificación cuidadosa para determinar qué área y tamaño de celda son los justos para resolver una ruta, También es importante el determinar qué objetos se deben evitar, y si es necesario contar con una detección precisa. Todos estos factores influyen sensiblemente en la eficiencia de este método. Al final, se debe considerar si usarlo es realmente necesario, ya que es posible que alguna de las (menos costosas) funciones mp_ pueda cumplir con la tarea de manera adecuada.
Cualquiera que sea la elección, se debe advertir que en muchas situaciones, ninguna de las funciones anteriores ofrecerá una solución convincente, y que podría ser necesario implementar una solución que recurra a más de una función de planeación de movimiento, dependiendo de la situación del juego.
x
Devuelve: Real
El valor x de una instancia es su posición horizontal en la habitación actual, medida en pixels. Éste valor puede ser 0, positivo o negativo, donde 0 corresponde a la orilla izquierda de la habitación. El valor de x se incrementa al moverse hacia la derecha y disminuye cuando se avanza hacia la izquierda. Un valor negativo indica que la instancia ha salido de la habitación, más allá de la orilla izquierda. x puede recibir un valor real, como 12.345, pero dado que no es posible tener 0.345 de un pixel, la instancia dará la impresión de que no se ha movido en pantalla aunque GameMaker:Studio en realidad mantiene y usa el valor decimal, el cual es perfectamente válido.
Al ajustar el valor de x (o de y) se logra qye el objeto "salte" a la posición elegida, o se le puede aumentar/decrementar en una cantidad pequeña paso a paso para dar la impresión de movimiento sin recurrir a la función speed o direction. Esto se debe tomar en consideración al crear juegos, ya un tipo de movimiento se adecua más a cierto estilo de juego más que otro.
if keyboard_check(vk_left) x += 5;
if keyboard_check(vk_right) x -= 5;
Este código usa las flechas de dirección para sumar o restar 5 a la posición x y de tal manera crear la ilusión de desplazamiento.
y
Devuelve: Real
El valor y de una instancia es su posición vertical en la habitación actual, medida en pixels. Éste valor puede ser 0, positivo o negativo, donde 0 corresponde al borde superior de la habitación. El valor de y se incrementa al moverse hacia abajo, y disminuye cuando se avanza hacia arriba. Un valor negativo para y indica que la instancia ha salido de la habitación, más allá del borde superior. x puede recibir un valor real, como 12.345, pero dado que no es posible tener 0.345 de un pixel, la instancia dará la impresión de que no se ha movido en pantalla aunque GameMaker:Studio en realidad mantiene y usa el valor decimal, el cual es perfectamente válido.
Al ajustar el valor de y (o de x) se logra que el objeto "salte" a la posición elegida, o se le puede aumentar/decrementar en una cantidad pequeña para dar la ilusión de movimiento sin recurrir a la función speed and direction. Esto se debe tomar en consideración al crear juegos, ya que cierto tipo de movimiento se adecua más a cierto estilo de juego más que otros.
if keyboard_check(vk_down) y += 5;
if keyboard_check(vk_up) y -= 5;
Este código usa las flechas de dirección para sumar o restar 5 a la posición x y de tal manera crear la ilusión de desplazamiento.
xprevious
Devuelve: Real
Puede resultar muy útil saber en dónde se encontraba la instancia en el step anterior, cuando se calculan colisiones por ejemplo, por lo que puedes utilizar esta función para obtener estos valores. Normalmente se almacena justo antes del evento step inicial pero la puedes asignar mediante código en cualquier momento, lo que significa que puedes asignarle algún valor propio si es necesario.
if x != xprevious || y != yprevious { moved = true; }
El código anterior revisa si hay diferencia entre los valores de xprevious y yprevious y los valores actuales de x y y. Si la hay, la variable moved se ajusta a true.
yprevious
Returns: Real
Puede resultar muy útil saber en dónde se encontraba la instancia en el step anterior, cuando se calculan colisiones por ejemplo, por lo que puedes utilizar esta función para obtener estos valores. Normalmente se almacena justo antes del evento step inicial pero la puedes asignar mediante código en cualquier momento, lo que significa que puedes asignarle algún valor propio si es necesario.
if x != xprevious || y != yprevious { moved = true; }
El código anterior revisa si hay diferencia entre los valores de xprevious y yprevious y los valores actuales de x y y. Si la hay, la variable moved se ajusta a true.
xstart
Devuelve: Real
Esta función almacena la posición inicial de la instancia de cuando fue creada por primera vez. También puedes asignarle un valor arbitrario mediante código.
if place_meeting(x, y, obj_spike)
{
score -= 100;
x = xstart;
y = ystart;
}
El código anterior revisa si existe una colisión con la instancia obj_spike y si existe, reduce 100 de score y mueve la instancia a su posición inicial.
ystart
Devuelve: Real
Esta función almacena la posición inicial de la instancia (y) cuando fue creada por primera vez. También puedes asignarle un valor arbitrario mediante código.
if place_meeting(x, y, obj_spike)
{
score -= 100;
x = xstart;
y = ystart;
}
El código anterior revisa si existe una colisión con la instancia obj_spike y si existe, reduce 100 de score y mueve la instancia a su posición inicial.
direction;
Devuelve: Real
Todas las instancias en GameMaker:Studio tienen algunas propiedades "pre-definidas " que podemos usar y modificar para controlar su apariencia y comportamiento. direction es una de estas propiedades y se utiliza para establecer la dirección del movimiento de la instancia cuando esa tiene una velocidad (speed) distinta a 0. Hay que tomar en cuenta que la dirección en GameMaker:Studio es usualmente calculada como 0° correspondiente a derecha, 90° es arriba, 180° es izquierda y 270° es abajo.
if keyboard_check(vk_left) direction += 5;
if keyboard_check(vk_right) direction -= 5;
Este código cambiará la dirección del movimiento de la instancia dependiendo de cuál de las teclas se presiona (izquierda o derecha)
friction
Devuelve: Real
Todas las instancias en GameMaker:Studio tienen algunas propiedades "pre-definidas " que podemos utilizar y modificar para alterar su apariencia y comportamiento. La Fricción es una de estas propiedades y se utiliza para reducir la velocidad de la instancia con el paso del tiempo, siempre y cuando su velocidad (speed) sea mayor que cero. Funciona simplemente al sustraer una cantidad fija de la velocidad en cada paso, hasta que el objeto alcance una velocidad de 0, por lo que si la fricción se fija a un valor de, por ejemplo, 0.1 y la velocidad de la instancia es de 1 (1 pixel por paso), la velocidad disminuirá hasta parar cuando hayan transcurrido 10 pasos. Hay que notar que la fricción se aplica tanto a velocidades positivas como negativas por igual, siempre llevando al objeto a una velocidad de cero después de algún tiempo.
if abs(speed) > 0
{
friction=0.05;
}
else
{
friction=0;
}
El código anterior aplicará una fricción de 0.05 siempre y cuando el valor absoluto de la velocidad sea mayor que 0.
gravity
Devuelve: Real
Todas las instancias en GameMaker:Studio tienen algunas propiedades "pre-definidas " que podemos utilizar y modificar para alterar su apariencia y comportamiento. La gravedad es una de estas propiedades y, cuando se utiliza, aplicará una fuerza continua en la dirección de la gravedad de la instancia, alterando su velocidad. Hay que notar que la gravedad es una fuerza acumulativa y acelerará constantemente al objeto si no se le asigna un tope o límite a la velocidad final de la instancia.
if !place_meeting(x, y + 1, obj_Ground)
{
gravity = 0.01;
}
else
{
gravity = 0;
}
El código anterior aplicará gravedad si no se encuentra alguna instancia de "obj_Ground" en el camino.
gravity_direction;
Devuelve: Real
Todas las instancias en GameMaker:Studio tienen algunas propiedades "pre-definidas" mediante las cuales es posible cambiar su apariencia o comportamiento. gravity_direction es una de estas propiedades, y se utiliza para establecer la dirección de movimiento cuando las instancias tienen una fuerza de gravedad mayor a 0. la dirección en GameMaker:Studio se calcula como: 0° es a la derecha, 90° hacia arriba, 180° a la izquierda y 270° hacia abajo.
if place_meeting(x, y, obj_switch)
{
gravity_direction += 180;
}
El código anterior modificará la dirección de la gravedad si el jugador se encuentra con una instancia de "obj_switch".
hspeed
Devuelve: Real
Todas las instancias en GameMaker:Studio tienen algunas propiedades "pre-definidas " que podemos usar y modificar para controlar su apariencia y comportamiento. >hspeed es una de estas propiedades y se utiliza para definir la velocidad de movimiento horizontal de la instancia en pixeles por step. Así que, una hspeed de 3 significa que cada step la instancia se desplazará 3 pixeles a la derecha (+x) y una hspeed de -3 significa que el movimiento se efectuará hacia la izquierda (-x) en 3 pixeles por step.
if keyboard_check(vk_left) hspeed = -5;
if keyboard_check(vk_right) hspeed = 5;
El código anterior modificará la velocidad horizontal dependiendo de qué teclas se presionen.
vspeed
Devuelve: Real
Todas las instancias en GameMaker:Studio tienen algunas propiedades "pre-definidas " que podemos usar y modificar para cambiar su apariencia y comportamiento. vspeed es una de estas propiedades y se utiliza para definir la velocidad vertical de movimiento de la instancia en pixeles por step. Así que, una vspeed de 3 significa que cada step la instancia se desplazará 3 pixeles hacia abajo (+y) y una vspeed de -3 significa que el movimiento se efectuará hacia arriba (-y) en 3 pixeles por step.
if keyboard_check(vk_up) vspeed = -5;
if keyboard_check(vk_down) vspeed = 5;
El código de arriba modificará la velocidad horizontal dependiendo de qué teclas se presionen.
speed
Devuelve: Real
Todas las instancias en GameMaker:Studio tienen algunas propiedades "pre-definidas " que podemos utilizar y modificar para controlar su apariencia y comportamiento. La velocidad es una de estas propiedades, y define cuantos pixeles se moverá la instancia por step. A diferencia de hspeed y vspeed, speed no tiene una dirección de movimiento asociada a ella, por lo que el movimiento se verá afectado por el valor de la dirección de la instancia, pero puede tener un valor negativo, lo que provocará que la instancia se desplace en dirección contraria a la dirección del objeto. (es decir, direction - 180°).
if keyboard_check(vk_up) speed = 2;
if keyboard_check(vk_left) direction += 5;
if keyboard_check(vk_right) direction -= 5;
El código de arriba utilizará las flechas para establecer la velocidad y dirección de la instancia.
distance_to_object( obj );
Argumento | Descripción |
---|---|
obj | El objeto a revisar. |
Devuelve: Real.
Esta función determina la distancia desde el borde de la caja de colisión de la instancia que ejecuta la función al borde más cercano de la instancia más cercada del objeto especificado. El objeto puede ser un índice de objeto, un identificador de instancia específico así como la palabra clave other. La distancia se devuelve en pixels. Se debe notar que si alguno de los dos objetos no tiene sprite o máscara definida, el resultado será incorrecto.
if distance_to_object(obj_Player) < range
{
canshoot = true;
}
Este código calcula la distancia al objeto player, y si ésta es menor que el valor almacenado en la variable "range", la variable "canshoot" se ajusta a true.
distance_to_point(x, y);
Argumento | Descripción |
---|---|
x | La posición x a revisar. |
y | La posición y a revisar. |
Devuelve: Real
Esta función determina la distancia desde el borde de la caja de colisión de la instancia que ejecuta la función a la posición x/y especificada, con el resultado devuelto en pixeles. Se debe notar que si la instancia que ejecuta el código no tiene sprite o máscara definida, el resultado será incorrecto.
Ejemplo:
if distance_to_point(obj_Player.x, obj_Player.y) < range
{
canshoot = true;
}
El código anterior revisa la distancia al objeto player, y si resulta menor que el valor almacenado en la variable "range" la variable "canshoot" se ajusta a true.
motion_add(dir, speed);
Argumento | Descriptción |
---|---|
dir | La dirección a sumar. |
speed | La velocidad a sumar. |
Devuelve: N/A
Esta función suma a la dirección y velocidad de una instancia, resultando muy útil en colisiones y comportamientos de física sencilla.
var pdir;
pdir = point_direction(other.x, other.y, x, y);
motion_add(pdir, other.speed);
if speed > 8 speed = 8;
El código anterior es llamado en el evento de colisión con otro objeto. El resultado es que a la dirección y velocidad de la instancia ejecutando el código, se le suma (algebráicamente) la dirección y velocidad de la instancia contra la que hay colisión. Por último, se limita la velocidad a un máximo de 8 pixels por step.
motion_set(dir, speed);
Argumento | Descripción |
---|---|
dir | La nueva dirección. |
speed | La nueva velocidad. |
Devuelve: N/A
Esta función establece una nueva dirección de movimiento así como una nueva velocidad para la instancia que ejecuta el código. Se debe notar que de esta manera, no se suma en modo alguno ni a la dirección ni a la velocidad actual de la instancia, sino que hay un cambio a los nuevos valores. Si se pretende sumar a la dirección/velocidad actuales, se debe entonces usar la función motion_add.
if irandom(9) = 1 motion_set(random(360), 1 + random(3));
El código anterior provocará que la instancia cambie de dirección y velocidad a intervalos aleatorios.
move_towards_point( x, y, sp );
Argumento | Descripción |
---|---|
x | La posición x del punto hacia el cual moverse. |
y | La posición y del punto hacia el cual moverse. |
sp | La velocidad a la cual moverse (en pixels por segundo). |
Devuelve: N/A
Esta función le indica a la instancia moverse hacia un punto determinado a cierta velocidad. Ten en cuenta que depende del programador indicar qué hará la instancia una vez que llegue a tal punto, ya que esta función por si misma no detiene el movimiento de la instancia. Esto significa que se pudiera dar el caso en donde se tenga una instancia "temblorosa" debido a que por ejemplo, avanzaría 3 pixeles y excedería la posición x/y del punto final por dos pixeles, entonces se volvería a mover hacia el punto final y volvería a excederse en la posición ahora por 1 pixel y así consecutivamente... Existen distintas maneras en que esto se puede evitar, por ejemplo, usando distance_to_point para saber qué tan lejos se está del punto final antes de moverse.
Nota: Esta función ajusta la velocidad de la instancia, así que incluso cuando se deja de usar el código, la instancia se seguirá moviendo en la dirección anterior, por lo que es necesario reajustar la velocidad de la instancia
speed de vuelta a 0 si se desea detenerla. Consulta el ejemplo más abajo.
if point_distance(x, y, target.x, target.y) > 5
{
move_towards_point(target.x, target.y, 5);
}
else speed = 0;
El código anterior mueve la instancia hacia la posición de la instancia indexada en la variable "target" a una velocidad de 5 pixeles por step. Una vez que llegue a esa posición, la velocidad se ajusta a 0.
move_bounce_all( adv );
Argumento | Descripción |
---|---|
adv | Indica si habilitar (true) o no (false) el rebote avanzado. |
Devuelve: N/A
Mediante esta función se logra que una instancia rebote contra todas las instancias existentes en la habitación, con la única excepción de aquellas que no tengan un sprite o máscara de colisión asignada. También se puede especificar si se usa la detección de colisión precisa, pero para que esto funcione, todas las instancias requieren tener habilitada la opción de máscara precisa, además que esto puede ralentizar el juego si se involucran muchas instancias debido a la cantidad de procesamiento que se requiere. Ésta función normalmente se llama en el evento step de una instancia, pero también se puede usar selectivamente en un evento de colisión, como se ilustra en el siguiente ejemplo.
if other.visible
{
move_bounce_all(false);
}
El código anterior debería colocarse en un evento de colisión. Primero revisa si el objeto es visible, y si lo es, ejecuta la función move_bounce_all(). Es preciso notar que en este caso el rebote es selectivo, es decir, sólo se calculará para esta colisión en específico, en lugar de para cualquier instancia, cada paso.
move_bounce_solid(adv);
Argumento | Descripción |
---|---|
adv | Indica si se activa el rebote avanzado (true) o no (false). |
Devuelve: N/A
Esta función permite ordenarle a una instancia que rebote solamente contra aquellas instancias marcadas como solid dentro de la habitación. También permite indicar el uso de detección de colisiones precisas, pero se debe considerar que esto requiere que todas las instancias tenga la opción de máscara precisa habilitada y que el rendimiento del juego puede decrecer considerablemente si hay muchas instancias involucradas debido a la cantidad de procesamiento que se tendría que realizar. Normalmente esta función iría en el evento STEP de una instancia, pero puede también podría usarse selectivamente en un evento de colisión.
move_bounce_solid(false);
Este código habilita el rebote no preciso contra instancias marcadas como "solid".
move_contact_all(dir, maxdist);
Argumento | Descripción |
---|---|
dir | La dirección en la cual moverse. |
maxdist | Distancia máxima que el objeto puede desplazarse (-1 or 0 a default value of 1000 pixels). |
Devuelve: N/A
Esta función se encarga de mover la instancia que ejecuta el código un número dado de pixeles en la dirección indicada, mientras no se tope con cualquier otra instancia con una máscara de colisión valida. Se puede usar -1 o 0 para indicar una distancia máxima por defecto de 1000 pixeles, de modo que GameMaker:Studio moverá la instancia continuamente hasta 1000 pixeles hasta que se encuentre en contacto con otra.
if !place_meeting(x, y + 1, all)
{
move_contact_all(270, -1);
}
Este código revisa si hay una colisión debajo de la instancia (y+1) y, si no la hay, la moverá hacia abajo hasta que haya avanzado 1000 pixeles o mientras no se produzca una colisión con cualquier otra instancia.
move_contact_solid( dir, maxdist );
Argumento | Descripción |
---|---|
dir | La dirección del movimiento. |
maxdist | Máxima distancia que el objeto puede desplazarse (-1 or 0 indica un valor por defecto de 1000 pixeles). |
Devuelve: N/A
Esta función mueve la instancia un numero de pixeles en una dirección determinada hasta que se encuentre con una instancia cuya propiedad solido este marcada como verdadero. Se puede usar -1 o 0 para indica la máxima distancia por defecto de 1000px, es decir, Game Maker: Studio moverá la instancia continuamente mas allá de 1000 pixeles hasta que este fuera de colisión.
if !place_meeting(x, y + 1, obj_Floor)
{
move_contact_solid(270, -1);
}
El código anterior comprueba si debajo de la instancia hay una colision con "obj_Floor" y si no la hay, entonces la moverá hacia abajo hasta colisionar o haber alcanzado los 1000 pixeles.
move_outside_all(dir, maxdist);
Argumento | Descripción |
---|---|
dir | La dirección del movimiento. |
maxdist | Máxima distancia que el objeto puede desplazarse (-1 or 0 indica un valor por defecto de 1000 pixeles). |
Devuelve: N/A
Mediante esta función es posible indicarle a una instancia que se mueva fuera de una colisión en cualquier dirección y a cualquier cantidad de pixeles por step, con un valor de -1 o 0 la máxima distancia es por defecto de 1000 pixeles. Es decir, Game Maker: Studio moverá la instancia continuamente mas de 1000 pixeles hasta que este fuera de colisión.
if place_meeting(x, y, all)
{
move_outside_all(90, 1);
}
El código de arriba moverá un pixel hacia arriba cualquier instancia que colisione con otra.
move_outside_solid(dir, maxdist);
Argumento | Descripción |
---|---|
dir | La dirección de movimiento. |
maxdist | Máxima distancia que el objeto puede desplazarse (-1 or 0 indica un valor por defecto de 1000 pixeles). |
Devuelve: N/A
Mediante esta función es posible indicarle a una instancia que se mueva fuera de una colisión con otra instancia marcada como "solid" en cualquier dirección y cualquier cantidad de pixeles por cada step. Un valor de -1 o 0 en "maxdist" ajusta la distancia máxima a su valor por defecto de 1000 pixeles, es decir, GameMaker:Studio moverá la instancia continuamente 1000 pixeles hasta que este fuera de una colisión.
if other.solid
{
var pdir;
pdir = point_dirección(other.x, other.y, x, y);
move_outside_solid(pdir, -1);
}
Este código debe estar en un evento de colisión, comprueba si la "otra" instancia esta marcada como "solid". Si es así, entonces moverá la instancia fuera de la colisión.
move_random(hsnap, vsnap);
Argumento | Descripción |
---|---|
hsnap | Valor de enganche horizontal (tamaño en pixeles entre celdas). |
vsnap | Valor de enganche vertical (tamaño en pixeles entre celdas). |
Devuelve: N/A
Mediante esta función puedes colocar la instancia en una posición cualquiera en el room, pero alineada a una cuadricula "invisible". De tal manera que un valor de 32 para hsnap y vsnap moverá la instancia a una posición aleatoria que estará alineada a una cuadricula de cuadros/celdas de 32x32 pixeles. Puedes poner los valores a 1 para obtener cualquier posición en la room.
if keyboard_check(vk_space) move_random(1,1);
Este código moverá la instancia a una posición aleatoria en cualquier lugar del room cuando la tecla de espacio sea presionada.
move_snap( hsnap, vsnap );
Argumento | Descripción |
---|---|
hsnap | Valor de enganche horizontal (tamaño en pixeles entre celdas). |
vsnap | Valor de enganche vertical (tamaño en pixeles entre celdas). |
Devuelve: N/A
Esta función sirve para "enganchar" la instancia en una cuadricula de tamaño dado. La instancia se "abrochará" a la posición mas cercana correspondiente en la cuadricula "invisible", cuyos valores están definidos por hsnap y vsnap.
with (obj_Pieces)
{
if !place_snapped(32, 32)
{
move_snap(32, 32);
}
}
El código anterior verifica todas la instancias de "obj_Pieces" para ver si están alineadas a la cuadricula de 32x32 pixeles, y si no, las mueve hacia la posición mas cercana en la cuadricula.
place_snapped(hsnap, vsnap);
Argumento | Descripción |
---|---|
hsnap | El valor de sujeción a revisar. |
vsnap | El valor de sujeción vertical a revisar. |
Devuelve: Booleano
Esta función se utiliza para revisar si el orgen de una instancia (su posición x e y) está alineado a una rejilla con valores de sujeción hsnap y vsnap especificados por el usuario.
with (obj_Pieces)
{
if !place_snapped(32, 32)
{
move_snap(32, 32);
}
}
Éste código revisa todas las instancias del objeto "obj_Pieces" para ver si están alineadas a una rejilla de 32x32 pixeles, y si no lo están, las alínea a la posición más cercana en la rejilla.
move_wrap(hor, vert, margin);
Argumento | Descripción |
---|---|
hor | Indica si se debe reinsertar horizontalmente (true) o no (false). |
vert | Indica si se debe reinsertar verticalmente (true) o no (false). |
margin | Qué tan lejos de la orilla del room debe estar el objeto (en pixeles) para iniciar la reinserción. |
Devuelve: No aplica
Esta función reinserta automáticamente una instacia que ha abandonado la habitación por un extremo (horizontal, vertical o ambos). Se puede especificar un margen fuera de los límites de la habitación para que esto ocurra, y que cuando la instancia se halla desplazado más allá de ese margen, GameMaker:Studio automáticamente la reinsertará de regreso a la habitación en el lado opuesto. Esta función se usa comúnmente en el evento
Outside Room.
move_wrap(true, false, sprite_width);
Esto hará que la instancia se reinserte horizontalmente, más no verticalmente, cuando al salir de la habitación supere la distancia igual a la anchura de su propio sprite.
mp_linear_step(xgoal, ygoal, stepsize, checkall);
Argumento | Descripción |
---|---|
xgoal | La posición x objetivo. |
ygoal | La posición y objetivo. |
stepsize | La velocidad a la que la instancia se mueve en pixeles por step. |
checkall | Indica si se revisan colisiones contra todas las instancias (true) o sólo contra las sólidas (false). |
Devuelve: Booleano
Mediante esta función se le ordena a una instancia dar un "paso" hacia un punto en específico, dado por los valores "xgoal" y "ygoal". El tamaño de los pasos (cuántos pixeles avanza la instancia em cada step) está indicado por el argumento "stepsize", y si la instancia ya está en la posición objetivo, se detendrá y no se moverá más, al contrario de otras funciones más simples como
move_towards_point. El valor de stepsize también es la distancia "hacia adelante" que el objeto revisará en cada paso en busca de una colisión, además de que se puede escoger si la instancia se detiene al colisionar con cualquier instancia o sólo aquellas que están marcadas como sólidas.
Nota: Esta función no trata de desviarse si se encuentra con un obstáculo, símplemente falla y deja de moverse. la función devuleve si ha alcanzado su meta (true) o si ha fallado (false).
if mp_linear_step(mouse_x, mouse_y, 5, 0)
{
instance_create(x,y,obj_Explosion);
instance_destroy();
}
El código anterior moverá al objeto hacia el puntero a una velocidad de 5 pixeles por step. Una vez que llegue a la posición del puntero, creará un objeto "obj_Explosion" y se autodestruirá.
mp_linear_step_object(xgoal, ygoal, stepsize, obj);
Argumento | Descripción |
---|---|
xgoal | The posición x objetivo. |
ygoal | The posición y objetivo. |
stepsize | la velocidad a la que la instancia se moverá (en pixeles por step). |
obj | El objeto que podría bloquear el path/ruta. Puede ser un índice de objeto, un id de instancia o la palabra reservada, all |
Devuelve: Booleano.
Esta función le indica a una instancia moverse en "pasos" hacia un punto en específico, dado por los valores xgoal y ygoal. El argumento stepsize corresponde al tamaño del paso (cuántos pixeles se debe mover la instancia en cada paso). Si la instancia ya está en la posición final, se detendrá automáticamente, y no se moverá más, a diferencia de otras funciones, como move_towards_point. stepsize también indica la distancia "hacia adelante" en la que el objeto irá revisando colisiones en cada paso. La función también permite definir si la instancia se detiene al colisionar con un objeto o instancia en específico.
if mp_linear_step_object(mouse_x, mouse_y, 5, obj_Wall)
{
instance_create(x,y,obj_Explosion);
instance_destroy();
}
El código anterior moverá al objeto hacia la posición del puntero del ratón a una velocidad de 5 pixeles per step, a la vez que revisa colisiones contra el objeto "obj_Wall". Una vez que llegue a la posición del puntero, creará un objeto "obj_Explosion" y se autodestruirá.
mp_linear_path(path, xgoal, ygoal, stepsize, checkall);
Argumento | Descripción |
---|---|
path | El índice del path a usar. |
xgoal | La posición x objetivo. |
ygoal | La posición y objetivo. |
stepsize | La velocidad a la que la instancia se mueve, en pixeles por step. |
checkall | Indica si se revisan colisiones contra todas las instancias (true) o sólo contra las sólidas (false). |
Devuelve: Booleano.
Esta función calcula una ruta en línea recta de la posición actual de la instancia al punto especificado por los valores "xgoal" y "ygoal". El path indicado debe de existir al momento de llamar a la función y será sobreescrito por el nuevo path. La función devolverá true si se encontró una nueva ruta completa o false si no. En el caso de que la función devuelva false, el path de todas maneras se genera, pero sólamente llegará hasta la posición donde ocurra el bloqueo.
Nota: Esta función no mueve la instancia, únicamente calcula el path, por lo que se deben usar las funciones Path para iniciar el movimiento.
if mp_linear_path(path, obj_Player.x, obj_Player.y, 2, 0) path_start(path, 2, 0, 0);
Este código revisa si existe una ruta en línea recta y libre de colisión desde la actual posición del objeto que ejecuta el código a la posición del objeto "obj_Player". Si existe, entonces se inicia el path.
mp_linear_path_object(path, xgoal, ygoal, stepsize, obj);
Argumento | Descripción |
---|---|
path | El índice del path a usar. |
xgoal | La posición x objetivo. |
ygoal | La posición y objetivo. |
stepsize | La velocidad a la que la instancia se mueve, en pixeles por step. |
obj | El objeto que podría bloquear el path. Puede ser el índice de un objeto, un id de instancia o la palabra reservada all |
Devuelve: Booleano
Esta función calcula una ruta en línea recta de la posición actual de la instancia al punto especificado por los valores "xgoal" y "ygoal". El path indicado debe de existir al momento de llamar a la función y será sobreescrito por el nuevo path. La función devolverá true si se encontró una nueva ruta o false si no. Una ruta válida sólo se encuentra si no se detectó colisión con el objeto especificado (o alguna de sus instancias) y en el caso de que la función devuelve false, el path de todas maneras se genera, pero sólamente llegará hasta la posición donde ocurre el bloqueo.
Nota: Esta función no mueve la instancia, únicamente calcula el path, por lo que se deben usar las funciones Path para iniciar el movimiento.
if mp_linear_path_object(path, mouse_x, mouse_y, 4, obj_Wall) path_start(path, 4, 0, 0);
Este código revisa colisiones contra el objeto "obj_Wall" a lo largo de un path entre el objeto ejecutando el código y la posición x/y position del ratón. Si no hay colisión y se calcula una ruta completa, entonces se comenzará a mover el objeto a lo largo del path generado.
mp_potential_settings(maxrot, rotstep, ahead, onspot)
Argumento | Descripción |
---|---|
maxrot | El número de grados a cualquier lado de la dirección actual que la instancia puede girar en un step |
rotstep | El número de grados a cualquier lado de la dirección actual en que la instancia puede revisar colisiones (una especie de 'ángulo de visión') |
ahead | El número de pasos hacia adelante que la instancia puede revisar en busca de una colisión. Usar un valor grande resulta más lento que usar uno corto. |
onspot | Define si la instancia puede girar(true) sobre si misma cuando no se encuentra una ruta. False indica que no puede girar |
Devuelve: N/D.
las Funciones mp_potential_ trabajan en base a ciertos parámetros que pueden ajustarse gracias a esta función. En general, el método funciona así: Primero se trata de mover directo hacia el punto objetivo, considerando el número de pasos hacia adelante dado por el parámetro "ahead" (cuyo valor por defecto es 3). Si este número se reduce, lo que sucede es que la instancia comenzará a cambiar su dirección después, pues no puede "ver" tan lejos, y si se incrementa, el resultado es que comenzará a cambiar de dirección antes. Si esta revisión conduce a una colisión, entonces la función comienza a "mirar" hacia la izquierda o derecha de la dirección ideal en línea recta. Esto se realiza por pasos, según el tamaño del argumento "rotstep" (cuyo valor por defecto es 10). Reducir "rotstep", le dará a la instancia más posibilidades de movimiento, pero será un proceso más lento porque demanda más trabajo del procesador.
La instancia tienen una dirección actual de movimiento, y "maxrot" (cuyo valor por defecto es igual a 30) indica qué tanto se permite variar esta dirección hacia cualquier lado en un step. Esto quiere decir que por ejemplo, incluso si fuera posible moverse en línea recta hacia el punto de destino, sólo se avanzará si la trayectoria en línea recta no viola el cambio máximo de dirección permitido. Si se especifica un valor grande para maxrot, entonces la instancia podrá cambiar mucho de dirección en cada paso, y esto hará más fácil encontrar un path corto, pero el path será menos natural. Si usa un valor pequeño para maxrot, el path será más suave, pero podría tomar desviaciones más largas (e incluso, en ocasiones, fallar al tratar de encontrar la meta).
Por último, si no se puede realizar ningún paso (avanzar), el comportamiento depende del valor del parámetro "onspot". Si onspot es true (valor por defecto), entonces la instancia girará sobre si misma según el valor de "maxrot" y si es false no se moverá en absoluto. Ajustarlo a false puede resultar útil en coches, pero reduce la probabilidad de encontrar una ruta/path.
mp_potential_settings(45, 5, 5, 0)
El código anterior ajustará las funciones mp_potential_ para usar la siguiente configuración: La instancia puede "mirar" hacia adelante cinco pasos, cambiar de dirección 45 grados con cada paso, mirar 5 degrees a ambos lados de la dirección actual en busca de un obstáculo y no rotar sobre su eje si se produce una colisión.
mp_potential_step(xgoal, ygoal, stepsize, checkall)
Argumento | Descripción |
---|---|
xgoal | La posición x del destino. |
ygoal | La posición y del destino. |
stepsize | La velocidad a la cual se moueve la instancia en píxeles por step. |
checkall | Indica si se deben comprobar todas las instancias (true) o sólo las sólidas (false). |
Devuelve: Booleano.
Esta función permite a la instancia avanzar hacia una posición particular definida por los parámetros xgoal/ygoal, a la vez que intenta evitar obstáculos. Cuando la instancia se tope con alguna instancia sólida (o cualquier instancia, si "checkall" es true) cambiará su dirección tratando de evitar esa instancia (rodeándola). El funcionamiento no está garantizado del todo, pero en la mayoría de casos simples moverá de forma eficaz la instancia hacia su destino. La función devuelve si se alcanzó o no la meta.
if instance_exists(obj_Enemy)
{
var inst;
inst = instance_nearest(x, y, obj_Enemy);
mp_potential_step(inst.x, inst.y, 5, false);
}
El código anterior primero verifica si existen instancias de "obj_Enemy" en la room. Si las hay, entonces busca la más cercana y almacena su id en la variable "inst". Esta variable es entonces usada para hacer que mp_potential_step mueva la instancia que ejecuta el código hacia la posición x/y del objeto obj_Enemy encontrado, a una velocidad de 5 píxeles por step, mientras trata de esquivar sólo las instancias marcadas como sólidas.
mp_potential_step_object(xgoal, ygoal, stepsize, obj)
Argumento | Descripción |
---|---|
xgoal | La posición x final. |
ygoal | La posición y final. |
stepsize | La velocidad a la cual avanzará la instancia (en píxeles por step). |
obj | El objeto que bloquea la ruta de la instancia ejecutando esta función. Puede ser un índice de objeto, un id de instancia o la palabra reservada all. |
Devuelve: Booleano.
Esta función permite que la instancia avance hacia una posición particular definida por los parámetros xgoal/ygoal, a la vez que intenta evitar obstáculos. Cuando la instancia encuentre una instancia del objeto especificado por el argumento "obj", cambiará su dirección tratando de evitarla (rodeándola). El funcionamiento no está garantizado del todo, pero en la mayoría de casos simples, la instancia se moverá de forma eficaz hacia su destino. La función devuelve si se alcanzó o no la meta.
if instance_exists(obj_Enemy)
{
var inst;
inst = instance_nearest(x, y, obj_Enemy);
mp_potential_step_object(inst.x, inst.y, 5, obj_Wall);
}
El código anterior primero verifica si existen instancias de "obj_Enemy" en la room. Si las hay, entonces busca la más cercana y almacena su id en la variable "inst". Esta variable se usa para indicarle a la función mp_potential_step_object que mueva la instancia que ejecuta el código hacia la posición x/y del enemigo encontrado a una velocidad de 5 pixeles por paso, mientras se evitan instancias del objeto "obj_Wall".
mp_potential_path(path, xgoal, ygoal, stepsize, factor, checkall)
Argumento | Descripción |
---|---|
path | Índice del path que usará esta función |
xgoal | Posición de destino X. |
ygoal | Posición de destino Y. |
stepsize | Velocidad a la que se moverá la instancia en pixeles por step. |
factor | Se usa para prevenir un ciclo infinito. Debe ser mayor a 1. Lee la descripción para más detalles. |
checkall | Indica si se revisan todas las instancias (true) o solamente las marcadas como sólidas(false). |
Devuelve: Booleano.
Esta función calcula una ruta (path) para la instancia, desde su posición actual y orientación a la posición indicada por los argumentos xgoal,ygoal. Utiliza el tamaño de paso indicado mientras intenta evitar colisiones ya sea contra todas las instancias o sólo aquellas marcadas como sólidas. Al igual que la función mp_potential_step se trabaja en base a pasos en potencia, y la manera de calcular la ruta se puede modificar mediante la función mp_potential_settings. El path indicado debe de existir de antemano y será reescrito por el nuevo path recien calculado. Esta función devuelve si se pudo encontrar una ruta (true) o no (false).
Para evitar que la función continúe calculando rutas indefinidamente se necesita proporcionar un factor mayor a 1 - la función se detendrá y reportará un error si no puede encontrar una ruta de longitud menor a la distancia I-D (inicio - destino) multiplicada por el factor. Un factor de 4 generalmente funciona bien, pero si se espera tomar desviaciones largas, se puede aumentar. Si la función falla y no encuentra un path, de todas maneras se crea una nueva ruta que vaya en una dirección aproximada al punto de destino, pero sin llegar a el de manera exacta.
Note: Esta función no mueve la instancia, sólo define una ruta, por lo que se debe usar las Funciones Path para iniciar el movimiento.
path = path_add();
mp_potential_path(path, obj_Player.x, obj_Player.y, 3, 4, 0);
path_start(path, 3, 0, 0);
Este código crea un nuevo recurso path y guarda su índice en la variable "path". Luego, mediante la función mp_potential_path genera un path entre el objeto ejecutando este código y el objeto "obj_Player", revisando colisiones contra todas las instancias en la habitación. Finalmente, inicia el movimiento del objeto a lo largo del path, aun si la función ha fallado al devolver una ruta completa hacia "obj_Player".
mp_potential_path_object(path, xgoal, ygoal, stepsize, factor, obj)
Argumento | Descripción | path | Índice del path que usará esta función |
---|---|
xgoal | Posición de destino X |
ygoal | Posición de destino Y. |
stepsize | >Velocidad a la que se moverá la instancia, en pixeles por step. |
factor | Se usa para prevenir un ciclo infinito. Debe ser mayor a 1. Lee la descripción para más detalles. |
obj | El objeto que podría bloquear el path. Puede ser el índice de un objeto, un id de instancia o la palabra reservada all |
Devuelve: Booleano.
Esta función calcula una ruta (path) para la instancia, desde su posición actual y orientación a la posición indicada por los argumentos xgoal,ygoal. Utiliza el tamaño de paso indicado mientras intenta evitar colisiones con instancias del objeto especificado por el argumento "obj". Al igual que la función mp_potential_step se trabaja en base a pasos en potencia, y la manera de calcular la ruta se puede modificar mediante la función mp_potential_settings. El path indicado debe de existir de antemano y será reescrito por el nuevo path recien calculado. Esta función devuelve si se pudo encontrar una ruta (true) o no (false).
Para evitar que la función continúe calculando rutas indefinidamente se necesita proporcionar un factor mayor a 1 - la función se detendrá y reportará un error si no puede encontrar una ruta de longitud menor a la distancia I-D (inicio - destino) multiplicada por el factor. Un factor de 4 generalmente funciona bien, pero si se espera tomar desviaciones largas, se puede aumentar. Si la función falla y no encuentra un path, de todas maneras se crea una nueva ruta que vaya en una dirección aproximada al punto de destino, pero sin llegar a el de manera exacta.
Note: Esta función no mueve la instancia, sólo define una ruta, por lo que se debe usar las Funciones Path para iniciar el movimiento.
path = path_add();
mp_potential_path_object(path, obj_Player.x, obj_Player.y, 3, 4, obj_Wall);
path_start(path, 3, 0, 0);
Este código crea un nuevo recurso path y guarda su índice en la variable "path". Luego, mediante la función mp_potential_path_object genera un path entre el objeto ejecutando este código y el objeto "obj_Player", revisando colisiones contra el objeto "obj_Wall". Finalmente, inicia el movimiento del objeto a lo largo del path, aun si la función ha fallado al devolver una ruta completa hacia "obj_Player".
mp_grid_create(xstart, ystart, hcells, vcells, cellwidth, cellheight):
Argumento | Descripción |
---|---|
xstart | Coordenada x inicial de la cuadrícula mp_grid en la habitación. |
ystart | Coordenada y inicial de la cuadrícula mp_grid en la habitación. |
hcells | Número de celdas horizontales que la cuadrícula contendrá. |
vcells | Número de celdas verticales que la cuadrícula contendrá. |
cellwidth | El ancho (en pixeles) de cada celda en la cuadrícula mp_grid. |
cellheight | la altura (en pixeles) de cada celda en la cuadrícula mp_grid. |
Devuelve: Real.
Por medio de esta función es posible crear una cuadrícula mp_grid para las funciones de planeación de movimiento. Devuelve un índice que debe ser usado en las demás llamadas a funciones mp_grid. Las coordenadas x e y indican la posición de la esquina superior derecha de la rejilla. Los parámetros "hcells" y "vcells" indican el número de celdas horizontales y verticales que formarán la rejilla/cuadrícula. Los últimos dos parámetros indican el tamaño de las celdas en pixeles. Se pueden crear y mantener múltiples cuadrículas al mismo tiempo si es que se necesitan para distintas cosas, pero se recomienda usarlas con moderación debido a que se trata de funciones complejas, y entre más se usen y entre mayor sea la resolución de la celda, más lento podría ejecutarse el juego en algún punto.
globalvar grid;
grid = mp_grid_create(0, 0, room_width / 32, room_height /32, 32, 32)
El código del ejemplo crea una variable global "grid", entonces genera una estructura mp_grid y asigna ese índice a esa variable para ser usada en las subsecuentes llamadas a funciones mp_grid. La cuadrícula cubre la habitación enetera, con una resolución de celda de 32X32 pixeles. Esto significa que, por ejemplo, en una room de 640X480 la rejilla contendría 300 celdas: 20 horizontales y 15 verticales.
mp_grid_destroy(id);
Argumento | Descripción |
---|---|
id | Índice de la rejilla mp_grid a destruír. |
Devuelve: N/A.
La utilidad de esta función es destruír la rejilla mp_grid indicada, liberando el espacio en memoria que ésta ocupaba. Es esencial que esta función se llame solamente cuando la la rejilla mp_grid ya no sea necesaria, o se podría producir una fuga de memoria, lo que provocaría que el juego se ralentizaría y eventualmente fallaría.
NOTA: ¡Destruír una rejilla mp_grid cuando todavía hay instancias usándola resultará en un error!
if timer = 0
{
mp_grid_destroy(grid);
room_goto(rm_Menu);
}
El código anterior destruirá la cuadrícula mp_grid indexada en la variable "grid" si la variable "timer" es igual a 0, y luego se pasará a otro room.
mp_grid_path(id, path, xstart, ystart, xgoal, ygoal, allowdiag);
Argumento | Descripción |
---|---|
id | Índice de la rejilla mp_grid a usar. |
path | Índice del path que la función usará. |
x start | Coordenada x inicial del nuevo path. |
y start | Coordenada x inicial del nuevo path. |
xgoal | Coordenada x final de la nueva ruta. |
ygoal | Coordenada x final de la nueva ruta. |
allowdiag | Indica si se permite movimiento en diagonal (true) en lugar de sólo horizontal o vertical(false). |
Devuelve: Boolean.
Esta función permite crar una ruta (path) comprendida entre un punto de inicio y un punto final usando una cuadícula mp_grid previamente definida, evitando cualquier obstáculo que se haya agregado anteriormente a la rejilla. Los argumentos xstart y ystart indican el inicio del path en coordenadas de rejilla, mientras que los argumentos xgoal y ygoal indican el destino. Se puede elegir sólo movimiento horizontal/vertical, o permitir movimientos en diagonal especificando true en el argumento final. La función devuelve true, si tuvo éxito encontrando un path, o false, si no encontró ninguno, a la vez que ajusta el path elegido. En la siguiente imagen se ilustra todo este comportamiento:
Como se puede ver, los objetos "tubulares" se han agregado a la cuadrícula, lo que significa que cualquier path debe de rodearlos. En la imagen hay dos paths creados, el verde incluye movimiento en diagonal, y el rojo sólo movimiento vertical/horizontal. La diferencia entre los dos resulta basta obvia, ya que el path verde muestra ser más "elegante" y directo, pero la efectividad depende de qué uso se le quiera dar a cada ruta. Es muy importante notar que el path
es independiente de la instancia actual -es una ruta a través de la cuadrícula, no un path para una instancia en específico-, aun cuando una instancia en específico puediera contener la variable donde está indexado el path. Es posible que se requiera depurar estas rutas para ver cómo están hechas y cómo interactúan con el ambiente, en tal caso se debe usar la función
draw_path.
NOTA: El path debe haber sido creado previamente (mediante código, como se explica en path_add o como recurso) y será reemplazado por el path generado por esta función.
globalvar grid;
grid = mp_grid_create(0, 0, room_width div 32, room_height div 32, 32, 32);
mp_grid_add_instances(grid, obj_wall, false);
with (obj_Enemy)
{
path = path_add();
if mp_grid_path(grid, path, x, y, obj_Player.x, obj_Player.y, 1)
{
path_start(path, 0, 3, 0);
}
}
El código del ejemplo crea una variable "grid", a continuación crea una cuadrícula mp_grid y asigna su índice (id) a "grid", la cual será usada en las siguientes llamadas mp_grid. Luego agrega todas las instancias del objeto "obj_Wall" a la cuadrícula, antes de hacer que todas las instancias de "obj_Enemy" creen un path y usen la función mp_grid_path para calcular una ruta que va de su posición a la posición del objeto "obj_Player". Si la ruta existe, entonces la instancia enemiga comienza a moverse a lo largo del path.
mp_grid_add_cell(id, h, v);
Argumento | Descripción |
---|---|
id | Índice de de la rejilla mp_grid a usar. |
h | Posición horizontal de la celda en la rejilla. |
v | Posición vertical de la celda en la rejilla. |
Devuelve: N/A
Esta función permite marcar celdas individuales en la rejilla mp_grid como "prohibidas", lo que significa que las funciones de búsqueda de ruta nunca las cruzarán. En una habitación normalmente se trabaja con coordenadas de habitación x/y y no con coordenadas de rejilla mp_grid, así que vamos a considerar que nos muestra cómo se relacionan ambos tipos de coordenadas:
Como se puede ver, la rejilla mp_grid está compuesta de una serie de celdas (siendo el comenzando la celda 0,0, en la esquina superior derecha), y cuando esta rejilla se coloca sobre la habitación, hay una relación directa entre las coordenadas del room (que también comienzan en 0,0, en la misma esquina) y las celdas de la rejilla. En la imagen, la instancia en la posición (260, 130) concuerda con la celda (8,4)de la rejilla. Se puede calcular la celda exacta en la que determinada posición "cae", al dividir el número entre la resolución de la rejilla para después hacer un redondeo hacia abajo, o, (si se están usando rejillas con resoluciones potencias de dos, como 8, 16, 32, etc) se pueden usar operadores bit a bit (esto es más rápido). El siguiente ejemplo muestra ambos métodos.
with (obj_Wall)
{
mp_grid_add_cell(grid, floor(x / 32), floor(y / 32));
}
with (obj_Door)
{
mp_grid_add_cell(grid, x>>5, y>>5);
}
El código anterior hace que todos los objetos "obj_Wall" y "obj_Door" agreguen su posición de celda equivalente a la rejilla indexada en la variable "grid". En la primera parte del ejemplo, esto se hace al tomar las coordenas x/y del objeto y dividirlas entre la resolución de la rejilla (usando floor para mantener los valores enteros). En la segunda parte (ya que la resolución de la rejilla es una potencia de 2), esto se hace aplicando un desplazamiento lógico de bit a las coordenadas x/y, 5 posiciones A LA DERECHA.
*NOTA (Wikipedia): En números enteros sin signo, el desplazamiento lógico hacia la izquierda equivale a una multiplicación por 2 y el desplazamiento lógico hacia la derecha equivale a una división por 2. En la división (desplazamiento hacia la derecha), se pierde el bit menos significativo, dando como resultado un truncamiento del resultado (redondeo hacia abajo, hacia menos infinito). Así, 6 / 2 es igual a 3, pero 7 / 2 es igual a 3,5, pero el 0,5 se pierde quedando el resultado en 3.
*http://es.wikipedia.org/wiki/Operador_a_nivel_de_bits#Desplazamiento_l.C3.B3gico
mp_grid_add_instances(id, obj, prec);
Argumento | Descripción |
---|---|
id | Índice de de la rejilla mp_grid a usar. |
h | Índice de objeto o id de instancia de las instancias que serán agregadas a la rejilla mp_grid |
prec | Usar colisión precisa (true = lento) o la caja de colisión (false = rápido). |
Devuelve: N/A
Esta función usa la máscara de colisión del sprite o el índice de máscara de la instancia que ejecuta el código para marcar la celda (o celdas) como prohibidas, lo que significa que las funciones de búsqueda de ruta nunca cruzarán a través de éstas. Se puede especificar si se considera usar colisiones precisas o no, de lo que dependerá qué celdas se marcarán como prohibidas. La siguiente imagen ilustra este comportamiento:
Las dos instancias han sido agregadas a la rejilla mp_grid usando la función mp_grid_add_instances() con un modo de colision precisa (true). La instancia de color verde sólo ha marcado como prohibidas las celdas que toca, debido a que su máscara de colisión ha sido ajustada al modo preciso. Sin embargo, la segunda instancia ha marcado adicionalmente otras celdas con las que pareciera no entrar en contacto. Esto se debe a que la máscara del sprite no está marcada como precisa, resultando en que a pesar de que la función está usando la colisión precisa, sólo la caja de colisión será considerada. Lo mismo ocurriría si el argumento "precise" de la función se hubiera ajustado a false (incluso instancias con máscara de colisión precisa serían agregadas a la rejilla basándose en sus cajas de colisión).
mp_grid_add_instances(grid, obj_Wall, 1);
Esté cpodigo agrega instancias del objeto "obj_Wall" a la rejilla indexada en la variable "grid" usado la máscara de colisión precisa en lugar de la cajade colisión.
mp_grid_add_rectangle(id, x1, y1, x2, y2);
Argumento | Descripción |
---|---|
id | Ínidice de la rejilla mp_grid a usar |
x1 | La coordenada x del lado izquierdo del rectángulo. |
y1 | La coordenada y del lado superior del rectángulo. |
x2 | La coordenada x del lado derecho del rectángulo. |
y2 | La coordenada y del lado inferior del rectángulo. |
Devuelve: N/A
El rectángulo definifo por (50, 90) y (200, 180) marca como prohibidas todas las celdas equivalentes que entran en contacto con él.
mp_grid_add_rectangle(grid, 0, 0, 100, 200);
Este código marca como prohibidas todas las celdas de la rejilla mp_grid indexada por la variable "grid" que se ubiquen en o "toquen" el área (0,0) a (100,200).
mp_grid_get_cell(id, x, y);
Argumento | Descripción |
---|---|
id | Índice de la rejilla mp_grid a usar |
x1 | La coordenada x a revisar en la rejilla (no en la habitación). |
y1 | La coordenada y coordinate a revisar en la rejilla (no en la habitación). |
Devuelve: Real
Esta función permite revisar cualquier celda de la rejilla para determinar si ha sido marcada como ocupada o no. Si la celda está ocupada, o la posición que se revisa se encuentra fuera de los límites de la rejilla, entonces la función devolverá -1, de lo contrario devolverá 0.
if mp_grid_get_cell(grid, mouse_x div 16, mouse_y div 16) == -1
{
image_blend = c_red;
}
else
{
image_blend = c_lime;
}
El código anterior revisará la celda en la cuadrícula que corresponda a la posición del ratón y, si está ocupada ajustará la variable image_blend a rojo, y si no está ocupada, la ajusta a verde.
mp_grid_clear_all(id);
Argumento | Descripción |
---|---|
id | Índice de de la cuadrícula mp_grid a usar. |
Devuelve: Booleano.
Con esta función es posible borrar todas las celdas marcacas como "prohibidas" de una cuadrícula mp_grid.
if !instance_exists(obj_Player) mp_grid_clear_all(grid);
Este código limpia la cuadrícula indexada por la variable "grid", marcando todas sus celdas como libres, si es que ya no existiera ninguna instancia del objeto "obj_Player" en el room.
mp_grid_clear_cell(id, h, v);
Argumento | Descripción |
---|---|
id | Índice de de la cuadrícula mp_grid a usar. |
h | Posición horizontal de la celda a limpiar. |
v | Posición vertical de la celda a limpiar. |
Devuelve: Booleano.
Esta función permite limpiar (marcar como libre) una celda específica en una rejilla mp_grid. La posición de las celdas no es determinada mediante coordenadas de habitación, sino como coordenadas de una cuadrícula, donde (0,0) equivale a lacelda de la esquina superior izquierda en la rejilla. Esto significa que para limpiar una celda en una posición específica en la habitación, debemos "traducir" las coordenadas x/y a coordenadas de celda, dividiendo aquellas entre la resolución de la rejilla mp_grid. El ejemplo debajo de estas líneas muestra cómo se hace.
with (obj_Box)
{
mp_grid_clear_cell(grid, floor(x / 32), floor(y /32));
instance_destroy();
}
Este código hace que todas las instancias del objeto "obj_Box" se destruyan y que marquen las celdas de la cuadrícula mp_grid indexada por la variable "grid" que ocupaban, como libres. La celda apropiada se encuentra tomando la coordenada x/y de la instancia y dividiéndola entre la resolución de la cuadrícula (recurriendo a floor para mantener los valores como enteros).
mp_grid_clear_rectangle(id, x1, y1, x2, y2);
Argumento | Descripción |
---|---|
id | Índice de la rejilla mp_grid a usar |
x1 | Coordenada x de la esquina superior izquierda del rectángulo a revisar. |
y1 | Coordenada y de la esquina superior derecha del rectángulo a revisar. |
x2 | Coordenada x del lado derecho del rectángulo a revisar. |
y2 | Coordenada y del lado inferior del rectángulo a revisar. |
Devuelve: Booleano.
Esta función permite definir un área en coordenadas de room, la cual limpiará las celdas correspondientes en la rejilla mp_grid indicada. Es suficiente que una celda entre parcialmente dentro de la región rectangular definida para que sea limpiada.
mp_grid_clear_rectangle(grid, 0, 0, 100, 200);
El código anterior marca como libres todas las celdas de la rejilla indexada en la variable "grid" que queden dentro del área (0, 0) a (100, 200).
mp_grid_to_ds_grid(source, destination);
Argumento | Descripción |
---|---|
source | Índice de la estructura mp_grid a copiar |
destination | Índice de la estructura ds_grid en la que se copiarán los datos. |
Devuelve: Booleano.
Esta función permite copiar una rejilla de planeación de movimiento a una estructura de datos DS Grid. Idealmente, la estructura DS grid debería tener el mismo tamaño que la rejilla MP, aunque en realidad no tiene por qué ser así (si la ds_grid es menor, se perderán datos, y si es mayor, las celdas extras restantes contendrán ceros). Las celdas marcadas como ocupadas en la rejilla mp ahora, en la rejilla DS grid, contendrán un valor de -1 y las celdas libres contendrán un 0.
motion_grid = ds_grid_create(room_width / 32, room_height / 32);
mp_grid_to_ds_grid(mp_grid, motion_grid);
El código de arriba creará una estructura DS grid nueva y entonces copiará los datos de la rejilla MP contenida en la variable "mp_grid" en la nueva DS grid.
mp_grid_draw(id);
Argumento | Descripción |
---|---|
id | Índice de la cuadrícula mp_grid a dibujar. |
Devuelve: Booleano.
Esta función dibuja la cuadrícula m_grid indicada, marcando las celdas libres en color verde y las prohibidas en rojo. Esta función es muy útil como herramienta de depuración, pero se debe notar que resulta muy lenta, y sólo funcionará si se usa en el evento draw de la instancia.
draw_set_alpha(0.3);
mp_grid_draw(grid);
draw_set_alpha(1);
Este código dibuja la cuadrícula mp_grid indexada en la variable "grid" en modo semitransparente (pero sólo si la instancia que ejecuta el código tiene una profundidad menor que el resto).
mp_grid_to_ds_grid(source, destination);
Argumento | Descripción |
---|---|
source | Índice de la rejilla mp_grid a usar |
destination | Índice de la rejilla ds_grid that en la que se copiarán los datos |
Devuelve: Booleano.
Mediante esta función es posible copiar la rejilla MP especificada a una rejilla DS. La rejilla DS debería ser del mismo tamaño que la rejilla MP grid, aunque no es obligatorio que sea así (se perderán datos en caso de que sea menor, y si fuera mayor, las celdas extras contendrán 0). The DS grid cells will contain the value -1 if the MP grid cell was flagged as occupied, or it will be 0 if not.
motion_grid = ds_grid_create(room_width / 32, room_height / 32);
mp_grid_to_ds_grid(mp_grid, motion_grid);
El código anterior crea una nueva rejilla DS y posteriormente copia los datos de la rejilla MP (contenida en la variable "mp_grid") a la nueva rejilla DS.