El evento Gesture en Game Maker Studio 2
Una de las novedades que vemos en Game Maker Studio 2 es un nuevo evento, llamado Gesture . ¿Y este evento que es? ¿Era necesario crearlo para nuestros juegos en GMS 2? Veamos en detalle que nos podemos encontrar una vez se dispara el evento y profundizar en los datos que podemos tratar.
Qué es el evento Gesture
El evento Gesture se activará cada vez que detecte el gesto del ratón o un evento en la pantalla táctil, lo que suele llamarse tap. Normalmente está pensado para cuando hacemos un proyecto con exportación para móviles, aunque también puede utilizarse para detectar el ratón. Este evento no detectará múltiples toques simultáneos, ya que el objetivo es itnentar reconocer los inputs a un nivel más alto que las funciones directas de lectura del ratón o touch, y está diseñado para simplificar la implementación de las entradas de uso común en móviles o tablets.
Antes, y la verdad que ahora también, teníamos una serie de funciones para gestionar los touchs simultáneos, desde el evento de Step . En el siguiente enlace lo comento
Funciones multitouch para dispositivos móviles
Ahora con este evento podemos detectarlo de una manera diferente. Veamos la lista de subeventos que nos encontramos.
La primera clasificación que vemos es que tenemos los gestos de la instancia y los gestos globales, dónde los gestos de la instancia solo se activarán cuando se toque a la instancia dentro de la room. Como siempre, solo funciona si la instancia tiene una máscara asignada para que funcione como un evento de colisión y se desencadene. Los eventos globales, sin embargo, se activarán tocando en cualquier lugar dentro de la room, y para todas las instancias que tenga programado este evento.
El mapa del evento Gesture
Al igual que pasa con los eventos relacionados con la red, cualquier subevento de la lista generará un mapa que contendrá los datos en la variable event_data, con las siguientes claves y valores que comentamos a continuación:
- gesture: Este es un valor ID que es exclusivo para el gesto que está ejecutándose. Esto permite enlazar las diferentes partes de gestos en diferentes eventos (como cuando usamos drag start, dragging y drag end).
- touch: Es el índice del touch que se está utilizando para el gesto. En general, comenzará en 0 y aumentará para cada dedo que se mantenga presionado, luego se restablece a o cuando se eliminan estos dedos, pero si el usuario está tocando la pantalla en cualquier otro lugar cuando este evento se dispara por otro toque, el valor será mayor que 0.
- posX: Es la posición X del lugar de la room que se ha tocado.
- posY: Es la posición Y del lugar de la room que se ha tocado.
- rawposX: Es la posición X en bruto del espacio de la ventana del toque. Recordemos que un juego puede tener una room de 600×480 píxeles, pero si lo ejecutamos a pantalla completa en un ordenador (o tablet/móvil) la resolución puede ser diferente porque el juego aumenta (digamos que hace zoom). Aquí detectaríamos la posición de la resolución del dispositivo.
- rawposY: Es la posición Y en bruto del espacio de la ventana del toque.
- guiposX: Es la posición X del la capa del GUI del toque. La capa GUI es una vuelta más a lo que hemos comentado, porque podemos tener un tamaño diferente de la resolución de pantalla y el tamaño de la sala. Siguiendo el mismo ejemplo, imagina que tenemos la room de 600×480, pero lo ejecutamos en una ventana (o pantalla completa) con un zoom de 900×720. Aquí nos daría la posición de ese zoom.
- guiposY: Es la posición Y del la capa del GUI del toque.
- diffX: Es la diferencia que hay entre la posición X del toque actual y la posición X del último toque dentro de la room.
- diffY: Es la diferencia que hay entre la posición Y del toque actual y la posición Y del último toque dentro de la room.
- rawdiffX: Es la diferencia en bruto que hay entre la posición X del toque actual y la posición X del último toque dentro de la room.
- rawdiffY: Es la diferencia en bruto que hay entre la posición Y del toque actual y la posición Y del último toque dentro de la room.
- guidiffX: Es la diferencia en la GUI que hay entre la posición X del toque actual y la posición X del último toque dentro de la room.
- guiddiffY: Es la diferencia en la GUI que hay entre la posición Y del toque actual y la posición Y del último toque dentro de la room.
- isflick: Solo está disponible en el evento Drag End. Se establece a 1 si se detecta que cuando hemos dejado de pulsar el tiempo que ha pasado es mayor de 2 pulgadas por segundo (aunque podemos variar este dato). Es decir, nos da un dato de velocidad. ¿Y para que nos sirve? Lo veremos en detalle con el evento, pero de esta manera podemos decir si se ha ejecutado un flick cuando acaba de arrastrar.
Recuerda que este mapa sólo es válido dentro de este evento, se crea automáticamente al inicio del evento, y al final se destruye de nuevo. Si buscamos la variable en otros eventos, tendrá un valor de -1.
También hay que saber que si tienes varias instancias que se están tocando, o superpuestas una encima de otras, y todos ellas tienen un evento Gesture , entonces se activarán en todas, y no en la superior (la que estaríamos viendo). Si tienes varias vistas y arrastras una instancia, los valores devueltos se basarán en la view en la que se encontraba cuando recibió el tap inicial. Así que si tocas una instancia en una vista, y la liberas en otra, devolverá los valores relativos a la vista inicial dónde se detectó el tap por primera vez.
Ahora vamos a detallar cada uno de los subeventos que podemos usar, y algún ejemplo para saber usar las diferentes claves del mapa event_data.
Evento Tap
El evento Tap se activará cuando se toque o haga click en una instancia, o si es global el juego registra un toque en cualquier parte de la room. Un tap se considera un toque rápido y soltar, pero si el toque dura demasiado tiempo se considera que es un arrastre o Drag, y desencadenará otros subeventos en lugar de Tap. Generará el mapa que hemos comentado antes.
Un ejemplo en sería el siguiente:
// CREATE EVENT x_goto = x; y_goto = y;
// GLOBAL TAP EVENT x_goto = event_data[? "posX"]; y_goto = event_data[? "posY"];
// STEP EVENT var _pd = point_distance(x, y, x_goto, y_goto); move_towards_point(x_goto, y_goto, clamp(_pd, 0, 5);
En el código anterior detectamos en el evento Tap para detectar la posición del toque, y así poder mover el objeto hasta esa nueva posición. Si queremos configurar el tiempo del tap, podemos hacerlo con una función, que veremos al final.
Evento Double Tap
Se activa cuando se hace click o tap dos veces bastante rápido (en la instancia o globalmente). Estamos hablando de dos toques rápidos y soltar, pero si alguno de esos toques dura demasiado tiempo, se considera un evento de Drag, y activará esos eventos en vez del que estamos tratando.
Un ejemplo sería para eliminar una instancia:
// CREATE EVENT x_goto = x; y_goto = y;
// INSTANCE DOUBLE TAP EVENT instance_destroy();
Luego veremos que podemos definir el tiempo de cada tap y el tiempo entre taps.
Evento Drag Start
El evento se disparará cuando el usuario mantiene un toque sin soltarlo, con el tiempo inicial (que por defecto es de 0,16 segundos). Después de activar el evento, y mientras el usuario lo mantiene `pulsado, el evento Dragging se activará en cada step hasta que se haya liberado. También generará un mapa event_data que podemos utilizar para obtener información sobre el evento.
// CREATE EVENT drag_offsetX = 0; drag_offsetY = 0;
// INSTANCE DRAG START EVENT drag_offsetX = x - event_data[?"posX"]; drag_offsetY = y - event_data[?"posY"];
El código anterior se usa para obtener la posición X/Y inicial del toque, y saber cuanto se va a desplazar. El evento siguiente seguirá con el mismo ejemplo.
Evento Dragging
El evento Dragging se activa después del evento Drag Start, y se activa en cada step que se mantiene pulsado. Se moverá dependiendo del límite del arrastre que se defina, siendo la distancia de 0.1 pulgadas por defecto (aunque se puede configurar). Si no hay movimiento o el movimiento está por debajo de la distancia que hemos comentado, el evento no se activará. Sigamos con el ejemplo de arrastre:
// CREATE EVENT drag_offsetX = 0; drag_offsetY = 0;
// INSTANCE DRAG START EVENT drag_offsetX = x - event_data[?"posX"]; drag_offsetY = y - event_data[?"posY"];
// INSTANCE DRAGGING EVENT x = event_data[?"posX"] + drag_offsetX; y = event_data[?"posY"] + drag_offsetY;
Ahora tenemos un evento más, y movemos la instancia dependiendo de los nuevos valores que obtenemos. Veamos el último evento relacionado con el arrastre.
Evento Drag End
El evento Drag End se activa cuando el jugador suelta el toque o click de la instancia (o globalmente). El evento vuelve a generar los datos de la variable event_data, que usaremos para obtener información sobre el evento. Ahora el mapa tendrá una clave adicional, isflick. El Flick se puede traducir como chasquido, y se activa a 1 (o true) si calcula que la distancia por segundo que se ha producido el arrastre es mayor que un valor (predeterminado a 2 pulgadas por segundo). Recuerda que tenemos un evento Flick que hablaremos a continuación, pero ahora vemos un ejempo de como usarlo.
// CREATE EVENT flickVelX = 0.0; flickVelY = 0.0;
// DRAG END EVENT isFlick = event_data[?"isflick"]; if (isFlick) { flickVelX = event_data[?"diffX"]; flickVelY = event_data[?"diffY"]; } else { flickVelX = 0; flickVelY = 0; }
// STEP EVENT x += flickVelX; y += flickVelY; flickVelX *= 0.7; flickVelY *= 0.7;
Evento Flick
Para entender como funciona Flick, mejor ver el siguiente vídeo que lo explica muy bien:
¿Vemos la diferencia que hay si desplazamos la página a una velocidad, diremos normal, y a una velocidad grande? Una vez hemos soltado, continúa moviéndose hasta que se para. Eso lo podemos detectar con este evento.
Sólo se activa cuando se mantiene presionado con el dedo la pantalla, se arrastra y se suelta Y LA DISTANCIA ENTRE LA ÚLTIMA POSICIÓN DEL DRAG Y LA POSICIÓN QUE SE LIBERA ES MAYOR QUE 2 PULGADAS POR SEGUNDO. El evento genera igualmente el mapa, que podemos usar para obtener información:
// CREATE EVENT flickVelX = 0.0; flickVelY = 0.0;
// FLICK EVENT flickVelX = event_data[?"diffX"]; flickVelY = event_data[?"diffY"];
// STEP EVENT x += flickVelX; y += flickVelY; flickVelX *= 0.7; flickVelY *= 0.7;
Vemos la diferencia que hay en este código respecto al mismo del evento anterior, y haciendo exactamente lo mismo.
Si quieres, puedes comprobar el código de estos ejemplos con los eventos de gesto con el que se hizo en su momento de como arrastrar objetos.
Tutorial de como mover objetos
Funciones de gesto
Existen una serie de funciones que nos permite saber todas las opciones de entrada de un usuario: si una tecla del teclado se pulsa o no, el ratón, la orientación del móvil o tablet, etc. Pero a veces queremos detectar cosas más complejas, como poder mover una instancia en una room.
Aparte de los eventos que hemos visto, que nos permite detectar tap, doble tap, arrastrar y soltar (tanto en una instancia como globalmente) existen una serie de funciones para tener un mayor control sobre como y cuando se desencadenan los eventos.
Tenemos funciones para obtener diferentes valores para calcular, estas son:
- gesture_get_drag_time: obtiene el tiempo que tarda un evento de Drag para ser activado por un toque. Este tiempo marca la diferencia entre un Tap y un Drag. El valor predeterminado es de 0.16.
- gesture_get_drag_distance: obtiene la distancia que necesita un evento de Dragging para que se active, La distancia por defecto es de 0.1 pulgadas.
- gesture_get_flick_speed: se utiliza para obtener la velocidad para que un evento Flick se active cuando se suelta el toque o click. La velocidad se mide en pulgadas por segundo es de 2.
- gesture_get_double_tap_time: obtiene el tiempo que se tarda entre dos toques para activar un evento Double Tap. El tiempo se mide en segundo y el valor por defecto es de 0.16.
- gesture_get_double_tap_distance: se usa para obtener la distancia dentro de la cual debe hacer un tap en la pantalla después de hacer el primer tap para activar el evento Double Tap. La distancia se mide en pulgadas y el valor por defecto es de 0.1.
Luego tenemos la equivalencia, que se utilizan para establecer los diferentes valores que se calculan:
- gesture_drag_time: establece el tiempo que tarda un evento Drag en ser activado por un toque.
- gesture_drag_distance: establece la distancia que se necesita para que se active el evento Dragging.
- gesture_flick_speed: establece la velocidad necesaria para que se active el evento Flick.
- gesture_double_tap_time: establece el tiempo que tarda entre dos toques para activar el evento Double Tap.
- gesture_double_tap_distance: establece la distancia dentro la cual debe tocar de nuevo la pantalla después de un sólo toque para activar el evento Double Tap.
tengo una duda con lo siguiente:
tengo 6 obj en pantalla, 3 figuras normales y 3 siluetas de las figuras (3 pares) cuando la fig normal colisiona con la silueta esta desaparece y aparece otra de la fig normal, lo que queda en 6 figuras normales y ninguna silueta hasta aquí todo bien.
Mi duda es la siguiente:
quiero que se revise si las 6 figuras normales están en pantalla para que después de que se revise entre un alarm de 2 segundos y que aparezca la pantalla para el sig nivel.
Como se haría con codigo y con D&D?
Primero, si esas figuras normales son el mismo objeto te sirve el ejemplo, sino es mejor crear un objeto padre y que éstas 6 lo hereden. En el evento Step, de un objeto controlador mejor, yo haria la siguiente comprobación:
if instance_number(obj_figura_normal) == 6 //o >= 6
{
alarm[0] = 60;
}
Si lo quieres con D&D, existe la acción Test Instance Count, que también te sirve. Mira aquí cual és:
Acciones de control en Game Maker
no son las mismas son 3 diferentes formas y sus siluetas respectivas
Por eso yo haría un objeto padre que herede esas 3 formas de él, así puedes controlar que hay 6 objetos en total.
Hola David tengo un problema que no acabó de entender,tengo una nave en arrastre x=mouse.x. y=mouse.y. y. Un botón disparo resulta que no se como hacer que me detecte las dos acciones a la misma vez
En un objetó tengo puesto if device_mouse_check_button (0, mb_left). Y en el otro if device_mouse_check_button (1, mb_left)
Realizaras mas tutoriales en udemy?
cuando se usa device_mouse_check_button(), el primer parámetro detecta si hay más de un click A LA VEZ, es decir, solo funcionaría para móviles que es Multitouch.
No entiendo exactamente como lo has programado, pero si usas dos objetos, utiliza device_mouse_check_button (0, mb_left) en los dos, ya que entiendo que está uno encima de otro.
Y si, seguiré haciendo más cursos y tutoriales en Udemy. Como plataforma de enseñanza me gusta bastante, aunque aún tengo que abordar que temas haré. Acepto sugerencias:
Hola! cómo pondría limites de movimiento en el drag? en cosdenada “y” le agredezco su respuesta
Podrías usar la función
clamp()
, por ejemplo:y = clamp(y, 1, 100);
Esto haría que si y se va fuera del rango marcado, entre 1 y 100, se quedaría en ese máximo o mínimo.
Hola tengo una duda estoy usando game maker studio 2 y quisiera hacer una dos acciones sobre un objeto boton:
1- Que cuando lo presione una sola vez este me realice una sola accion.
2.- Cuando deje presionado me realice tra accion.
Como lo podria hacer :c ya trate muchas cosas y lo que me pasa es que se hace la primera bien y la segunda no la hace,
o me hace las dos pero al presionar una vez realiza la accion unas 5 veces aunque haya presionado una vez.
espero me puedas ayuda ya probe muchas cosas y nada.
1. -Left released 8partiendo que usas el raton) para una sola vez.
2.-Left pressed para detectar que está presionado. Para que no lo detecte siempre los dos, puedes usar una alarma.