手势
中级 程序员
手势(Gesture)是预定义的指针模式。Stride 可以识别手势并触发相应的事件。例如,在策略游戏中,玩家可以用拖动手势将单位拖放到战场上。手势可以使用一根或多根手指。
Note
配置文件中所有的长度、速度和误差范围都必须使用归一化的值。
开启手势识别
默认情况下,输入系统不会识别手势,因为这会占用 CPU 时间。
要开启手势识别:
- 为要识别的手势创建配置类的实例。例如,对于拖动手势,请创建 @'Stride.Input.GestureConfigDrag' 的实例。
- 配置类参数。
- 将手势配置添加到 @'Stride.Input.InputManager.Gestures' 集合中。
Warning
激活某个手势的识别后,就无法再修改该手势的参数。如果需要修改,请从 @'Stride.Input.InputManager.Gestures' 集合中删除该手势,并使用新参数创建新的条目。
关闭手势识别
从 InputManager.Gestures 集合中删除该手势。
手势识别
当输入系统检测到手势时,它会将一个 @'Stride.Input.GestureEvent' 添加到 InputManager.GestureEvents 列表中。该事件包含手势及其状态的信息,例如位置和使用的手指数量。
Note
每个手势都有其关联的手势事件类(见下文)。
GestureEvent.Type 字段指示识别出的是哪种手势。然后你可以将基础手势事件转换为该手势特有的事件类型,以获取与手势类型相关的事件信息。
Stride 可以同时检测多个手势,因此一次更新中事件列表可能包含多个条目。
该列表会在每次更新时清空,因此你无需手动清除。
配置手势
在 @'Stride.Input.GestureConfig' 类中,你可以配置的参数包括:
手势使用的手指数量
手势使用的轻点(Tap)次数和时长
手势方向
Note
每个手势都有自己的配置类和特定的配置参数(见下文)。
手势类型
Stride 支持两种主要的手势类型:
离散手势
轻点(Tap)

用户触摸屏幕并快速移开手指。
配置类:@'Stride.Input.GestureConfigTap'
事件类:@'Stride.Input.GestureEventTap'
手势过程中屏幕上的手指数量不能变化。要设置轻点所需的手指数量,请修改 @'Stride.Input.GestureConfig.RequiredNumberOfFingers'。
Tip
为了区分单次轻点和多次轻点,系统会在轻点事件中使用延迟。要禁用此功能,请将 GestureConfigTap.MaximumTimeBetweenTaps 字段设置为 0。
轻弹(Flick)

用户触摸屏幕,快速进行一次直线平移,然后收起手指。
配置类:@'Stride.Input.GestureConfigFlick'
事件类:@'Stride.Input.GestureEventFlick'
手势过程中屏幕上的手指数量不能变化。
要为轻动手势设置最小长度,请使用 GestureConfigFlick.MinimumFlickLength。
要将轻弹方向限制为垂直或水平,请使用 GestureConfigFlick.FlickShape。
长按(Long press)

用户触摸屏幕并保持按压,在一段时间内不移开手指(默认时间为一秒)。
手势过程中屏幕上的手指数量不能变化。
要更改长按手势的最小按压时长,请修改 GestureConfigLongPress.RequiredPressTime。
连续手势
拖动(Drag)

用户触摸屏幕,进行一次平移,然后收起手指。
事件类:GestureEventDrag
手势过程中屏幕上的手指数量不能变化。
要检测更小的拖动,请减小 GestureConfigDrag.MinimumDragDistance。
要将拖动方向限制为垂直或水平,请使用 GestureConfigDrag.DragShape。
复合(Composite)

用户用两根手指触摸屏幕并独立移动它们。
配置类:@'Stride.Input.GestureConfigComposite'
事件类:@'Stride.Input.GestureEventComposite'
复合手势要求屏幕上恰好有两根手指。当系统检测到以下三种基本动作之一时触发:
- 平移(Translation):用户将两根手指沿相同方向一起移动。
- 缩放(Scale):用户将两根手指移近或移远。
- 旋转(Rotation):用户围绕一个中心点旋转两根手指。
手势状态
手势始终处于以下四种状态之一:
Began(开始)
Changed(变化)
Ended(结束)
Occurred(已发生)
离散手势(轻点、轻弹、长按)始终为 occurred 状态。连续手势(拖动和复合手势)始终以 began 状态开始,随后是任意多个 changed 状态,最后以 ended 状态结束。
要查询手势的当前状态,请使用触发的手势事件的 GestureEvent.State 字段。
示例代码
激活或停用手势识别
要创建要识别的手势的配置:
// 创建要识别的手势的配置
var singleTapConfig = new GestureConfigTap();
// 开始轻点手势识别
Input.Gestures.Add(singleTapConfig);
// 创建要识别的手势的配置
var doubleTapConfig = new GestureConfigTap(2, 1);
// 开始双击手势识别
Input.Gestures.Add(doubleTapConfig);
// 停止轻点手势识别
Input.Gestures.Remove(singleTapConfig);
// 停止所有手势识别
Input.Gestures.Clear();
配置手势
每个配置类都有一个无参构造函数,对应默认的手势配置。对于经常修改的参数,你可以使用专用的构造函数。
Warning
我们不建议你修改其他字段,因为这可能会破坏输入系统。但如果确实需要,可以通过相应的属性进行修改。
// 默认手势配置
var singleTapConfig = new GestureConfigTap();
// 使用专用构造函数个性化手势配置
var doubleTapConfig = new GestureConfigTap(2, 2);
// 通过直接访问所需属性来个性化手势配置
// 请确保你清楚自己在做什么!修改此设置可能会破坏输入系统
var noLatencyTap = new GestureConfigTap() { MaximumTimeBetweenTaps= TimeSpan.Zero };
访问手势事件
你可以使用 InputManager.GestureEvents 集合访问已识别手势触发的事件列表。该集合会在每次更新时自动清空。
var currentFrameGestureEvents = Input.GestureEvents;
识别手势类型
使用 GestureEvent.Type 字段识别手势类型,然后将其转换为相应的事件类型,以获取有关该事件的额外信息。
foreach( var gestureEvent in Input.GestureEvents)
{
// 判断事件是否来自轻点手势
if (gestureEvent.Type != GestureType.Tap)
continue;
// 转换为特定的轻点事件类
GestureEventTap tapEvent = (GestureEventTap) gestureEvent;
// 访问轻点事件特有的字段
log.Info("Tap position: {0}.", tapEvent.TapPosition);
}
识别手势状态
使用 GestureEvent.State 字段获取手势事件状态。
switch(compositeGestureEvent.State)
{
case GestureState.Began:
image.ComputePreview();
break;
case GestureState.Changed:
image.TransformPreview(compositeGestureEvent.TotalScale, compositionGestureEvent.TotalRotation);
break;
case GestureState.Ended:
image.TransformRealImage(compositeGestureEvent.TotalScale, compositionGestureEvent.TotalRotation);
break;
default:
break;
}