XNA中的触摸按钮(包含按下、释放和移动状态)

3

我想在WP8中制作具有所有状态(按下,释放,移动)的触摸按钮,但是 TouchLocationState.Released 没有起作用。

以下是我的代码:

类变量:

bool touching = false;
int touchID;
Button tempButton;

Update方法包含以下代码:

TouchCollection touchCollection = TouchPanel.GetState();

if (!touching && touchCollection.Count > 0)
        {
            touching = true;

            foreach (TouchLocation location in touchCollection)
            {
                for (int i = 0; i < menuButtons.Count; i++)
                {
                    touchID = location.Id; // store the ID of current touch
                    Point touchLocation = new Point((int)location.Position.X, (int)location.Position.Y); // create a point
                    Button button = menuButtons[i]; 

                    if (GetMenuEntryHitBounds(button).Contains(touchLocation)) // a method which returns a rectangle.
                    {
                        button.SwitchState(true); // change the button state
                        tempButton = button; // store the pressed button for accessing later
                    }
                }
            }
        }
        else if (touchCollection.Count == 0) // clears the state of all buttons if no touch is detected
        {
            touching = false;

            for (int i = 0; i < menuButtons.Count; i++)
            {
                Button button = menuButtons[i];
                button.SwitchState(false);
            }
        }

menuButtons是菜单上按钮的列表。

在touched变量为true后,Update方法内有一个单独的循环。

if (touching)
{
    TouchLocation location;
    TouchLocation prevLocation;

    if (touchCollection.FindById(touchID, out location))
    {
          if (location.TryGetPreviousLocation(out prevLocation))
          {
                Point point = new Point((int)location.Position.X, (int)location.Position.Y);

                if (prevLocation.State == TouchLocationState.Pressed && location.State == TouchLocationState.Released)
                {
                       if (GetMenuEntryHitBounds(tempButton).Contains(point))
                              // Execute the button action. I removed the excess 
                }
           }
     }
}

location.State == TouchLocationState.Released 往往会变成 false。(即使在我松开触摸后,它的值仍为 TouchLocationState.Moved)更让人烦恼的是,有时它能正常工作!

我真的很困惑,已经卡了几天了。这是正确的方式吗?如果是,那么我做错了什么?还是有其他更有效的方法来实现这个功能?

1个回答

1

我终于自己找到了解决方案。它不需要TouchLocationStatereleased状态。

在这里发布它。希望能帮助其他人。 感谢任何尝试过的人。

类变量已重命名:

private Point _touchPoint;
private TouchLocation _touchLocation;
private int _touchID;
private Button _selectedButton;
private bool _touched;
private bool _launchEvent;

更新方法现在具有以下代码。
        TouchCollection touchCollection = TouchPanel.GetState();

        if (!_touched && touchCollection.Count > 0)
        {
            _touched = false;
            _launchEvent = false;

            foreach (TouchLocation location in touchCollection)
            {
                for (int i = 0; i < menuButtons.Count; i++)
                {
                    Button button = menuButtons[i];
                    _touchID = location.Id;
                    _touchPoint = new Point((int)location.Position.X, (int)location.Position.Y);

                    if (GetButtonHitBounds(button).Contains(_touchPoint))
                    {
                        button.SwitchState(true);
                        _selectedButton = button;
                    }
                }
            }
        }
        else if (touchCollection.Count == 0)
        {
            _touched = false;

            for (int i = 0; i < menuButtons.Count; i++)
            {
                Button button = menuButtons[i];
                button.SwitchState(false);

                if (GetButtonHitBounds(button).Contains(_touchPoint) && _launchEvent)
                {
                    OnReleased(i, PlayerIndex.One);
                    _launchEvent = false;
                }
            }
        }

        ///
        // This if statement checks whether the touch is still inside the button area.
        // Then assigns a value of true to the _launchEvent variable.
        //
        // The 'try' block is used because if the first touch is not on button, then the
        // value of the _selectedButton is null and it will throw an exception.
        ///
        if (touchCollection.FindById(_touchID, out _touchLocation))
        {
            if (_touchLocation.State == TouchLocationState.Moved)
            {
                try
                {
                    if (GetButtonHitBounds(_selectedButton).Contains((int)_touchLocation.Position.X, (int)_touchLocation.Position.Y))
                        _launchEvent = true;
                    else
                        _launchEvent = false;
                }
                catch { }
            }
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接