手势事件

The Gesture Events

手势事件类别中的事件将在GameMaker检测到鼠标或触摸屏事件时触发(虽然这些手势事件是专门为移动使用设计的,但它们也可以用于其他目标来检测鼠标,尽管在这种情况下它们不会检测多个触摸)。手势系统的目标是尝试并识别比直接鼠标/触摸阅读功能更高级别的输入,旨在简化基于触摸的设备上常用输入的实现。

注意 这些事件不会在HTML5平台上触发,因为该平台不支持使用这些事件的多点触摸。如果您要在该目标上查找手势,则应使用设备功能

您可以选择检测实例手势或全局手势,其中实例手势事件只有在初始触摸/点击房间内的实例时才会被触发。请注意,实例必须具有有效的碰撞遮罩(有关详细信息,请参见精灵编辑器-碰撞遮罩对象编辑器-碰撞遮罩部分),才能触发此事件。然而,全局事件将通过触摸/点击游戏室内的任何位置以及所有具有该事件的实例来触发。

当手势被识别时,它将触发一个或多个可用事件,并且触发的事件将取决于已检测到的手势的类型。但是,在任何情况下,都会为您生成一个DS 映射 ,并将其存储在内置变量event_data中。可用的密钥将取决于它是由哪种事件创建的,并在下面的每个小节中显示。

注意:变量 event_data 仅在这些事件中有效,因为它所指向的 DS 映射是在事件开始时自动创建的,然后在结束时再次销毁,而此变量在所有其他时间都被重置为值 -1。

值得注意的是,如果您在被触摸的位置下有多个实例,并且它们都有一个手势事件,那么它们会被触发,而不仅仅是最上面的实例。另请注意,当使用多个摄像头视图并拖动实例时,返回的值将基于接收到初始触摸/单击时所在的视图-对于该实例该手势中的所有后续事件都是如此。因此,在一个视图中触摸和拖动实例,然后在另一个视图中释放触摸,将返回相对于首次检测到手势的初始视图的值。

 

    点击、拖动和点击事件点击、拖动和点击事件

点击、拖动和点击事件均基于屏幕上的一次触摸或鼠标点击,并且event_data DS 映射将包含以下键:

描述
"gesture"
This is an ID value that is unique to the gesture that is in play. This allows you to link the different parts of multi-part gestures (such as drag start, dragging and drag end) together.
"touch"
This is the index of the touch that is being used for the gesture. In general this will start at 0 and increase for each finger that is held down, then reset back to 0 when all fingers are removed, but if the user is touching the screen anywhere else when this event is triggered by another touch, then the value will be greater than 0.
"posX"
This is the room-space X position of the touch.
"posY"
This is the room-space Y position of the touch.
"rawposX"
This is the raw window-space X position of the touch (equivalent to getting the mouse position using device_mouse_raw_x()).
"rawposY"
This is the raw window-space Y position of the touch (equivalent to getting the mouse position using device_mouse_raw_y()).
"guiposX"
This is the gui-space X position of the touch (equivalent to getting the mouse position using device_mouse_x_to_gui()).
"guiposY"
This is the gui-space Y position of the touch (equivalent to getting the mouse position using device_mouse_y_to_gui()).
"diffX"
This is the room-space X difference between the position of the current touch and the position of the last touch in this gesture.
"diffY"
This is the room-space Y difference between the position of the current touch and the position of the last touch in this gesture.
"rawdiffX"
This is the raw X difference between the position of the current touch and the position of the last touch in this gesture.
"rawdiffY"
This is the raw Y difference between the position of the current touch and the position of the last touch in this gesture.
"guidiffX"
This is the gui-space X difference between the position of the current touch and the position of the last touch in this gesture.
"guidiffY"
This is the gui-space Y difference between the position of the current touch and the position of the last touch in this gesture.
"viewstartposX"
This is the room X start position of the current gesture.
"viewstartposY"
This is the room Y start position of the current gesture.
"rawstartposX"
This is the raw X start position of the current gesture.
"rawstartposY"
This is the raw Y start position of the current gesture.
"guistartposX"
This is the gui-space X start position of the current gesture.
"guistartposY"
This is the gui-space Y start position of the current gesture.
"isflick"
Only available in the Drag End event
. This is set to 1 if the end of the drag is detected as a flick, meaning that you don't need a separate Flick Event if you're handling dragging anyway.

 

