鼠标拖动方向公差

本文关键字:方向 拖动 鼠标 | 更新日期: 2023-09-27 18:28:57

我正在开发一款2D游戏,玩家可以在其中拖动瓷砖。它的工作方式是玩家点击并按住一个瓦片,然后根据玩家从那时起移动鼠标的方向,决定拖动方向。

然而,问题是这过于敏感。通常情况下,玩家开始拖动并想垂直拖动,但由于鼠标的敏感性,结果是水平拖动(反之亦然)。

有人知道如何为这种拖动行为添加容忍阈值吗?我的代码中的相关部分基本上是这样的:

private void Update()
{
    if (_isMouseDown && sourceTile != null)
    {
        _isDraggingTile = true;
        /* Determine drag direction and drag target cell. */
        Vector3 dragDistance = Input.mousePosition - _originMousePosition;
        dragDistance.Normalize();
        if (_dragDirection == DragDirection.None)
        {
            float f = Vector3.Dot(dragDistance, Vector3.up);
            /* Mouse up drag. */
            if (f >= 0.5f)
            {
                _dragDirection = DragDirection.Up;
                _dragTargetCell = sourceTile.gridCell.upNeighbor;
            }
            /* Mouse down drag. */
            else if (f <= -0.5f)
            {
                _dragDirection = DragDirection.Down;
                _dragTargetCell = sourceTile.gridCell.downNeighbor;
            }
            else
            {
                /* Mouse right drag. */
                f = Vector3.Dot(dragDistance, Vector3.right);
                if (f >= 0.5f)
                {
                    _dragDirection = DragDirection.Right;
                    _dragTargetCell = sourceTile.gridCell.rightNeighbor;
                }
                /* Mouse left drag. */
                else if (f < -0.5f)
                {
                    _dragDirection = DragDirection.Left;
                    _dragTargetCell = sourceTile.gridCell.leftNeighbor;
                }
            }
        }
        if (_dragTargetCell != null)
        {
            // Take care of moving the dragged tile!
        }
    }
}

简单地将CCD_ 1的计算延迟一些帧并不能很好地工作。我认为需要的是一个解决方案来计算鼠标的移动,并决定它在哪些轴上移动得最远。如上所述确定拖动方向可能永远不会成功。

鼠标拖动方向公差

任何信息收集的问题都是噪声。在您的情况下,噪声是由用户的错误移动定义的。尽管如此,应该可以通过对值进行平均来最小化噪声的影响。

DSP中使用了先进的算法,但我想在您的情况下,应该对信息进行基本的平均。

你可以尝试的是,不是像你那样一次在更新中移动,而是收集几帧的移动,然后对所有这些帧进行平均,看看它是否会更好:

IEnumerator GetAverageMovement(Action<Vector3> result)
{
    int frames = 0; 
    List<Vector3>list = new List<Vector3>();
    while(frames < 30f) // half a second appr
    {
        list.Add(GetDirection());
        frames++;
        yield return null;
    }
    result(AverageAllValues()); 
}

GetDirection只是返回当前位置和上一个位置之间的差值,AverageAllValues只是将列表中的所有值相加并除以列表。计数(又名30)。

这应该可以解决用户一直向右移动但最后有点向上移动的情况。最后一位应该被大的向右移动所抵消。

如果这还不够,那么你可以在方法中添加一些逻辑,如果一个值离平均值太远,就放弃它。我认为你不需要这个。

我认为应该在拖动后立即创建一个大小有限的位置队列。

通过比较Queue的最终值和第一个值,您可以找到方向。

如果你想得到更好的结果,你可以得到位置的方差,得到更好的效果。