Regular Ángulos

Muchas veces se tienen variables que contienen ángulos para diferentes cálculos, pero cuando los valores que nos devuelven son mayores a 360 o menores a 0, a veces traen ciertos problemas a la hora de usarlos, por lo que se tienen que regular de alguna forma, para saber en qué ángulo cae si le damos vueltas de 360º. Lo más común es usar este procedimiento:

1
2
3
4
while (angulo < 0)
angulo += 360;
while (angulo > 360)
angulo -= 360;

Es efectivo,  pero no lo más eficiente.

1
2
///regular_angulo(angulo);
return (argument[0] mod 360 + 360) mod 360;

Este script permite mantener el valor entre 0 y 359 sin necesidad de recurrir a un ciclo, incluso aceptando valores negativos, pero sin dejar de devolver el ángulo correcto al que corresponda el valor ingresado.

 

Pueden descargar el archivo GML para importarlo a sus proyectos pinchando aquí.

Funciones Trigonométricas

Cada vez que empiezo un proyecto nuevo en donde necesito usar las funciones trigonométricas para ciertos cálculos, siempre aprovecho de usar mi pack de funciones que contienen ya las conversiones de radianes a grados, además de invertir el eje Y para poder usarlas con los ángulos de Game Maker.

 

Seno

1
2
///seno(angulo);
return sin(degtorad(-argument[0]));

Coseno

1
2
///coseno(angulo);
return cos(degtorad(argument[0]));

Tangente

1
2
///tangente(angulo);
return tan(degtorad(-argument[0]));

ArcoSeno

1
2
///arcoseno(valor);
return -radtodeg(arcsin(argument[0]));

ArcoCoseno

1
2
///arcocoseno(valor);
return radtodeg(arccos(argument[0]));

ArcoTangente

1
2
///arcotangente(valor);
return -radtodeg(arctan(argument[0]));

 

Pueden descargar el archivo GML para importarlos a sus proyectos pinchando aquí.

Acción en varias direcciones con 1 sólo sprite

Este script nos entrega la facilidad de usar tan solo 1 sprite para cada acción de un personaje (ej.: caminar, atacar, morir, etc.), conteniendo todas las direcciones en las que se moverá.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
///draw_sprite_dir(direcciones);
var final_animacion = false;
var direcciones = argument[0];
var angulos = floor(direction / (360 / direcciones));
var subimagenes = image_number / direcciones;
var index_minimo = angulos * subimagenes;
var index_maximo = index_minimo + subimagenes - image_speed;

if ((image_index < index_minimo) || (image_index >= index_maximo))
{
if (image_index >= index_maximo)
final_animacion = true;
image_index = index_minimo;
}

draw_self();

return final_animacion;

Se debe colocar en el evento Draw del objeto que contenga el sprite y reemplazará la acción de dibujo. Además de que devuelve true o false cuando termina la animación en una de las direcciones.

 

Ejemplo de uso:

1
2
3
4
5
6
7
8
///EVENTO DRAW
if (sprite_index == spr_personaje_dispara)
{
if (draw_sprite_dir(4))
{
instance_create(x, y, obj_bala);
}
}

En este ejemplo, el objeto comprueba de que se esté ejecutando la animación de disparo del personaje y cuando termina esta animación, crea un objeto que representa la bala.

 

Pueden descargar el archivo GML para importarlo a sus proyectos pinchando aquí.

Move Snap Isométrico

Éste es el primero de muchos scripts para Game Maker: Studio que iré subiendo, varios de los cuales ya los tenía en mi antiguo sitio web, pero que iré mejorando y agregando nuevos.

 

En GML hay una función llamada move_snap(hsep, vsep), la cual posiciona a la instancia que llama al método, alineándola a una cuadrilla con celdas hsep pixeles de anchas y vsep pixeles de altas. Por ejemplo, si hsep y vsep tienen ambos un valor de 32 (move_snap(32, 32)) y la instancia que llama al método tiene x=39 e y=73, estos valores se redondean a x=32 (32 * 1) e y=64 (32 * 4).

 

El script que desarrollé lo llamo move_snap_iso(hsep, vsep), ya que cumple un rol similar a move_snap(hsep, vsep) con la diferencia que alinea a la instancia a una cuadrilla isométrica, en donde cada rombo tiene un ancho de hsep y un alto de vsep y posicionando la coordenada (x,y) en el centro del rombo.

 

Primero pedimos los argumentos y los almacenamos en variables que nos permitirán hacer el análisis correcto:

1
2
3
4
var W = argument[0] / 2;
var H = argument[1] / 2;
var I = round(x / W);
var J = round(y / H);

W y H son variables que dividen el escenario en cuadrillas con la mitad del tamaño de los rombos. I y J serían la posición en la que se encuentra la instancia dentro de estas cuadrillas.

1
2
3
4
5
if ((I mod 2 = 0 && J mod 2 = 0) || (I mod 2 == 1 && J mod 2 == 1))
{
x = W * I;
y = H * J;
}


Primero revisamos si los índices son ambos divisibles por 2 o ambos no lo son. Es decir, que ambos son impares o ambos son pares al mismo tiempo. En ese caso, se posiciona la instancia en la esquina superior izquierda de (W * I, H * I).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
else if (I mod 2 = 0 && J mod 2 == 1)
{
if (x > W * I)
x = W * (I + 1);
else
x = W * (I - 1);
y = H * J;
}
else if (I mod 2 == 1 && J mod 2 = 0)
{
x = W * I;
if (y > H * J)
y = H * (J + 1);
else
y = H * (J - 1);
}

 

Pueden descargar el archivo GML para importarlo a sus proyectos pinchando aquí.