点击点击

Tap 事件将在实例被触摸或点击时触发,或者-如果它是全局事件-当游戏记录到房间中的任何位置被触摸或点击时。轻触被认为是快速触摸和释放,如果触摸持续太长时间,则将被视为拖动 (并触发拖动手势事件,而不是轻击事件)。此事件将生成一个 event_data DS 映射,然后您可以使用该映射获取有关该事件的信息。例如:

创建事件

x_goto = x;
y_goto = y;

点击事件

x_goto = event_data[? "posX"];
y_goto = event_data[? "posY"];

步事件

var _pd = point_distance(x, y, x_goto, y_goto);
move_towards_point(x_goto, y_goto, clamp(_pd, 0, 5);

上面的代码将检测屏幕上的点击,然后获取点击的位置以将实例移动到该位置。请注意,如果您想要更长或更短的点击检测时间,则可以使用函数 gesture_drag_time() 进行设置。这设置了从初始检测到轻触变为拖拽之间的时间,因此将其设置为较高的值可延长轻触检测的时间,或设置较低的值可缩短轻触检测的时间 (值以秒为单位,默认为 0.16)。

 

双击双击

当一个实例被快速连续触摸或点击两次时 (或者-如果它是一个全局事件-当游戏记录了两次快速触摸或在房间中的任何地方点击时),将触发双击事件。双击被认为是两次快速触摸和释放,但如果任何一次触摸持续时间太长,则将被视为拖动 (并触发拖动手势事件,而不是双击事件)。此事件将生成一个 event_data DS 映射,然后您可以使用该映射获取有关该事件的信息。例如:

创建事件

x_goto = x;
y_goto = y;

双击事件

instance_destroy();

上面的代码只是检测到双击,然后销毁实例。请注意,您可以使用函数 gesture_double_tap_time() (默认值为秒) 设置两次轻击之间的时间间隔,也可以使用函数 gesture_double_tap_distance() (如果设置两次轻击之间的检测距离。

 

拖动开始拖动开始

当用户保持触摸或单击而不松开它时,将触发拖动开始事件。它会在初始触摸后经过设置的时间时触发一次,默认为 0.16 秒 (尽管您可以使用函数 gesture_drag_time() 将其设置为以秒为单位的任何其他值)。在此事件被触发后,只要用户按住触摸 / 点击,则每一步都会触发拖动事件,直到触摸 / 点击被释放。此事件将生成一个 event_data DS 映射,然后您可以使用该映射获取有关该事件的信息。例如:

创建事件

drag_offsetX = 0;
drag_offsetY = 0;

拖动开始事件

drag_offsetX = x - event_data[?"posX"];
drag_offsetY = y - event_data[?"posY"];

上面的代码使用拖动开始事件来获取触摸 / 单击的位置,并使用它来设置 X 和 Y 轴的偏移值。然后可以在拖动实例时使用它,以确保它不会 " 跳转 " 到检测到触摸 / 单击的位置 (请参阅下面的拖动事件以继续此示例)。

 

正在拖动正在拖动

拖拽事件是在拖拽开始事件之后触发的,用户在实例 (或屏幕,如果是全局事件) 上保持触摸 / 点击并移动超过定义的拖拽阈值的每一步都会触发拖拽事件。默认情况下,此距离为 0.1 英寸,但可以使用函数 gesture_drag_distance() 设置。如果没有移动或移动低于定义的阈值,则不会触发该事件。此事件将生成一个 event_data DS 映射,然后您可以使用该映射获取有关该事件的信息。例如:

创建事件

drag_offsetX = 0;
drag_offsetY = 0;

拖动开始事件

drag_offsetX = x - event_data[?"posX"];
drag_offsetY = y - event_data[?"posY"];

正在拖动事件

x = event_data[?"posX"] + drag_offsetX;
y = event_data[?"posY"] + drag_offsetY;

当触发拖动事件时,上面的示例代码使用在拖动开始事件中设置的偏移变量来移动实例。

 

拖动结束拖动结束

当用户在实例 (如果事件是全局事件,则是屏幕) 上释放触摸 / 单击时,将触发拖动结束事件。此事件将生成一个 event_dataDS 映射,然后您可以使用该映射来获取有关该事件的信息,但在此事件中,该映射将有一个额外的密钥:"isflick"。轻拍按发生拖动的每秒距离计算,如果大于定义的每秒距离值,"isflick" 键的值将为 True,否则为 False。请注意,缺省值为每秒 2 英寸,但您可以使用函数 gesture_flick_speed() 将其设置为另一个值。还要注意,如果 "isflick" 变量为真,则也会触发专用的轻击事件。使用的一个示例是:

创建事件

flickVelX = 0.0;
flickVelY = 0.0;

拖动结束事件

isFlick = event_data[?"isflick"];
if (isFlick)
    {
    flickVelX = event_data[?"diffX"];
    flickVelY = event_data[?"diffY"];
    }
else
    {
    flickVelX = 0;
    flickVelY = 0;
    }

步事件

x += flickVelX;
y += flickVelY;
flickVelX *= 0.7;
flickVelY *= 0.7;

上面的代码只是获取最后一个拖动事件和当前拖动结束事件的 X 和 Y 位置之差,如果移动大于轻击阈值,它将设置一些用于在步事件中移动实例的变量。

 

轻击轻击

仅当按住、拖动并释放触摸 / 点击,并且最后一次拖动位置与释放位置之间的距离大于每秒 2 英寸时,才会触发 Flick 事件 (这是默认设置,但可以使用函数 gesture_flick_speed() 进行更改)。此事件将生成一个 event_data DS 映射,然后您可以使用该映射获取有关该事件的信息。例如:

创建事件

flickVelX = 0.0;
flickVelY = 0.0;

轻击事件

flickVelX = event_data[?"diffX"];
flickVelY = event_data[?"diffY"];

步事件

x += flickVelX;
y += flickVelY;
flickVelX *= 0.7;
flickVelY *= 0.7;

上面的代码只是获取最后一个拖动事件和当前轻击事件的 X 和 Y 位置之差,如果移动超过了轻击阈值,它将设置一些用于在步事件中移动实例的变量。

 

捏事件(双指向内)捏事件(双指向内) 

"捏"事件是基于一次对设备屏幕的两次触摸被识别的,其中一次(或两次)移动超过了一定距离。触摸的移动角度以及每次触摸的移动将确定捏或旋转事件的检测,其中(在捏事件类型的情况下):

当检测到符合上述标准的两次触摸和一次移动时,将触发夹压事件,并且在每个事件中,将使用以下键填充 event_data DS 映射:

描述
"gesture"
This is an ID value that is unique to the gesture that is in play. This allows you to link the different parts of multi-part gestures (such as drag start, dragging and drag end) together.
"touch1"
This is the index of the first touch that is being used as part of the pinch gesture. In general this will be 0, but if the user is touching the screen anywhere else when this event is triggered by another touch, then the value will be greater than 0.
"touch2"
This is the index of the second touch that is being used as part of the pinch gesture. In general this will be 1 more than the value for touch1, but may be some other value depending on the number of touches being detected elsewhere.
"posX1"
This is the room-space X position of the first touch.
"posY1"
This is the room-space Y position of the first touch.
"rawposX1"
This is the raw window-space X position of the first touch (equivalent to getting the mouse position using device_mouse_raw_x()).
"rawposY1"
This is the raw window-space Y position of the first touch (equivalent to getting the mouse position using device_mouse_raw_y()).
"guiposX1"
This is the gui-space X position of the first touch (equivalent to getting the mouse position using device_mouse_x_to_gui()).
"guiposY1"
This is the gui-space Y position of the second touch (equivalent to getting the mouse position using device_mouse_y_to_gui()).
"posX2"
This is the room-space X position of the second touch.
"posY2"
This is the room-space Y position of the second touch.
"rawposX2"
This is the raw window-space X position of the first touch.
"rawposY2"
This is the raw window-space Y position of the second touch.
"guiposX2"
This is the gui-space X position of the second touch.
"guiposY2"
This is the gui-space Y position of the second touch.
"midpointX"
The X position of the mid point between the two touches in room space.
"midpointY"
The Y position of the mid point between the two touches in room space.
"rawmidpointX"
This is the raw window-space X position of the mid point.
"rawmidpointY"
This is the raw window-space Y position of the mid point.
"guimidpointX"
This the gui-space X position of the mid point.
"guimidpointY"
This the gui-space Y position of the mid point.
"relativescale"
This is difference in scale compared to the last event in this gesture (so for Pinch In events this will always be smaller than 1.0, whereas for Pinch Out events it will always be larger than 1.0)
"absolutescale"
This is the scale compared to where the fingers were when the gesture started (so if the distance between the fingers has halved then this will be 0.5 whereas if the distance has doubled it will be 2.0).

 

捏开始捏开始

当实例 (如果事件是全局的,则是屏幕) 被两个 " 手指 " 触摸 (并且保持触摸),然后移动一个或两个 " 手指 " 时,将触发捏开始事件。如果触点彼此远离或朝向彼此移动的距离超过最小检查距离 (默认为 0.1 英寸,但可以使用函数 gesture_pinch_distance()) 进行设置,并且它们之间的角度在定义的值内 (此默认为 45°,但可以使用 gesture_pinch_angle_towards()gesture_pinch_angle_away() 设置),则将触发收缩开始事件。在这种情况下,您可以设置变量或存储职位日期以备将来使用。例如:

捏开始事件

pinching = true;
pinch_x = event_data[? "midpointX"]; pinch_y = event_data[? "midpointY"];

上面的代码将检测一个捏点并存储该捏点的中点位置。

 

捏入/捏出捏入/捏出

构成收缩的两个触摸之间的距离超过最小阈值 (默认情况下设置为 +/-0.1 英寸,但您可以使用函数 gesture_pinch_distance 更改) 的每一步都将触发收缩和收缩事件。如果按压触摸没有移动,则不会触发这些事件。这些事件将生成一个 event_data DS 映射,然后您可以使用该映射获取有关该事件的信息。例如:

全局捏入/捏出事件

var _scale = event_data[? "relativescale"];
var _w = camera_get_view_width(view_camera[0]);
var _h = camera_get_view_height(view_camera[0]);
var _x = camera_get_view_x(view_camera[0]) + (_w / 2);
var _y = camera_get_view_y(view_camera[0]) + (_h / 2);

_w *= _scale;
_h = _w * (room_height / room_width);
_x -= _w / 2;
_y -= _h / 2;

camera_set_view_pos(view_camera[0], _x, _y);
camera_set_view_size(view_camera[0], _w, _h);

上面的代码将根据捏触点的相对比例来缩放视图。

 

捏停止捏停止

当用户从设备释放一个 (或两个) 触摸时,将触发捏结束事件。此事件将生成一个 event_data DS 映射,然后您可以使用该映射获取有关该事件的信息。例如:

捏停止事件

var _pinchx = event_data[? "midpointX"];
var _pinchy = event_data[? "midpointY"];
var _w = camera_get_view_width(view_camera[0]);
var _h = camera_get_view_height(view_camera[0]);
var _x = _pinchx - (_w / 2);
var _y = _pinchy - (_h / 2);

camera_set_view_pos(view_camera[0], _x, _y);

上面的代码将在释放触摸时将视图位置设置为两个触摸的中点为中心。

 

旋转事件旋转事件

"旋转"事件是基于对设备屏幕的两次触摸被一次识别,并且在特定时间内两者之间存在一致的角度旋转。触摸的移动角度以及每次触摸的移动将确定是否检测到挤压或旋转事件,其中(在旋转事件类型的情况下):

当检测到符合上述标准的两次触摸和一次移动时,将触发旋转事件,并且在每个事件中,将使用以下键填充event_data DS 映射:

描述
"gesture"
This is an ID value that is unique to the gesture that is in play. This allows you to link the different parts of multi-part gestures (such as drag start, dragging and drag end) together.
"touch1"
This is the index of the first touch that is being used as part of the pinch gesture. In general this will be 0, but if the user is touching the screen anywhere else when this event is triggered by another touch, then the value will be greater than 0.
"touch2"
This is the index of the second touch that is being used as part of the pinch gesture. In general this will be 1 more than the value for touch1, but may be some other value depending on the number of touches being detected elsewhere.
"posX1"
This is the room-space X position of the first touch.
"posY1"
This is the room-space Y position of the first touch.
"rawposX1"
This is the raw window-space X position of the first touch (equivalent to getting the mouse position using device_mouse_raw_x()).
"rawposY1"
This is the raw window-space Y position of the first touch (equivalent to getting the mouse position using device_mouse_raw_y()).
"guiposX1"
This is the gui-space X position of the first touch (equivalent to getting the mouse position using device_mouse_x_to_gui()).
"guiposY1"
This is the gui-space Y position of the second touch (equivalent to getting the mouse position using device_mouse_y_to_gui()).
"posX2"
This is the room-space X position of the second touch.
"posY2"
This is the room-space Y position of the second touch.
"rawposX2"
This is the raw window-space X position of the first touch.
"rawposY2"
This is the raw window-space Y position of the second touch.
"guiposX2"
This is the gui-space X position of the second touch.
"guiposY2"
This is the gui-space Y position of the second touch.
"pivotX"
The X position of the rotation pivot point in room space.
"pivotY"
The Y position of the rotation pivot point in room space.
"rawpivotX"
This is the raw window-space X position of the rotational pivot point.
"rawpivotY"
This is the raw window-space Y position of the rotational pivot point.
"guipivotX"
This the gui-space X position of the rotational pivot point.
"guipivotY"
This the gui-space Y position of the rotational pivot point.
"relativeangle"
This is difference in rotation compared to the last event in this gesture, measured in degrees
"absoluteangle"
This is the difference in angle compared to where the fingers were when the gesture started, measured in degrees. So, for example, if the fingers have rotated a quarter-circle since the start of the gesture then this value will be 90° or -90°, depending on the direction of rotation.

 

旋转开始旋转开始

当实例 (如果事件是全局的,则是屏幕) 被两个“手指”触摸 (并且保持触摸),然后一个或两个“手指”从其开始位置旋转时,将触发旋转开始事件。触摸的旋转需要在短时间内开始 (默认为 0.16 秒,但可以使用函数 gesture_rotate_time()) 进行设置,并且大于最小角度阈值 (默认为 5°,但可以使用函数 gesture_rotate_angle() 进行更改)。如果这些检查为真,则将触发旋转开始事件,您可以使用它来存储值或设置变量,以便与其余旋转事件一起使用。例如:

创建事件

rotating = false;
view_a = camera_get_view_angle(view_camera[0]);

旋转开始事件

rotating = true;

上面的代码简单地设置了一些用于旋转视图相机的变量,然后在旋转开始事件中,它将其中一个设置为 true。

 

正在旋转正在旋转

只要移动大于最小角度阈值 (默认为 5°,但可以使用函数 gesture_rotate_angle()),屏幕上的触点围绕彼此旋转的每一步都会触发正在旋转事件。此事件可用于设置变量和操作实例,例如:

正在旋转事件

var _relangle = event_data[?"relativeangle"];
var _a = camera_get_view_angle(view_camera[0]);
_a += _relangle;
camera_set_view_angle(view_camera[0], _a);

上面的代码根据事件中触摸的旋转移动来旋转相机视图。

 

旋转结束旋转结束

当构成手势的一个(或两个)触摸从设备屏幕上释放时,将触发旋转结束事件。此事件可用于设置变量和操作实例,例如:

旋转结束事件

rotating = false;

步事件

if (!rotating)
    {
    var _a = camera_get_view_angle(view_camera[0]);
    var _adif = angle_difference(view_a, _a);
    _a += median(-5, _adif, 5);
    camera_set_view_angle(view_camera[0], _a);
    }

上面的代码使用旋转结束事件来检测用户何时停止手势,然后设置一个变量。然后,在步事件中使用此变量将视图相机旋转回其原始位置。