我正在使用 Monogame 并且遇到了一个问题,如果我快速将很多手指放在屏幕上然后快速移除它们,最终(经过几次重复)我最终会得到一些从未得到匹配的“已释放”的“按下”事件事件。
我不认为问题出在 Monogame 上,因为我可以使用使用 vs2012 创建的小型“Windows Phone 和 Direct3D”应用程序重现该问题(在我的诺基亚 Lumia 920 上)。
在 C++ 方面,我只是在生成的 Direct3DInterop 类中存储一个向量,该类记录按下事件和释放事件
void Direct3DInterop::OnPointerPressed(DrawingSurfaceManipulationHost^ sender, PointerEventArgs^ args)
{
uint32 pointerID = args->CurrentPoint->PointerId;
auto i = std::find (_pressed.begin(), _pressed.end(), pointerID);
if (i == _pressed.end())
_pressed.push_back(pointerID);
}
void Direct3DInterop::OnPointerReleased(DrawingSurfaceManipulationHost^ sender, PointerEventArgs^ args)
{
uint32 pointerID = args->CurrentPoint->PointerId;
_pressed.erase(std::remove(_pressed.begin(), _pressed.end(), pointerID), _pressed.end());
}
在我的 XAML 中,我只有一个文本块和一个调度计时器,它定期检查 _pressed 中的元素计数(它应该始终返回 0)。
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent"
Margin="0,115,0,0">
<DrawingSurface x:Name="DrawingSurface" Margin="0,-113,0,0" Loaded="DrawingSurface_Loaded"/>
<TextBlock x:Name="LostReleasedCount" Text="Lost released count = 0" HorizontalAlignment="Left" Margin="0,-113,0,0" VerticalAlignment="Top" Height="113" Width="480"/>
</Grid>
并在文件后面的代码中
private Direct3DInterop m_d3dInterop = null;
private DispatcherTimer _timer;
private int _seconds;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// Creates a new instance of a timer.
_timer = new DispatcherTimer();
// Tells the _timer to tick every second.
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += TimerOnTick;
_timer.Start();
_seconds = 0;
}
private void TimerOnTick(object sender, EventArgs eventArgs)
{
Dispatcher.BeginInvoke(() =>
{
_seconds++;
LostReleasedCount.Text = "Lost released count = " + m_d3dInterop.GetPressedCount().ToString();
});
}
我在这里遗漏了一些明显的东西吗?您是否应该始终期望按下事件和释放事件匹配?如果我直接将 XAML 与 Touch.FrameReported 事件一起使用,我将无法重现该问题,所以这可能是 DirectX 的一些问题?
如果没有匹配的按下/释放对,我不确定如何将真正的问题与仅将手指放在屏幕上而不移动它的人区分开来。